JSForge
Acceder →
← Volver al catálogo
CLIENTEDIFÍCIL En navegador

Config Fantasma

DOM Clobbering

// OBJETIVO

Sin ejecutar JavaScript, hacer que window.appConfig.isAdmin sea verdadero para desbloquear el rol admin.

// ZONA DE ATAQUE

app vulnerable · sandbox aislado

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 panel confía en variables globales que en realidad puede definir el HTML:

    const html = sanitize(userInput);   // quita <script>, pero deja id/name
    container.innerHTML = html;
    
    const cfg = window.appConfig || {};
    if (cfg.isAdmin) unlockAdmin();     // ← window.appConfig lo puede clonar el markup

    En el navegador, un elemento con id="appConfig" queda accesible como window.appConfig, y un control name="isAdmin" dentro de un <form> aparece como appConfig.isAdmin. Inyectando <form id="appConfig"><input name="isAdmin"> el atacante clona (clobbers) esos globales con nodos del DOM, y el chequeo pasa sin una sola línea de JavaScript — por eso quitar <script> no alcanza.

    Remediación

    No leas configuración ni estado de seguridad desde globales que el DOM pueda definir, y sanitizá con una allowlist real que elimine id/name.

    - const cfg = window.appConfig || {};
    - if (cfg.isAdmin) unlockAdmin();
    + // La config viene del servidor/JSON, nunca del DOM ni de globales implícitos.
    + if (session.role === 'admin') unlockAdmin();
    - const html = sanitize(userInput);
    + const html = DOMPurify.sanitize(userInput, { SANITIZE_DOM: true }); // quita id/name peligrosos
      container.innerHTML = html;

    Por qué funciona: decidir el rol a partir de datos de sesión —no de window.appConfig— saca del juego cualquier global clonable por el markup. Y un sanitizador con protección anti-clobbering (p. ej. DOMPurify con SANITIZE_DOM) elimina los id/name que habilitan la técnica.

    Verificación

    Se verifica en tu navegador contra un hash. La flag no se envía a ningún lado.