San Antonio API Security Summit 2025 に参加しよう!
San Antonio API Security Summit 2025 に参加しよう!
San Antonio API Security Summit 2025 に参加しよう!
San Antonio API Security Summit 2025 に参加しよう!
San Antonio API Security Summit 2025 に参加しよう!
San Antonio API Security Summit 2025 に参加しよう!
閉じる
プライバシー設定
ウェブサイト運営に必要なCookieや類似技術を使用しています。追加のCookieは貴社の同意がある場合のみ利用されます。同意は「Agree」をクリックすることでいただけます。どのデータが収集され、どのようにパートナーと共有されているかの詳細は、Cookieポリシープライバシーポリシーをご確認ください。
Cookieは、貴社デバイスの特性や、IPアドレス、閲覧履歴、位置情報、固有識別子などの特定の個人情報を取得、解析、保存するために使用されます。これらのデータは様々な目的で利用されます。分析Cookieによりパフォーマンスを評価し、オンライン体験やキャンペーンの効果向上に役立てます。パーソナライズCookieは、利用状況に応じた情報やサポートを通じ、貴社専用の体験を提供します。広告Cookieは、第三者が貴社のデータをもとにオーディエンスリストを作成し、ソーシャルメディアやネット上でのターゲット広告に使用します。貴社は各ページ下部のリンクから、いつでも同意の許可、拒否、または撤回が可能です。
ご送信ありがとうございます。内容を受け付けました。
申し訳ありません。フォーム送信時にエラーが発生しました。
/
/
Vulnerabilities

プロトタイプ汚染

あまり知られていないセキュリティ欠陥の一つにプロトタイプ汚染が挙げられます。2017年に研究者の間で攻撃経路として注目され、2018年初頭には実際の事例が確認されました。 

プロトタイプ汚染を利用した攻撃に伴うリスクは何か、またその対策はどうすればよいか。本記事ではこれらの疑問に詳しく触れていきます。

著者
プロトタイプ汚染

プロトタイプ汚染の定義

プロトタイプ上書きの脆弱性により、不正な利用者が JavaScript 環境を狙えるようになります。既存の JavaScript で構築されたプロトタイプにプロパティを挿入することで、ハッキングを試みる攻撃です。

攻撃者は、基底オブジェクトの雛形を無効化または汚染する変数を注入でき、これがプロパティ注入と呼ばれる脆弱性につながります。この有害な現象は、継承関係にある複数のオブジェクトに影響します。ハッカーがオブジェクトの既定の属性を変更できれば、アプリのロジックまで改変され、DoS や遠隔コード実行 (RCE) などの被害が生じる可能性があります。

プロトタイプ汚染の脆弱性はどのように発生するか?

欧州コンピュータ製造者協会 (ECMA) は ECMAScript2015、第6版の要求事項を発表し、その中でプロトタイプ汚染の概念を盛り込みました。これにより統一された ECMAScript 標準が確立されました。

標準化された機能の一つに、オブジェクトの性質を認識するための __proto__ 属性があります。ECMAScript の全ての項目はこの性質を持ち、__proto__ 自体が項目の説明となっています。‘プロトタイプ’ という用語は、ECMAScript オブジェクト間で資産を共有する仕組みを示します。

プリミティブ型を除けば、ECMAScript に入力する全てはオブジェクトであり、これらは入れ子になり、互いにプロトタイプを継承できます。まさにその連鎖が生じるのです。

ハッカーが通常、新たな雛形を挿入することで __proto__ 属性を改ざんする場合、これを雛形改ざんと呼びます。全ての JavaScript 項目は __proto__ を有し、すべてのエンティティがプロトタイプを継承するため、新たなプロトタイプは自動的に連鎖の一部となります。

このように、攻撃者が既存の JavaScript オブジェクトに属性を注入し、DoS、悪質なコードによる遠隔コード実行、またはその他深刻な影響をもたらす例外を発生させる可能性があることが明らかになります。

Prototype Pollution example

プロトタイプ汚染の要因

任意の特性をプロトタイプに与えられるユーザー操作可能な入力は、プロトタイプ汚染の要因です。代表的なものは以下の通りです:

  • クエリまたはフラグメント(ハッシュ)付き URL
  • JSON 形式の入力
  • オンラインメッセージ
  • URL 経由

以下は、攻撃によって生成されたクエリ文字列が URL に挿入された例です:

https://vulnerable-website.com/?__proto__[evilProperty]=payload

クエリ文字列をキーと値の組に分解する際、URL パーサは __proto__ を単なる文字列と誤認する場合があります。しかし、これらの値とキーが既存のオブジェクトに属性として組み込まれると、どのような事態が起こるでしょうか。

ターゲットオブジェクトに __proto__ プロパティとその内部の evilProperty を追加することは単純に思えるかもしれません。

{ existingProperty1: 'foo', existingProperty2: 'bar', __proto__: { evilProperty: 'payload' } }

しかし、そうとは限りません。再帰的なマージ操作の任意の段階で、次のような文により evilProperty の値が割り当てられる可能性があります:

targetObject.__proto__.evilProperty = 'payload';

この代入時、JavaScript エンジンは __proto__ をプロトタイプのゲッターとして解釈します。その結果、意図したターゲットオブジェクトではなく、返された雛形オブジェクトに evilProperty が設定されます。同じキーのプロパティを持たない限り、ECMAScript の全項目が evilProperty を継承するようになります。ターゲットオブジェクトがデフォルトの Object.prototype を上書きしていても同様です。

多くの場合、「evilProperty」というプロパティを追加しても目立った影響はありません。しかし、攻撃者は同様の手法で、パッケージやインポートされたライブラリが依存するプロトタイプにプロパティを注入する可能性があります。

  • JSON 入力経由

JSON.parse() メソッドは、JSON 文字列をユーザー操作可能なオブジェクトに変換するためによく用いられます。不思議なことに、JSON.parse() は、__proto__ などの特殊なキーも文字列として解釈します。これにより、有害なプロトタイプが拡散する新たな道が開かれます。

例えば、攻撃者からのウェブメッセージを通じて注入される可能性のある、以下の悪意ある JSON を考えてみましょう:

{ "__proto__": { "evilProperty": "payload" } }

この JSON を JSON.parse() で解析すると、最終的な JavaScript オブジェクトには __proto__ というキーのプロパティが含まれます。

const objectLiteral = {__proto__: {evilProperty: 'payload'}}; const objectFromJson = JSON.parse('{"__proto__": {"evilProperty": "payload"}}'); objectLiteral.hasOwnProperty('__proto__'); // false objectFromJson.hasOwnProperty('__proto__'); // true

先述の URL 例のように、十分なキー検証を行わずに JSON.parse() で生成されたオブジェクトを既存のオブジェクトにマージすると、プロトタイプ汚染が発生する可能性があります。

プロトタイプ汚染による安全性リスク

JavaScript の移植性により、ウェブアプリのクライアント側とサーバ側の両方でプロトタイプ改ざんの脆弱性が発生する可能性があります。そのため、プロトタイプ攻撃による被害の深刻度や範囲はアプリごとに大きく異なります。以下にいくつかの例を示します:

プロトタイプ汚染攻撃により、攻撃者はクライアント側から対象ユーザーやアプリをホストするウェブサーバに対して DoS 攻撃を行えます。

  • JavaScript 環境の妨害

プロトタイプ汚染により、属性が追加または変更され、予期せぬ動作が引き起こされることがあり、特定のロジックが正常に機能しなくなる恐れがあります。

  • 次の攻撃への足掛かり

プロトタイプ汚染の発生は、同一環境内の他のコンポーネント(ガジェット)を攻撃者が利用する足掛かりとなります。これにより、より巧妙な攻撃の実行や、更なるアクセス権の獲得、権限の引き上げが可能となります。

  1. クライアント側の悪用

攻撃者は、例えば URL のようなクライアント側ロジックやアプリのレンダリングを行うコンストラクタにペイロードを埋め込むことで、プロパティ注入を悪用し始めます。例えば、URL パーサがターゲットとなるプロパティの関連性を確認せずに ECMAScript オブジェクトに属性を割り当てる場合があります。

また、クライアント側でのプロトタイプ汚染の悪用により、クロスサイトスクリプティング (XSS) など複数の攻撃が可能となります。ここでは、汚染されやすい属性に依存する仕組みが狙われます。オブジェクトがページの DOM と連携すると、攻撃者はクライアント側での ECMAScript 実行を誘発できます。

  1. サーバ側の悪用

攻撃者がソフトウェア環境のツールを用いてオブジェクトの雛形の属性を変更する際、これをサーバ側での悪用と呼びます。悪意ある改変を受けた ECMAScript の実行は、クライアント側での攻撃よりも深刻な影響を及ぼす可能性があります。

プロトタイプ汚染の脆弱性の全容を把握するのは困難で、攻撃の詳細を明らかにするためにはアプリのロジックの解析が必要となる場合があります。それでも、サーバ側での悪用は RCE、SQL インジェクション (SQLi)、認証回避など深刻な結果につながる恐れがあります。

プロトタイプ汚染の例

これは、ハッカーが悪意あるオブジェクトをパッケージのプロトタイプ連鎖に注入する際に発生する LiveScript の脆弱性です。予期せぬ動作や情報セキュリティの問題が引き起こされる恐れがあります。

以下は、JavaScript のプロトタイプ汚染を示す簡単なコード例です:

const myObject = {}; myObject.__proto__.isAdmin = true; console.log(myObject.isAdmin); // true

この例では、ハッカーが myObject の雛形に isAdmin プロパティを追加しています。myObject で isAdmin にアクセスすると true が返されます。この攻撃を防ぐため、ユーザー入力に対する検証とサニタイズは必ず行うべきです。

プロトタイプ汚染の緩和策

  • 最も重要なのは、コードが優れたプログラミング慣行に沿って作られることです。
  • クライアント側の脆弱性が多いため、ユーザー入力のサニタイズが欠かせません。
  • ライブラリの更新や npm の監査を実施し、脆弱性を確認してください。
  • 繰り返しのマージを避けることで、脆弱性のリスクが軽減されます。
  • 凍結されたオブジェクトは変更できないため、Object.freeze() を利用して雛形の変更を防いでください。
  • ECMAScript 6 (ES6) で導入されたマップは、オブジェクトが抱えるセキュリティ問題を回避しつつ、ハッシュマップとして機能します。
  • 最後に、Object.create(null) など、プロトタイププロパティを持たないオブジェクトを構築することで、プロトタイプ連鎖への影響を避け、汚染リスクを低減できます。

Wallarm が JavaScript 攻撃の防止を支援

Wallarm は、プロトタイプ汚染の脆弱性を突く JavaScript 攻撃の阻止に寄与します。

API Security 基盤、WAAP、アプリ、そして cloud-native 環境で動作するサーバーレスワークロードは、セキュリティ専門家向けに開発された Wallarm の技術により確実に守られています。

Wallarm は、世界中の多くのプライバシー保護担当者や開発者に利用され、厳しい攻撃への迅速な対応、API 全体に及ぶ広範なセキュリティ、自動化されたイベント対応によって製品防衛を支えています。

FAQ

Open
プロトタイプ汚染とは何?
Open
OWASPが推奨するプロトタイプ汚染防止策は何か?
Open
プロトタイプ汚染の影響はどんなものですか?
Open
プロトタイプ汚染はどのように発生するか?
Open
プロトタイプ汚染はどう防ぐ?

参考資料

ECMAScript 6 - www.w3schools.com

最新情報を購読

更新日:
February 25, 2025
学習目標
最新情報を購読
購読
関連トピック