Client-side prototype pollution via browser APIs
概要
DOM Invaderを使用して、ブラウザAPI経由でのクライアントサイド・プロトタイプ汚染(Client-side Prototype Pollution)を検出し、エクスプロイトを実行する。
調査
- DOM Invaderの有効化: ブラウザのDevToolsを開き、DOM Invaderタブを選択して有効化する。
-
脆弱性の特定: ターゲットページを操作し、DOM Invaderが
Object.prototypeへの汚染が可能である箇所(Source)を検出するのを待つ。 - Gadgetの探索: 検出されたSourceに対して、実際に攻撃に利用できる既存のコード片(Gadget)が存在するかを確認する。
攻撃手順
- DOM Invaderで検出された脆弱なSourceの横にある「Scan for gadgets」をクリックする。
- 新しいタブが開き、自動的にガジェットのスキャンが実行される。
- スキャン完了後、Exploit可能なガジェットが見つかった場合、DOM Invader上に「Exploit」ボタンが表示される。
- 「Exploit」をクリックし、
alert(1)などの任意のJavaScriptが実行されることを確認する。
解説:なぜ攻撃が成立するのか
-
プロトタイプ汚染のメカニズム:
- JavaScriptでは、オブジェクトのプロパティが見つからない場合、プロトタイプチェーンを遡って検索する。
- 攻撃者が
__proto__やconstructor.prototypeを通じてObject.prototypeに悪意のあるプロパティを追加すると、アプリケーション内のすべてのオブジェクトがそのプロパティを継承してしまう。
-
ブラウザAPIの悪用:
- 開発者が
location.searchやlocation.hashなどのブラウザAPIから取得した値を、適切なサニタイズなしにオブジェクトのキーや値としてマージ処理などに使用することで発生する。
- 開発者が
-
Gadget(ガジェット)の役割:
- プロトタイプ汚染単体では単なるプロパティの追加に過ぎないが、アプリケーションがその汚染されたプロパティを参照して危険な処理(例:
innerHTMLへの書き込みやevalの実行)を行うコード片(Gadget)が存在することで、XSSなどの実害に繋がる。
- プロトタイプ汚染単体では単なるプロパティの追加に過ぎないが、アプリケーションがその汚染されたプロパティを参照して危険な処理(例:
対策
-
オブジェクトの凍結:
Object.freeze(Object.prototype)を実行し、プロトタイプの変更を禁止する。 -
Mapの使用: キーと値のペアを扱う際は、プレーンなオブジェクトではなく
Mapを使用する。 -
プロトタイプを持たないオブジェクトの作成:
Object.create(null)を使用して、__proto__を持たないオブジェクトを作成する。 - ライブラリの更新: 再帰的なマージ処理を行うライブラリに脆弱性がある場合が多いため、最新版にアップデートする。
クリアするまでにかかった時間
1h
所感
DOM Invaderを使用することで、複雑なプロトタイプ汚染の検出からガジェットの探索までを自動化できる点は非常に強力である。しかし、ツールに頼るだけでなく、根本的な原因(安全でないマージ処理など)や、なぜそのガジェットが発火したのかというコードレベルでの理解を深めることが、セキュアコーディングには不可欠だと感じた。
メモ
-
プロトタイプ汚染とは:
- JavaScriptのプロトタイプベースの継承モデルを悪用した攻撃。
- グローバルな
Object.prototypeを汚染することで、アプリケーション全体に影響を及ぼす。
-
DOM Invader:
- Burp Suiteに組み込まれたブラウザ拡張機能。DOM XSSやプロトタイプ汚染の検出を支援する。