なぜGoogleはJSONの先頭に while(1); をつけるのか

More than 5 years have passed since last update.

Stack Overflowに面白い質問があったので紹介する


質問

Googleのサービス内で使われるJSONの先頭に while(1); てついているのは何故?

例えばGoogle Calendarではカレンダーを切り替えるときに以下のような内容のデータがサーバから返される。


json

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が設定されていないため。


合わせて読みたい