グーグルはなぜ彼らの(私的な)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']]]]
私はこれが人々がeval()
を実行するのを防ぐためであると思いますが、あなたが本当にしなければならないのはwhile
を置き換えることだけです。私は、eval防止は、人々が安全なJSON構文解析コードを書くことを確実にすることであると思います。
私はこれが他の場所でも使われているのを見たことがありますが、グーグル(メール、カレンダー、連絡先など)ではもっともっとそうです、 Google Docs は&&&START&&&
で始まりますGoogleコンタクトはwhile(1); &&&START&&&
で始まるようです。
何が起きてる?
JSONハイジャック 、すべての主要なブラウザーで正式に 修正済み である主要なJSONセキュリティ問題 2011年以降 ECMAScript 5を防止します。
工夫された例:Googleにはmail.google.com/json?action=inbox
のようなURLがあり、受信ボックスの最初の50メッセージをJSON形式で返すとします。他のドメインの邪悪なウェブサイトは、同じ起源のポリシーのため、このデータを取得するためのAJAXリクエストを行うことはできませんが、<script>
タグを介してURLを含めることができます。 URLはyourCookieでアクセスされ、 グローバル配列コンストラクターまたはアクセサーメソッドをオーバーライドする で、いつでもメソッドを呼び出すことができますオブジェクト(配列またはハッシュ)属性が設定され、JSONコンテンツを読み取ることができます。
while(1);
または&&&BLAH&&&
はこれを防ぎます。mail.google.com
でのAJAXリクエストは、テキストコンテンツへの完全なアクセス権を持ち、それを取り除くことができます。ただし、<script>
タグを挿入すると、処理せずにJavaScriptが盲目的に実行され、無限ループまたは構文エラーが発生します。
これは、 クロスサイトリクエストフォージェリ の問題には対応していません。
JSONハイジャックによるレスポンスの漏洩を防ぎます。
理論的には、HTTP応答の内容は同じオリジンポリシーによって保護されています。1つのドメインからのページは他のドメイン上のページから情報を取得することはできません(明示的に許可されている場合を除く)。
攻撃者があなたに代わって他のドメインのページをリクエストすることができます。 <script src=...>
タグまたは<img>
タグを使用しても、結果に関する情報(ヘッダー、コンテンツ)を取得できません。
したがって、攻撃者のページにアクセスしても、gmail.comからあなたの電子メールを読むことはできません。
ただし、JSONコンテンツを要求するためにscriptタグを使用する場合、攻撃者の制御された環境ではJSONがJavascriptとして実行されます。攻撃者がArrayやObjectのコンストラクタ、あるいはオブジェクトの構築中に使用されたその他のメソッドを置き換えることができる場合、JSON内の何かが攻撃者のコードを通過し、公開される可能性があります。
これは、解析時ではなく、JSONがJavascriptとして実行されたときに発生することに注意してください。
複数の対策があります。
JSONデータの前にwhile(1);
ステートメントを配置することで、GoogleはJSONデータがJavascriptとして実行されないようにします。
正当なページだけが実際にコンテンツ全体を取得し、while(1);
を取り除き、残りをJSONとして解析することができます。
例えば、Facebookではfor(;;);
のようなものが見られ、同じ結果が出ています。
同様に、&&&START&&&
のように、JSONの前に無効なトークンを追加すると、それが実行されることはありません。
これはJSONの乗っ取りから保護するための OWASP
推奨される方法です そしてそれほど邪魔にならない方法です。
これまでの対策と同様に、JSONがJavascriptとして実行されることは決してありません。
何にも囲まれていない場合、有効なJSONオブジェクトはJavascriptでは無効です。
eval('{"foo":"bar"}')
// SyntaxError: Unexpected token :
しかしこれは有効なJSONです。
JSON.parse('{"foo":"bar"}')
// Object {foo: "bar"}
そのため、常にレスポンスのトップレベルでObjectを返すようにすると、JSONは有効なJavascriptではありませんが、それでも有効なJSONになります。
コメントの@hvdで述べたように、空のオブジェクト{}
は有効なJavascriptであり、オブジェクトが空であることを知ること自体が貴重な情報となるかもしれません。
クライアントライブラリを変更する必要がなく、有効なJSONを転送するので、OWASPの方法はそれほど邪魔になりません。しかしながら、過去または将来のブラウザのバグがこれを打ち負かすことができるかどうかは定かではありません。 @oriadamが指摘したように、エラー処理によって解析エラーでデータがリークされる可能性があるかどうかは不明です(たとえば、window.onerror)。
グーグルの方法はそれが自動デシリアライゼーションをサポートするためにクライアントライブラリを必要とし、ブラウザのバグに関してより安全であると考えることができます。
開発者が誤って脆弱なJSONを送信しないようにするために、どちらの方法でもサーバー側の変更が必要です。
これは他のサイトがあなたのデータを盗もうとする厄介なトリックをすることができないことを確実にするためです。たとえば、 を配列コンストラクタ に置き換え、<script>
タグを介してこのJSON URLを含めると、悪意のある第三者のサイトがJSON応答からデータを盗む可能性があります。先頭にwhile(1);
を付けると、代わりにスクリプトがハングします。
一方、XHRと別のJSONパーサーを使用した同一サイトリクエストでは、while(1);
プレフィックスを簡単に無視できます。
第三者が<script>
タグを使用してJSON応答をHTML文書に挿入するのを困難にするためです。 <script>
タグは 同一オリジンポリシー から免除されていることを忘れないでください。
注 :2019年現在、この質問で説明した予防策を導いていた古い脆弱性の多くは、現在のブラウザではもはや問題になっていません。私は以下の答えを歴史的な好奇心として残すつもりですが、本当にこれが尋ねられた2010年(!!)以降、トピック全体が根本的に変わりました。
単純な<script>
タグのターゲットとして使用されるのを防ぎます。そのため、悪意のある人が自分のサイトにそのscriptタグを挿入して、アクティブなセッションに頼ってコンテンツを取得することはできません。
編集 - コメント(およびその他の回答)に注意してください。この問題は、Object
およびArray
コンストラクタなど、破壊された組み込み機能に関係しています。そうでなければ無害なJSONが解析されると攻撃者のコードを引き起こす可能性があるようにそれらを変更することができます。
<script>
タグはWebの世界ではセキュリティ上の必要条件であるSame Origin Policyから除外されているため、JSONレスポンスにwhile(1)
を追加すると、<script>
タグでの誤用が防止されます。