// Seguridad de OTP

Buenas prácticas de OTP: códigos, caducidad, límites de tasa y respaldo

Una contraseña de un solo uso parece trivial: genera un número, envíalo por texto, compruébalo. Pero los detalles son donde viven los fallos de robo de cuenta. Esta guía cubre las decisiones que hacen que un flujo de OTP sea de verdad seguro y usable: entropía del código, almacenamiento, ventanas de caducidad, limitación de tasa, reintentos y canales de respaldo.

Genera códigos con entropía real

Usa un generador aleatorio criptográficamente seguro, nunca una semilla predecible ni un valor derivado de una marca de tiempo. Seis dígitos es el equilibrio habitual entre seguridad y usabilidad; los códigos más cortos necesitan límites de tasa más estrictos para ser seguros.

Nunca envíes el mismo código dos veces, ni hagas un código adivinable a partir de un id de usuario o una secuencia. Toda la seguridad del OTP por SMS descansa en que el código sea impredecible durante su corta vida.

  • Usa un CSPRNG (por ejemplo, bibliotecas secrets/crypto), no un PRNG de uso general.
  • 6 dígitos es lo estándar; si usas 4, aprieta con fuerza los límites de tasa y la caducidad.
  • Un código por solicitud; invalida los códigos anteriores cuando emitas uno nuevo.

Almacena los códigos de forma segura, nunca en texto plano

Trata un OTP como una contraseña de vida corta. Almacena un hash del código (con el identificador y la caducidad) en lugar del valor en bruto, para que una filtración de la base de datos no exponga códigos vivos. Compara con una función de tiempo constante para evitar ataques de temporización, y elimina el registro en cuanto se use o caduque.

  • Aplica hash al código antes de almacenarlo; compara en tiempo constante.
  • Vincula cada código a un único usuario/sesión y propósito.
  • Elimina al tener éxito, al caducar o al alcanzar el tope de intentos.

Establece una ventana de caducidad corta

Los códigos deben vivir minutos, no horas. Una caducidad de 5 a 10 minutos es el rango habitual: suficiente para que un SMS retrasado aún llegue, corto para que un código filtrado ya suela estar muerto. Muestra la validez restante al usuario para que un mensaje lento no parezca un flujo roto.

!

Combina una caducidad corta con un tiempo de espera de reenvío, o los usuarios machacarán el reenvío cuando un mensaje se retrase y multiplicarán tu coste de SMS.

Limita la tasa en todas las dimensiones

La limitación de tasa es lo que detiene tanto la adivinación por fuerza bruta de los códigos como el abuso de tu endpoint de envío (que te cuesta dinero y puede hacer que marquen a tu remitente). Limita por número de teléfono, por IP y por cuenta, tanto en el envío como en la verificación.

  • Intentos de verificación: limita los intentos por código (por ejemplo, 5) y luego invalida y fuerza el reenvío.
  • Solicitudes de envío: tiempo de espera entre envíos y un tope diario por número.
  • Guardias globales: límites por IP y por cuenta para amortiguar el abuso automatizado.
  • Añade retroceso exponencial o CAPTCHA cuando se alcancen los límites repetidamente.

Maneja reintentos y canales de respaldo

El SMS es de mejor esfuerzo, así que un buen flujo asume que algunos mensajes no llegarán. Ofrece un reenvío tras un tiempo de espera y, tras uno o dos intentos de SMS fallidos, escala a un canal de respaldo — una llamada de voz que lee el código, WhatsApp o email — que es exactamente lo que automatizan las Verify APIs gestionadas.

Haz humanos los estados de fallo: una vía clara de "¿no lo has recibido?", una forma de cambiar el número y contacto con soporte tras fallos repetidos.

  1. 1

    Primer intento: SMS

    Envía el código e inicia una cuenta atrás visible con un tiempo de espera de reenvío.

  2. 2

    Reenvío a petición

    Permite un reenvío tras el tiempo de espera; invalida el código anterior cuando emitas uno nuevo.

  3. 3

    Escala de canal

    Tras fallos de SMS repetidos, ofrece voz o un canal alternativo para entregar la misma verificación.

  4. 4

    Ofrece una salida

    Deja que el usuario corrija su número o llegue a soporte en lugar de quedar en un callejón sin salida.

Mejora la UX sin debilitar la seguridad

Pequeños detalles elevan las tasas de finalización: usa la WebOTP API y los formatos de autorrelleno de SMS para que los navegadores móviles lean el código, mantén una redacción de mensaje consistente (algunas plataformas cachean remitentes de confianza) y no incluyas nada más que el código y el nombre de tu app. Evita enlaces en los mensajes de OTP: acostumbran a los usuarios a hacer clic y hacen saltar los filtros de spam de operadora.

  • Soporta WebOTP / autorrelleno de código de un solo uso en móvil.
  • Mantén el mensaje mínimo: nombre de app + código, sin marketing, sin enlaces.
  • Localiza el texto del mensaje pero mantén estable el formato del código.

Preguntas frecuentes

¿Cuánto tiempo debe ser válido un OTP?+

De cinco a diez minutos es la ventana habitual. Es suficiente para sobrevivir a un SMS retrasado pero corta para que un código filtrado ya suela estar caducado. Muestra siempre el tiempo restante para que un mensaje lento no parezca un flujo roto.

¿Cuántos intentos de verificación debo permitir?+

Limita los intentos por código a unos cinco, luego invalida el código y exige un envío nuevo. Combínalo con límites de tasa por número, por IP y por cuenta tanto en el envío como en la verificación para detener la fuerza bruta y el abuso del endpoint de envío.

¿Debo poner un enlace en el mensaje de OTP?+

No. Mantén los mensajes de OTP con solo el nombre de tu app y el código. Los enlaces acostumbran a los usuarios a hacer clic, pueden filtrar el código a través de los referrers y disparan con frecuencia el filtrado de spam de operadora que daña la entregabilidad.

¿Es el OTP por SMS suficientemente seguro por sí solo?+

El OTP por SMS es un salto significativo respecto a solo contraseñas, pero es vulnerable a SIM swaps e interceptación. Para cuentas de alto valor, ofrece factores más fuertes como passkeys o TOTP y trata el SMS como respaldo; consulta la guía de alternativas a OTP.

EdgeGigs

Implementa tu flujo de OTP bien a la primera.

Contrata en EdgeGigs a un desarrollador verificado para construir generación de códigos segura, caducidad, limitación de tasa y respaldo en tu app web o móvil.

Encuentra un desarrollador en EdgeGigs