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

Sin Firma No Hay Problema

JWT alg:none

// OBJETIVO

Falsificar un token que el server acepte como admin, sin conocer el secreto de firma.

// 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

    La verificación decide el algoritmo a partir del token recibido:

    function verify(token) {
      const [h, p, sig] = token.split('.');
      const header = JSON.parse(b64urlDecode(h));
      if (header.alg === 'none') return JSON.parse(b64urlDecode(p)); // ← sin firma
      if (header.alg === 'HS256') {
        if (sig === hmac(`${h}.${p}`, SECRET)) return JSON.parse(b64urlDecode(p));
      }
      return null;
    }

    El header lo controla el atacante, así que puede declarar alg: "none" y el server acepta el payload sin verificar ninguna firma. Con {"user":"admin"} dentro, se autentica como administrador sin conocer SECRET.

    Remediación

    Nunca dejes que el token elija su propio algoritmo: fijalo del lado del server y rechazá none.

    - function verify(token) {
    -   const [h, p, sig] = token.split('.');
    -   const header = JSON.parse(b64urlDecode(h));
    -   if (header.alg === 'none') return JSON.parse(b64urlDecode(p));
    -   if (header.alg === 'HS256') {
    -     if (sig === hmac(`${h}.${p}`, SECRET)) return JSON.parse(b64urlDecode(p));
    -   }
    -   return null;
    - }
    + // Algoritmo fijo y obligatorio; la firma se valida siempre.
    + function verify(token) {
    +   return jwt.verify(token, SECRET, { algorithms: ['HS256'] });
    + }

    Por qué funciona: al pasar algorithms: ['HS256'], la librería descarta cualquier token cuyo header declare otra cosa —incluido none— antes de confiar en él, y exige una firma válida con el secreto. El algoritmo deja de ser una decisión del atacante y vuelve a ser del servidor.

    Verificación

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