
プロトタイプ汚染は、攻撃者がグローバルオブジェクトのプロトタイプに任意のプロパティを追加できるようにするJavaScriptの脆弱性であり、その後ユーザー定義のオブジェクトによって継承される可能性があります。 プロトタイプ汚染のソースとは、ユーザーが制御可能な入力で、プロトタイプオブジェクトに任意のプロパティを追加できるものを指します。最も一般的なソースは以下の通りです: URL JSON Webメッセージ
tough-cookiesパッケージ(v2.5.0)では、最初のURL経由のものがより関連性があります。 これは次のように発生します:
以下のようなリクエストを考えます:
https://vulnerable-website.com/?__proto__[badProperty]=payload
クエリ文字列をキー:値のペアに分割する際、URLパーサーは__proto__を任意の文字列として解釈する可能性があります。
ある時点で、再帰的なマージ操作により、次のようなステートメントと同等の方法でevilPropertyの値が割り当てられる可能性があります:
targetObject.__proto__.badProperty = 'payload';
__proto__はJavaScriptで特別な用途を持ちます。ご存知のように、あるオブジェクトで特定のプロパティP1が見つからなかった場合、そのオブジェクトのプロトタイプ内で検索されます。
例
function myClass() {
this.P1 = 'value';
}
let mc = new myClass();
console.log(mc.P1); //Value
console.log(mc.P2); //Undefined
mc.__proto__.P2 = 'value2';
let mc2 = new myClass();
console.log(mc.P2); //value2
__proto__を変更した後、myClassのすべての作成されたインスタンスはプロパティP2を持つようになります。
tough-cookiesパッケージ(v2.5.0)の場合、このプロトタイプ汚染の脆弱性は以下のコードスニペットから確認できます:
await new Promise((resolve, reject) => {
cookiejar.setCookie(
"Slonser=polluted; Domain=__proto__; Path=/notauth",
"https://__proto__/admin",
{ loose: true },
(err, cookie) => {
if (err) {
reject(err);
} else {
resolve(cookie);
}
}
);
});
CookieJarクラスはデフォルトでMemoryCookieStoreをストアとして使用することが判明しました。そしてMemoryCookieStoreのいくつかのメソッドでは、オブジェクトは次のように初期化されています:
this.idx = {};
これは、this.idxのプロトタイプに__proto__経由でプロパティを値(問題のある値になり得る)とともに追加できることを意味します。これを防ぐために、いくつかの場所で初期化が以下のように変更されました:
this.idx = Object.create(null);
これにより、プロトタイプなしの空のオブジェクトが作成されます。修正を検証するためのテスト memstore_vulnerability_fix_test.js が追加されました。