【ぷろとたいぷおせん】

プロトタイプ汚染 とは?

💡 JavaScriptの「親オブジェクト」を書き換えてシステム全体を汚染する攻撃
📌 このページのポイント
プロトタイプ汚染 — Object.prototype を改ざんする攻撃 通常の継承 Object.prototype (全オブジェクトの親) 通常オブジェクト {"name": "Alice"} アプリコード isAdmin → undefined 攻撃者のJSON {"__proto__": {"isAdmin": true}} deepMerge() で処理 Object.prototype 汚染! isAdmin = true が注入される 汚染後の状態 Object.prototype isAdmin: true ← 注入! (すべての親が汚染済み) オブジェクトA obj.isAdmin → true ⚠ オブジェクトB obj.isAdmin → true ⚠ 対策 Object.create(null) / hasOwnProperty チェック / __proto__ キーの入力バリデーション
プロトタイプ汚染:Object.prototypeへの不正な書き込み
ひよこ ひよこ

プロトタイプ汚染って名前が物騒だけど、どんな攻撃なの?

ペンギン先生 ペンギン先生

JavaScriptにはプロトタイプチェーンという仕組みがあって、すべてのオブジェクトは「Object.prototype」という共通の親オブジェクトを持っているんだよ。プロトタイプ汚染はその親オブジェクトを攻撃者が書き換えることで、アプリ全体の動作を変えてしまう攻撃なんだ。

ひよこ ひよこ

オブジェクトが書き換わると何が起きるの?

ペンギン先生 ペンギン先生

例えば、認証チェックで使っている変数のデフォルト値を書き換えてログイン制限をバイパスしたり、任意のコードを実行させたりできるんだよ。影響がアプリ全体に及ぶのが怖いところで、CVSSスコア9台の深刻な脆弱性として報告された事例もあるんだ。

ひよこ ひよこ

どうやって攻撃されるの?

ペンギン先生 ペンギン先生

よくあるのはJSONの深いマージ処理を使うパターンだよ。例えば攻撃者が{"__proto__": {"isAdmin": true}}というJSONを送り込むと、それをdeepMergeした瞬間にObject.prototypeのisAdminがtrueになってしまうんだ。多くのライブラリが昔はこの問題を持っていたよ。

ひよこ ひよこ

どうすれば防げるの?

ペンギン先生 ペンギン先生

いくつかの対策があるよ。Object.create(null)でプロトタイプを持たないオブジェクトを作る、hasOwnPropertyでプロパティの所有者を確認する、JSON.parseの結果を直接マージしない、といった方法が有効だよ。また、lodashなどのライブラリは修正済みバージョンを使うことも大切だね。

ひよこ ひよこ

有名なライブラリでも起きたことあるの?

ペンギン先生 ペンギン先生

あるよ。lodash・jQuery・node-mergeなど多くの著名ライブラリで過去に発見されたんだ。npmエコシステム依存関係を通じて知らないうちに脆弱なバージョンを使っているケースもあるから、npm auditで定期的にチェックするのが大切だね。

ペンギン
まとめ:ざっくりこれだけ覚えればOK!
プロトタイプ汚染」って出てきたら「JavaScriptオブジェクト継承の仕組みを悪用した攻撃のことだな」と思えればだいたいOK!
📖 おまけ:英語の意味
「Prototype Pollution」 = プロトタイプ汚染
💬 JavaScriptの「プロトタイプ(Prototype)」という継承機構を「汚染(Pollution)」することから名付けられたんだよ
← 用語集にもどる