JSForge
Acceder →
← Volver al catálogo
SERVIDORMEDIO En navegador

Igual pero Distinto

Bypass de auth por coerción de tipos

// OBJETIVO

Entrá como admin sin conocer la contraseña, aprovechando cómo JavaScript coacciona tipos en comparaciones flojas.

// 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 handler compara con igualdad floja y confía en el tipo del body:

    app.post('/api/login', (req, res) => {
      const { user, remember } = req.body;
      const account = db.find(user); // admin tiene rememberToken = 0
    
      // "recordarme": si el token coincide, saltea la contraseña
      if (account && remember == account.rememberToken) {
        return res.json({ ok: true, flag: FLAG });
      }
      // ...verificación normal de contraseña
    });

    Como el body es JSON, remember puede llegar como false, 0, [] o "", y == los coacciona: false == 0, [] == 0 y "" == 0 son todos true. Mandando {"user":"admin","remember":false} la comparación pasa sin conocer nada.

    Remediación

    Compará con === y validá el tipo antes de comparar:

    - if (account && remember == account.rememberToken) {
    + if (
    +   account &&
    +   typeof remember === 'string' &&
    +   remember.length > 0 &&
    +   remember === account.rememberToken
    + ) {
        return res.json({ ok: true, flag: FLAG });
      }

    Por qué funciona: === no coacciona, así que false, 0 o [] dejan de ser iguales a un token string. Exigir typeof === 'string' y longitud mínima cierra el resto de los valores raros que un cliente puede inyectar por JSON.

    Verificación

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