【ぷろとたいぷおせん】

プロトタイプ汚染 とは?

最終更新:
💡 継承元を書き換え、その値を読む処理に影響を広げる

JavaScriptで、攻撃者の入力などを通じて継承元のプロパティを不正に変更し、それを参照する処理の動作を変える攻撃。危険な動的書き込みやマージ処理などが原因になり得る。

📌 このページのポイント
継承元の変更と、その値を読む処理正常不正入力汚染後Object.prototypeisAdminなし不正なキーObject.prototypeisAdmin=true利用側自身に値なし危険な書き込み処理利用側自身に値なし参照値 true入力の検証と、自身の値かの確認が必要
不正な入力を危険な書き込み処理が継承元へ反映する例。上向きの矢印は利用側が継承元を探す向きです。isAdminを自身に持たず、継承したtrueをそのまま信じる処理で権限の誤判定が起こり得ます。
ひよこ ひよこ
継承元が汚染されるって、どんな攻撃なの?
ペンギン先生 ペンギン先生
JavaScriptのオブジェクトは、自分にないプロパティを継承元で探す場合があるよ。攻撃者がその継承元を書き換え、アプリが不正な値を読むようにするんだ。普通のオブジェクトではObject.prototypeが関係するけれど、継承元を持たないものもあるよ
ひよこ ひよこ
書き換わると何が起きるの?
ペンギン先生 ペンギン先生
例えばisAdminを自身に持たないオブジェクトで、継承元のtrueをそのまま読んで管理者と判断するような処理なら、権限を誤判定する危険がある。影響は読み方や使い方によるので、汚染だけで必ずアプリ全体が乗っ取られるわけではないんだ
ひよこ ひよこ
JSONを送るだけで攻撃できるの?
ペンギン先生 ペンギン先生
JSON.parseでは、__proto__も通常のキーとして読み込まれるよ。その後に攻撃者が決めたキーで深い書き込みや危険なマージを行うと、継承元へ到達する場合がある。全てのマージで必ず起きるわけではなく、constructor.prototypeの経路も考える必要があるね
ひよこ ひよこ
どうすれば防げるの?
ペンギン先生 ペンギン先生
受け付けるキーや型を検証して、意図しない書き込みを避けるよ。読み取りではObject.hasOwnで自身のプロパティか確認する。用途に応じてMapやObject.create(null)も使えるけれど、自分が使う処理全体を確認する必要があるんだ
ひよこ ひよこ
__proto__を無効にすれば十分?
ペンギン先生 ペンギン先生
攻撃の経路を減らせるけれど、constructor.prototypeから到達する可能性もあるよ。Node.jsの無効化設定だけで完全防御とはならない。入力検証や読み取り方法の見直し、依存ライブラリの更新を組み合わせるんだ
ペンギン
まとめ:ざっくりこれだけ覚えればOK!
「プロトタイプ汚染」って出てきたら「継承元の不正な値を、処理が読み込んでしまう攻撃」と思えばだいたいOK!
📖 おまけ:英語の意味
「Prototype Pollution」 = プロトタイプ汚染
💬 Prototypeは継承元、Pollutionは汚染という意味だよ。継承元のプロパティへの不正な変更と、それを使う処理への影響を表す名前なんだ

参考資料

← 用語集にもどる