Stack Overflowに面白い質問があったので紹介する
質問
Googleのサービス内で使われるJSONの先頭に while(1);
てついているのは何故?
例えばGoogle Calendarではカレンダーを切り替えるときに以下のような内容のデータがサーバから返される。
while(1);[['u',[['smsSentFlag','false'],['hideInvitations','false'],['remindOnRespondedEventsOnly','true'],['hideInvitations_remindOnRespondedEventsOnly','false_true'],['Calendar ID stripped for privacy','false'],['smsVerifiedFlag','true']]]]
これ以外にもGoogleのサービスでは &&&START&&&
とか while(1); &&&START&&&
てのが先頭に入ってたりするんだけど、これは一体何?
解答
これはクロスサイト・リクエスト・フォージェリ対策。
例えばGoogleが gmail.com/json?action=inbox
というURLを持ってて、そこにユーザのCOOKIEでアクセスすると最新50件のメールが取れるとする。悪意のあるサイトからはsame-origin policyでAjaxではアクセスできないが、scriptタグのsrc属性に直接入れることでJSONを取得することはできてしまう。そして ArrayコンストラクタやそのアクセッサメソッドをオーバライドすることでJSONの値にアクセスできてしまう。
先頭に while(1);
とかシンタックスエラーになる文字列があればこれを抑制できる。Ajaxではレスポンスを文字列として扱うことができるけれどscriptタグでは即実行されるため、これら余分な箇所を取り除くことができないからだ。
余談
- 最近のWebブラウザでは組み込み型のコンストラクタの再定義はできないようになっている。
- FacebookのJSONの先頭には
for(;;);
がついているらしい。こっちの方が1文字短い。 - 古いブラウザのセキュリティホールに対応するためのバッドノウハウなので、相当セキュリティに気を使わなければならないようなページでなければ必要ない。
- 「CSRF対策」というよりは「JSON hijacking対策」という方が適切。
- より正確に言うならAjaxでアクセスできないのはSame-Origin PolicyとCross-Origin Resource Sharingが設定されていないため。