0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【セキュリティ】Prototype Pollution を利用した Denial of Service(DoS)攻撃

0
Posted at

はじめに

― toString() を破壊するとアプリはどうなるのか? ―

Prototype Pollution は「新しいプロパティをねじ込む」だけの可愛い攻撃ではありません。
油断していると、アプリケーションをまるごとクラッシュさせる DoS(サービス妨害)攻撃へ直行します。

今回の記事では、JavaScript アプリの心臓部分とも言える Object.prototype.toString() を狙い撃ちして、
アプリを落とすまでの流れを丁寧に解説していきます。


1. なぜ Prototype Pollution が DoS を引き起こすのか?

JavaScript のすべてのオブジェクトは Object.prototype を継承しています。

つまり、

Object.prototype.toString を汚染したら、全オブジェクトの toString が壊れる

という、恐ろしく破壊的な現象が起こります。

toString() は以下のような場面で暗黙的に使われます:

  • ログ出力
  • 文字列テンプレート ${obj}
  • デバッグ
  • オブジェクト比較
  • JSON 変換時の内部処理
  • フレームワーク内部のユーティリティ関数

ある意味、アプリ中で最も呼ばれる関数のひとつ。
そこを壊すということは――

アプリの“酸素”を奪うようなもの

です。


2. 典型的な攻撃の流れ

TryHackMe の教材で紹介されているケースをベースに見ていきましょう。

攻撃対象ページ(Clone Album)

<form action="/clone-album/1" method="post">
    <input type="text" name="newAlbumName">
    <button type="submit">Clone Album</button>
</form>

ユーザーが入力する newAlbumName は、
サーバ側で JSON としてパースされる可能性がある という点が致命傷でした。

そしてサーバ側では、例の脆弱な merge 関数が実行されます:

merge(clonedAlbum, payload);

3. toString を汚染する攻撃ペイロード

攻撃者が入力欄に次の JSON を入れます:

{"__proto__": {"toString": "Just crash the server"}}

これがサーバに送信されると…

  1. JSON.parse() によってオブジェクト化
  2. merge() によって __proto__.toString が上書き
  3. つまり Object.prototype.toString = "Just crash the server"` と同等

4. すると何が起こるのか?

アプリの内部では、至るところで toString() が呼ばれます。

ところが汚染後の toString は もはや関数ではなくただの文字列

そのため、次のような例外が発生します:

TypeError: Object.prototype.toString.call is not a function

この瞬間、サーバの処理は止まり、
フロントには 500 エラーが表示され、ユーザーは正しく操作できません。

TryHackMe の教材でも、この動作が確認できます:

  • 「Clone Album」をクリックすると即クラッシュ
  • 画面はエラー画面に切り替わる
  • サーバログにも TypeError が出力

Prototype Pollution の威力、侮れません。


5. 他に DoS を引き起こしうる汚染対象

toString は強力ですが、他にも DoS 化しやすいプロパティがあります:

汚染対象 影響
valueOf 数値変換の失敗 → 数学処理全滅
toJSON JSON.stringify が壊れる
constructor 新しいオブジェクト生成が壊れる
hasOwnProperty ほぼすべてのプロパティチェックがバグる
__defineGetter__ / __defineSetter__ ループが無限再帰に陥る可能性

ただし すべてが即クラッシュするわけではない ため、
狙いどころとして最も安定して DoS に直結するのが toString() です。


6. 守るためにはどうするべきか?

開発者目線での対策はこちら。

① 危険キーを必ずブロック

if (["__proto__", "prototype", "constructor"].includes(key)) {
    continue;
}

② JSON.parse を安易に使わない

ユーザー入力を文字列として扱うべき場面では 絶対に JSON 化しない

③ マージ関数を自前で実装しない

lodash なども古いバージョンは Prototype Pollution の脆弱性がありました。
必ず 最新版を使用

④ Object.freeze(Object.prototype)

場面によっては有効(ただし副作用も大きいので慎重に判断)。


まとめ

Prototype Pollution が危険な理由は、単に“変なプロパティが増える”だけではなく…

アプリ全体の基盤となる prototype が破壊され、
内部のあらゆる処理が正常に動かなくなる点にあります。

特に:

  • toString()
  • valueOf()
  • constructor

といった「全オブジェクトが頼る関数」を汚染されると、
アプリケーションは 一撃でクラッシュ します。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?