上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
 新しいウィンドの作成を使わずに、POST元リファラ問題を解決してTwitterに投稿できるブックマークレットが出来たんですが、これって公開してもいいんでしょうか。Twitterにログインした状態で踏むと勝手にTwitterに「hogehoge」とか投稿されるリンクが作れちゃうんですが。

CSRFっぽい動きはするんですが、これが脆弱性かというと、Twitterの仕様のような気もしますし、仮に脆弱性だとしてもTwitterの脆弱性なのかブラウザ側の脆弱性なのか良くわかりません。

とりあえずIPAに報告してみて、脆弱性だと言われなければ問題ないですかね。
スポンサーサイト
 Twit! ブックマークレットによると、新しいウィンドを作成してその中でPOSTすればFirefoxではリファラーが空になるとの事。という事はリファラーを送る設定にしているFirefoxでも・・。(ウィンドが一瞬表示されるので何かがあった事はユーザにわかるんですが)

というわけでブラウザ設定を弄らなくても使えるバージョンを作りました。


javascript:
(
function(){
if(status=prompt('post to Twitter')){
commit='Update';

w=window.open('','_blank','width=0,height=0');

f=w.document.createElement('form');
f.setAttribute('name','TwitterPostForm');
f.setAttribute('action','http://twitter.com/status/update');
f.setAttribute('method','POST');
f.setAttribute('Accept-charset','UTF-8');

s=w.document.createElement('input');
s.setAttribute('name','status');
s.setAttribute('value',status);
f.appendChild(s);

c=w.document.createElement('input');
c.setAttribute('name','commit');
c.setAttribute('value',commit);
f.appendChild(c);

w.document.body.appendChild(f);
w.document.TwitterPostForm.submit();

w.onunload=
function(){
w.close();
}

}
}
)();



続く
 ここまでブラウザのリファラー設定を変更した(無効にした)状態を前提にしたブックマークレットを作ってきましたが、つまりブラウザの設定がリファラーを送らない設定になっている場合、CSRF攻撃が成り立つんじゃないかと思い当たりました。

例えばこんな感じで。

del.icio.usの場合は、post to del.icio.us実行後に一度確認画面を挟み、そこでランダムキーを入れるような対策をしているみたいですが、Twitterの場合は一発投稿出来てしまうのでこんな現象が起きてしまいます。

調べてみた所、既に指摘されているブログがありました。

[速報]TwitterにCSRF脆弱性あり

というわけで、これらブックマークレットを使うため(そうでなくても、リファラを送らない設定にしているユーザはいそうですが)にリファラーを送らないブラウザ設定にした場合、Twitterへの限定的なCSRFが発生する可能性があるという事をご理解ください。

続く
 ここまでAPIを使わずにブックマークレットを作りましたが、折角なのでAPIを使ったブックマークレットも作る事にしました。

Twitter API Documentation

これによると、どうやら送信するデータは全てUTF-8エンコードで無ければならないようです。


javascript:
(
function(){
if(status=prompt('post to Twitter')){
i=document.createElement('iframe');
i.setAttribute('name','TwitterPostIframe');
i.setAttribute('width',0);
i.setAttribute('height',0);
i.onload=
function(){
document.body.removeChild(f);
document.body.removeChild(i);
};
document.body.appendChild(i);


f=document.createElement('form');
f.setAttribute('name','TwitterPostForm');
f.setAttribute('action','http://twitter.com/statuses/update.xml');
f.setAttribute('method','POST');
f.setAttribute('target','TwitterPostIframe');
f.setAttribute('Accept-charset','UTF-8');

s=document.createElement('input');
s.setAttribute('name','status');
s.setAttribute('value',status);
s.setAttribute('type','hidden');
f.appendChild(s);

document.body.appendChild(f);
document.TwitterPostForm.submit();
}
}
)();



formのAccept-charsetでUTF-8を指定するようにしましたが、IEでは無視されるそうなので、IEに対応させる場合はmetaタグの文字コード指定を送信時に入れ替える等の修正が必要になりそうです。レスポンスはXMLで返ってきますが、全く利用していません。

続く
 前回でとりあえず作成したpost to Twitterですが、postした後に現在見ているページからTwitterへ画面遷移が起きてしまいます。私の使い方の場合、この画面遷移は無い方が嬉しいので、もう一つ別のブックマークレットを作る事にしました。

方法としてはformと一緒にheight=0、width=0のiframe要素を作成し、iframe要素をtargetとしてPOSTする事で一見画面遷移が起きていないように見せるというものです。


javascript:
(
function(){
if(status=prompt('post to Twitter')){
commit='Update';

i=document.createElement('iframe');
i.setAttribute('name','TwitterPostIframe');
i.setAttribute('width',0);
i.setAttribute('height',0);
document.body.appendChild(i);

f=document.createElement('form');
f.setAttribute('name','TwitterPostForm');
f.setAttribute('action','http://twitter.com/status/update');
f.setAttribute('method','POST');
f.setAttribute('target','TwitterPostIframe');

s=document.createElement('input');
s.setAttribute('name','status');
s.setAttribute('value',status);
s.setAttribute('type','hidden');
f.appendChild(s);

c=document.createElement('input');
c.setAttribute('name','commit');
c.setAttribute('value',commit);
c.setAttribute('type','hidden');
f.appendChild(c);

document.body.appendChild(f);
document.TwitterPostForm.submit();
}
}
)();


ただし、このままだと同じページで複数回のpost to Twitterが出来ないので、iframeへのpostが終わったタイミングで追加した要素を削除してやります。


javascript:
(
function(){
if(status=prompt('post to Twitter')){
commit='Update';

i=document.createElement('iframe');
i.setAttribute('name','TwitterPostIframe');
i.setAttribute('width',0);
i.setAttribute('height',0);
i.onload=
function(){
document.body.removeChild(f);
document.body.removeChild(i);
};
document.body.appendChild(i);

f=document.createElement('form');
f.setAttribute('name','TwitterPostForm');
f.setAttribute('action','http://twitter.com/status/update');
f.setAttribute('method','POST');
f.setAttribute('target','TwitterPostIframe');


s=document.createElement('input');
s.setAttribute('name','status');
s.setAttribute('value',status);
s.setAttribute('type','hidden');
f.appendChild(s);

c=document.createElement('input');
c.setAttribute('name','commit');
c.setAttribute('value',commit);
c.setAttribute('type','hidden');
f.appendChild(c);

document.body.appendChild(f);
document.TwitterPostForm.submit();
}
}
)();



続く
 久しぶりのエントリです。三ヶ月ほど仕事が忙しく、ブログも中々更新が出来ない状況が続いていましたが、今週は割とまったりとしていたので、少しはまともな物を書こうと思います。(来週には来週の風が吹く)

そも、このブログはコミュニケーションツールというよりも、自分の思考結果を書き残しておく外部記憶装置として使っている側面が強いのですが、最近は考える事は山ほどにあるのに、ブログという形ではスワッピングのコストが高く機能不全に陥ってしまっている状況です。

そこでTwitterの登場です。ブログ、SNSに続くコミュニケーションツールとして盛り上がっているTwitterですが、同様にスワッピングコストの低い外部記憶装置としても使えるのではないでしょうか。

そう思い立ち、post to del.icio.us的なブックマークレットを探してみたのですが、これが意外とすぐには見つかりません。車輪の再発明も勉強としては歓迎するべきという事で、今回は自作してみる事にしました。

 完成のイメージとしてはブックマークレットを起動すると入力プロンプトが表示され、それに入力しOKを押すとプロンプトが閉じTwitterへの投稿が完了するというものです。ベースになる環境はFirefoxです。私自身がFirefoxユーザのため、先ずはFirefoxで動かない事には話しにならないからです。


 先ずはTwitterのコメント投稿画面を調べてみます。

Twitter/home

ここで「ページ情報→フォーム」を見るとstatusとcommitというnameでPOSTを使いTwitterサーバにコメントデータを送信している事がわかります。

GETでは無くPOSTのため少し面倒な事になりそうです。del.icio.usのようにGETであればJavascriptからURLを叩けば済む話なのですが、POSTではそういうわけにも行きません。

そこで先ず思いついたのが現在表示しているページにmethod=postのform要素を追加し、それを自動submitしてやるという方法です。



javascript:
if(status=prompt('post to Twitter')){
commit='Update';

f=document.createElement('form');
f.setAttribute('name','TwitterPostForm');
f.setAttribute('action','http://twitter.com/status/update');
f.setAttribute('method','POST');

s=document.createElement('input');
s.setAttribute('name','status');
s.setAttribute('value',status);
s.setAttribute('type','hidden');
f.appendChild(s);

c=document.createElement('input');
c.setAttribute('name','commit');
c.setAttribute('value',commit);
c.setAttribute('type','hidden');
f.appendChild(c);

document.body.appendChild(f);
document.TwitterPostForm.submit();
}



これをブックマークレット用に1ライナーへ整形して実行してみた所


Sorry, due to abusive behaviour, we have been forced to disable posting from external websites. If you are posting from an API tool, please ensure that the HTTP_REFERER header is not set.


というメッセージがTwitterから返ってきました。そういえばAPIが公開されていたという事をこの時点で思い出しましたが、それはさて置きどうやらAPI経由での投稿時にはリファラーを消せとの事。

API経由ではありませんがリファラを消せば動くかと試してみたのですが、どうやらFirefoxではJavascriptからリファラへのアクセスはエラーメッセージを見る限りだと読取専用で書き込みは出来ないようです。

仕方が無いのでブラウザ側の設定でリファラを全て送信しないようにしてみます。

Mozilla Japan ナレッジベース - リファラを無効にする

この状態で先ほどのブックマークレットを起動した所、無事に投稿に成功しました。

ただし、このままではブックマークレット内で使っている変数が現在表示しているページのJavascript変数を汚染してしまうため無名関数として実行させるようにします。


javascript:
(
function(){
if(status=prompt('post to Twitter')){
commit='Update';

f=document.createElement('form');
f.setAttribute('name','TwitterPostForm');
f.setAttribute('action','http://twitter.com/status/update');
f.setAttribute('method','POST');

s=document.createElement('input');
s.setAttribute('name','status');
s.setAttribute('value',status);
s.setAttribute('type','hidden');
f.appendChild(s);

c=document.createElement('input');
c.setAttribute('name','commit');
c.setAttribute('value',commit);
c.setAttribute('type','hidden');
f.appendChild(c);

document.body.appendChild(f);
document.TwitterPostForm.submit();
}
}
)();



続く
コンピュータが絡む話ではよくキロ・バイト、メガ・バイト、ギガ・バイトといった単位が使われます。これはSI接頭辞と呼ばれるものから来ていて、これがそもそも10進数を想定したものなので1KBと表記した時に1024バイト(2^10)なのか1000(10^3)バイトなのかが不明瞭だという問題があるのですが、2進接頭辞なるものが1998年頃、IEC(国際電気標準会議)によって承認されていたんだとか。

1000なのか1024なのか問題の存在自体は認識していましたが、2進接頭辞の存在はずっと知りませんでした。認知されなさすぎというか、別にその程度の曖昧さが問題になるケースが世の中には少なすぎるという事でしょうか。
copyright © 2005 The elephant vanishes all rights reserved.
Powered by FC2ブログ.
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。