
Correggi la vulnerabilità di prototype pollution (CVE-2023-26136) per il pacchetto tough-cookie
La pollution dei prototipi (prototype pollution) è una vulnerabilità JavaScript che consente a un attaccante di aggiungere proprietà arbitrarie ai prototipi degli oggetti globali, che possono poi essere ereditate dagli oggetti definiti dall'utente. Una fonte di pollution dei prototipi è qualsiasi input controllabile dall'utente che consente di aggiungere proprietà arbitrarie agli oggetti prototipo. Le fonti più comuni sono le seguenti: URL JSON Web Messages
Per il pacchetto tough-cookies (v2.5.0) è più rilevante la prima tramite URL Avviene come segue:
Ecco una richiesta:
https://vulnerable-website.com/?__proto__[badProperty]=payload
Quando la stringa di query viene scomposta in coppie chiave:valore, un parser URL può interpretare proto come una stringa arbitraria.
A un certo punto, l'operazione di merge ricorsivo può assegnare il valore di evilProperty usando un'istruzione equivalente alla seguente:
targetObject.__proto__.badProperty = 'payload';
__proto__ ha un uso speciale in JavaScript. Come sappiamo, se per un oggetto una certa proprietà P1 non viene trovata, verrà cercata nel prototipo di questo oggetto.
Esempio
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
Dopo aver modificato __proto__ - tutte le istanze create di myClass avranno la proprietà P2.
Per il pacchetto tough-cookies (v2.5.0) questa vulnerabilità di pollution dei prototipi può essere vista dal seguente snippet di codice:
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);
}
}
);
});
È stato scoperto che la classe CookieJar utilizza MemoryCookieStore come store predefinito. E in diversi metodi di MemoryCookieStore gli oggetti vengono inizializzati come segue:
this.idx = {};
Ciò significa che per questo.idx il prototipo può ricevere proprietà con valori (che possono essere problematici) tramite __proto__. Per prevenire ciò - in diversi punti l'inizializzazione è stata modificata come segue:
this.idx = Object.create(null);
Questo crea un oggetto vuoto senza prototipo. È stato aggiunto un test memstore_vulnerability_fix_test.js che verifica la correzione.