Prototipo Contaminado
Prototype Pollution (cliente)
// OBJETIVO
Contaminá Object.prototype para que una propiedad que vos controlás aparezca en un objeto que nunca la definió, y disparar así la bandera de admin.
// ZONA DE ATAQUE
Corre en un iframe de origen opaco: no puede leer este sitio ni tu progreso. Cuando logres el exploit, la flag aparece dentro de la app — copiala y verificala.
// CONSULTÁ
Pistas
Código vulnerable
El merge recursivo copia cualquier clave, incluida __proto__:
function merge(target, source) {
for (const key in source) {
if (typeof source[key] === 'object' && source[key] !== null) {
target[key] = target[key] || {};
merge(target[key], source[key]); // ← recorre __proto__ sin frenar
} else {
target[key] = source[key];
}
}
return target;
}
const config = merge({}, parseQuery(location.search));
Con ?__proto__[isAdmin]=true, merge termina escribiendo en Object.prototype,
y entonces ({}).isAdmin === true para todo el programa.
Remediación
Frená las claves peligrosas y no sigas el __proto__ de la fuente:
function merge(target, source) {
for (const key in source) {
+ if (key === '__proto__' || key === 'constructor' || key === 'prototype') continue;
if (typeof source[key] === 'object' && source[key] !== null) {
- target[key] = target[key] || {};
+ target[key] = target[key] || Object.create(null);
merge(target[key], source[key]);
} else {
target[key] = source[key];
}
}
return target;
}
Por qué funciona: descartar __proto__/constructor/prototype impide
alcanzar el prototipo, y construir los objetos intermedios con
Object.create(null) los deja sin prototipo que contaminar.