El ciclo WebAuthn: fallos lógicos comunes en el apretón de manos "sin contraseña"

La industria de la ciberseguridad está atravesando su cambio más importante en décadas: la transición de “secretos compartidos” (contraseñas) a “prueba asimétrica de posesión” (passkeys). Basados en el estándar WebAuthn (FIDO2), los passkeys prometen un futuro inmune a phishing, credential stuffing y la fatiga de la autenticación basada en memoria.
Sin embargo, a medida que su adopción crece en 2025, ha surgido una tendencia peligrosa. Investigadores de seguridad y testers de penetración están identificando un fenómeno recurrente conocido como el “Bucle WebAuthn”. Esto sucede cuando un protocolo técnicamente “no-phishable” se ve socavado por una lógica de implementación defectuosa, especialmente en el apretón de manos entre solicitudes frontend y verificación backend.
En este análisis profundo, desglosamos los desajustes técnicos, las “trampas del apretón de manos” y las recuperaciones críticas que están reintroduciendo los mismos agujeros de seguridad que los passkeys estaban diseñados para cerrar.
1. La anatomía de un apretón de manos WebAuthn moderno
Para entender los fallos, primero debemos ver cómo se supone que funciona el apretón de manos. A diferencia de un inicio de sesión con contraseña, que es una comparación de cadenas simple, una ceremonia WebAuthn implica un intercambio complejo de tres vías entre la Parte Confiable (tu servidor), el Cliente (el navegador/OS) y el Autenticador (sensor biométrico o llave de seguridad).
El flujo de registro:
Generación del desafío: El servidor envía un desafío aleatorio criptográficamente y un ID de la Parte Confiable (RP ID).
Creación de credencial: El dispositivo del usuario genera un par de claves pública-privada.
Atestación: El dispositivo envía la clave pública, un credentialID y un “objeto de atestación” (prueba de que la clave fue creada por un dispositivo legítimo) de vuelta al servidor.
Verificación: El servidor valida la firma y almacena la clave pública.
El flujo de autenticación:
Solicitud de afirmación: El servidor envía un nuevo desafío.
Firma: El autenticador firma el desafío con la clave privada.
Verificación de afirmación: El servidor usa la clave pública almacenada para verificar la firma.
El “Bucle” comienza cuando los desarrolladores tratan este complejo baile criptográfico como una simple presentación de formulario API.
2. Fallo #1: La brecha en la validación del Origen & RP ID
La característica más poderosa de WebAuthn es la Vinculación de Origen. Un passkey creado para bank.com no puede usarse en bänk.com (un sitio de phishing con homógrafos). El navegador aplica esto estrictamente. Sin embargo, el navegador solo hace cumplir una parte del contrato.
El desajuste técnico:
Muchas implementaciones backend no verifican estrictamente el clientDataJSON devuelto por el autenticador. Durante el apretón de manos, el autenticador proporciona un objeto codificado en base64 que contiene el origen donde tuvo lugar la ceremonia.
El fallo lógico: Si el código backend solo verifica la firma pero omite la verificación manual del campo origin dentro del clientDataJSON, crea una oportunidad de “Phishing Reenviado”. Un atacante podría hacer proxy de una ceremonia WebAuthn legítima a través de un dominio malicioso, y si el backend es perezoso, aceptará una firma válida de un origen “inválido”.
La solución 2025: Implementa siempre una lista blanca estricta de orígenes en el servidor. En un entorno multi-dominio (por ejemplo, brand.co.uk y brand.com), usa las nuevas solicitudes relacionadas de origen (ROR) para compartir de forma segura los RP IDs entre dominios sin reducir la seguridad.
3. Fallo #2: El “Desafío Estático” y la vulnerabilidad de Repetición
Un error común en la implementación de WebAuthn es tratar el “desafío” como un simple identificador de sesión en lugar de un nonce criptográfico.
El desajuste técnico:
El desafío debe ser:
- Generado en el servidor.
- De alta entropía (al menos 16 bytes).
- De corta duración (con límite de tiempo).
- De un solo uso.
El fallo lógico: Algunos desarrolladores usan desafíos estáticos o predecibles (como un ID de usuario o una marca de tiempo) para simplificar la naturaleza “sin estado” de sus APIs. Si un desafío se reutiliza o persiste en varias sesiones, un atacante que intercepte una afirmación firmada puede realizar un Ataque de Repetición. No necesitan tu clave privada; solo necesitan reenviar tu última prueba válida a un servidor que no comprueba si ese desafío específico ya fue “consumido”.
La solución 2025: Usa un patrón “Almacenar-Desafío-Verificar”. Guarda el desafío en una caché del servidor (como Redis) con un TTL de 60–120 segundos. Una vez que se verifica la firma, elimina inmediatamente el desafío de la caché.
4. Fallo #3: La “Paradoja de la Recuperación” (El eslabón más débil)
Este es el fallo lógico más crítico en el ecosistema “Passwordless”. Los passkeys son prácticamente imposibles de phishing. Pero, ¿qué pasa cuando un usuario pierde su teléfono?
El desajuste técnico:
Para evitar “bloqueos”, los servicios implementan recuperación de cuenta. A menudo, vuelven a las “viejas formas”:
- Códigos de un solo uso vía SMS (OTP).
- Enlaces mágicos por email.
- Preguntas de seguridad.
El fallo lógico: Al ofrecer una recuperación por OTP vía SMS, efectivamente haces que tu implementación de passkeys sea inútil. Un atacante no intentará romper la criptografía WebAuthn; simplemente hará clic en “Perdí mi dispositivo” e iniciará un ataque de intercambio de SIM o ingeniería social para interceptar el código SMS.
La seguridad de la cuenta “bucle” vuelve al eslabón más débil. Solo en 2024, más del 22% de las brechas comenzaron con abuso de credenciales, a menudo apuntando a estos mecanismos de “respaldo”.
La solución 2025:
Fomenta múltiples passkeys: Pide a los usuarios que registren un dispositivo de respaldo (por ejemplo, una laptop y un teléfono) o una llave de hardware (YubiKey).
Códigos de recuperación: Proporciona “códigos de recuperación” de un solo uso que el usuario debe guardar offline.
Verificación de identidad: Para cuentas de alto valor, requiere un período de espera de 24 horas o verificación manual de identidad antes de permitir un restablecimiento de passkey.
5. Fallo #4: Negligencia en la atestación & el problema del “Autenticador Virtual”
Durante el registro, el servidor puede solicitar “Atestación”. Esto es un certificado digital del fabricante del dispositivo (Apple, Google, Yubico) que prueba que la clave pública fue generada dentro de un enclave seguro o un Módulo de Seguridad de Hardware (HSM).
El desajuste técnico:
Muchas librerías usan por defecto la atestación: “none” porque verificar las declaraciones de atestación es técnicamente difícil y requiere mantener una lista de certificados raíz confiables.
El fallo lógico: Al ignorar la atestación, tu servidor no puede saber si la “passkey” es realmente una clave segura vinculada al hardware o una “autenticador virtual” emulado por un script atacante. Aunque las “Passkeys sincronizadas” (como las en iCloud) han hecho que la atestación sea más compleja, los entornos empresariales aún deben aplicar verificaciones estrictas.
La solución 2025: Usa el Servicio de Metadatos FIDO (MDS3). Es una base de datos centralizada de características del autenticador. Al verificar en el MDS3, tu backend puede confirmar que una passkey proviene de un dispositivo con sensor biométrico y almacenamiento respaldado por hardware, en lugar de un navegador Chrome sin cabeza.
6. Fallo #5: Desincronización frontend/backend y el “Fallo Exitoso”
WebAuthn es un proceso de múltiples pasos. En muchas SPA modernas (Single Page Applications) construidas con React o Next.js, el frontend maneja la llamada a navigator.credentials, y el backend realiza la verificación.
El desajuste técnico:
Un error común es que el frontend “valida” la respuesta del autenticador y luego simplemente dice al backend, “El usuario lo firmó, aquí está el ID, ingrésalo.”
El fallo lógico: El backend nunca debe confiar en una señal de “éxito” del frontend. En varios CVEs de 2024 (especialmente en algunos wrappers de autenticación de Next.js), se encontró que un atacante podía evadir la verificación WebAuthn interceptando la llamada API del frontend e inyectando un estado de “Éxito”, que el backend aceptaba sin verificar realmente la firma criptográfica contra la clave pública almacenada.
La solución 2025: El backend debe ser la única fuente de verdad. La única función del frontend es transportar los bytes crudos del navegador al servidor. El servidor debe hacer todo el procesamiento: analizar authData, hashear el clientDataJSON y realizar la verificación de firma RS256 o ES256.
7. Cómo “Cerrar el ciclo”: Lista de verificación para desarrolladores
Para construir un sistema verdaderamente seguro sin contraseña, pasa de los tutoriales básicos y aborda estos fallos lógicos directamente:
Aplicar estrictamente la validación de origen: No solo verifiques la firma. Analiza el clientDataJSON y asegúrate de que el origen coincida exactamente con tu dominio.
El estado sin estado es peligroso: Asegúrate de que tus desafíos sean aleatorios, generados por el servidor y consumidos al usarlos.
La UX “Passkey-First”: Si un usuario tiene un passkey, no muestres el campo “Contraseña” por defecto. Esto evita que sean engañados para ingresar una contraseña que ya no usan.
Audita tus mecanismos de respaldo: Si debes usar SMS como respaldo, trátalo como un “estado de seguridad degradado”. Notifica al usuario por email y limita los permisos de la cuenta durante 48 horas tras una recuperación por SMS.
Usa librerías verificadas: No “te hagas tú mismo” la lógica WebAuthn. Usa librerías probadas como SimpleWebAuthn, FIDO2-lib, o servicios gestionados como Clerk, Auth0 o Passkeys.io que manejan MDS3 y validación de origen de forma automática.
Conclusión: El futuro es sin contraseña, no sin lógica
Los passkeys representan un avance monumental en seguridad, pero no son una solución de “configurar y olvidar”. El ciclo WebAuthn nos enseña que las mayores vulnerabilidades a menudo están en las transiciones—los apretones de manos entre el navegador y el servidor, y el cambio de modos “seguro” a “recuperación”.
Al centrarse en los desajustes técnicos entre la conveniencia del frontend y el rigor del backend, los desarrolladores pueden garantizar que la promesa “sin contraseña” realmente cumpla su objetivo: una web donde tu identidad te pertenece a ti, y nadie más.
Related InstaTunnel pages
Continue from this article into the most relevant product guides and workflows.
Related Topics
Keep building with InstaTunnel
Read the docs for implementation details or compare plans before you ship.