Ataques de confusión entre HS256 y RS256
Cómo aparece la confusión de algoritmos cuando los verificadores mezclan claves simétricas y asimétricas, con pruebas concretas.
La confusión de algoritmos en JWT parece un caso muy concreto hasta que encuentras un servicio con tres librerías de autenticación y un helper compartido llamado verifyToken. El ataque clásico abusa de un verificador que acepta HS256 y RS256 mientras usa el mismo material de clave con el papel equivocado. Si el servidor trata una clave pública RSA como secreto HMAC, un atacante puede firmar un token HS256 falso usando datos que nunca fueron secretos.
Por qué sobrevive a las revisiones
En una revisión de código se ve jwt.verify(token, key) y se sigue adelante. La decisión peligrosa vive en los valores por defecto: qué algoritmos se aceptan, cómo se selecciona la clave y si el código decide según el encabezado del token. Los equipos también copian snippets entre servicios. Una cadena PEM segura en un verificador RS256 se vuelve peligrosa cuando se pasa a un verificador que confía en el valor alg recibido.
El atacante busca endpoints JWKS expuestos, archivos PEM en apps móviles, bundles frontend, ejemplos de documentación y mensajes de error que revelen el comportamiento del verificador. Con una clave pública disponible, crea un token con alg en HS256, firma el payload usando los bytes de esa clave pública como secreto HMAC y prueba si el servicio lo acepta. El cambio de payload suele ser pequeño: subir scope, cambiar tenant_id o poner admin en true.
Pruebas sin generar ruido
Usa una cuenta con pocos permisos y empieza por un endpoint no destructivo, como metadatos del perfil o una ruta de feature flags. Mantén iss, aud y exp válidos para que un rechazo apunte mejor al manejo de firma. Si el servicio responde invalid algorithm, buena señal. Si responde invalid signature, confirma si el algoritmo está fijado o si el formato de la clave está mal. Cabeceras PEM, saltos de línea y espacios finales pueden cambiar el resultado.
Lista defensiva
Fija algoritmos por emisor. No permitas que el encabezado del token decida si una clave es simétrica o asimétrica. Guarda secretos HMAC y claves públicas RSA o EC en rutas de configuración distintas, con tipos distintos si el lenguaje lo permite. Un verificador RS256 debería negarse a arrancar si recibe un secreto HMAC, y uno HS256 nunca debería cargar una clave pública desde JWKS.
Lección operativa
La corrección es separación aburrida. Un emisor, una familia de algoritmos esperada, una fuente de claves, un wrapper de verificación. Si hay una migración de HS256 a RS256, no aceptes ambos algoritmos indefinidamente para la misma audiencia. Crea una ventana corta, monitoriza el uso del algoritmo antiguo y elimina el fallback al cerrarla.