Hello there, ('ω')ノ
💣 攻撃の出発点:悪意あるURL
https://vulnerable-website.com/?__proto__[evilProperty]=payload
このURLのクエリパラメータ部分に注目してください:
?__proto__[evilProperty]=payload
これは、JavaScriptでオブジェクトを作成する時の次のような形にパースされる可能性があります:
{ "__proto__": { "evilProperty": "payload" } }
ここで攻撃者の意図は:
__proto__を使って、オブジェクトの親(=プロトタイプ)を汚染すること。
⚙️ アプリ側の処理の流れ(想定)
- クエリパラメータをオブジェクトとしてパース
- それを設定オブジェクトや既存のデータにマージ
merge(config, parsedQuery)のような処理が実行される
❌ 期待される挙動(開発者の想定)
開発者は、以下のような構造になると考えているかもしれません:
{ existingProperty1: 'foo', existingProperty2: 'bar', __proto__: { evilProperty: 'payload' } }
つまり「__proto__ は普通のプロパティとして扱われるはずだ」と思いがちです。
😱 実際に起こること
実際には、__proto__はJavaScriptエンジンによって特別に処理されます。
以下のようなコードが実行されることになります:
target.__proto__.evilProperty = 'payload';
これが意味するのは:
targetオブジェクト自身ではなく、そのプロトタイプ(親)にevilPropertyを追加している!
つまり:
Object.prototype.evilProperty = "payload";
となり、以後全てのオブジェクトが evilProperty を継承してしまうのです。
🧪 確認例:どのオブジェクトにも見える!
console.log({}.evilProperty); // → "payload" console.log({a:1}.evilProperty); // → "payload"
このように、どんなオブジェクトを作っても evilProperty が勝手に存在してしまいます。
⚔️ 実際の攻撃は?
evilProperty では何も起きないかもしれませんが、次のような「アプリやライブラリが使っている本物のプロパティ名」を汚染すると…
isAdmin(管理者フラグ)authenticated(認証状態)constructor(危険!コード実行の可能性あり)
アプリのロジックが完全に書き換えられる可能性があります。
🧠 理解のポイント
| 用語 | 解説 |
|---|---|
__proto__ |
オブジェクトのプロトタイプ(親)を指す特殊なキー |
target.__proto__ |
実際には Object.prototype にアクセスしている |
| URLからの攻撃 | クエリパラメータで__proto__を使って意図的にマージ処理を悪用 |
| 被害の範囲 | すべてのオブジェクトに不正なプロパティが見えるようになる |
| 影響 | 本物のプロパティを汚染すれば、認証回避やRCEにつながる |
✅ 防止策
__proto__,constructor,prototypeをクエリパラメータとして受け付けない- マージ処理でキーを明示的にホワイトリスト制限する
- 安全なライブラリ(例:
deepmergewith sanitization)を使用する
📝 まとめ
URLから始まるPrototype Pollutionは、一見無害なパラメータがアプリ全体のロジックを書き換える深刻な問題を引き起こす可能性があります。
特に、__proto__ のような「特別な名前を持つプロパティ」が、ただの文字列として扱われず、JavaScriptの内部動作に深く関与している点が最大のリスクです。
Best regards, (^^ゞ