Desarrollo de software

Ataques de tiempo en PHP: Un ejemplo práctico - por qué `hash_equals()` es importante

¿Quieres un ejemplo realista de un ataque de temporización a tokens API en Wordpress/Laravel/PHP? Lo cubrimos aquí, incluyendo consejos y medidas de mejores prácticas contra los ataques de temporización.

Muchos desarrolladores confían en la simple comparación mediante === o == cuando comprueban claves API, tokens u otras cadenas secretas. A primera vista, esto parece razonable - pero hay una trampa: las diferencias de tiempo en la comparación pueden ser explotadas por los atacantes.

Este artículo describe un ejemplo realista de cómo funciona conceptualmente un ataque de sincronización.

El escenario real (ejemplo simplificado)

Imagina que un microservicio interno acepta peticiones con un token de parámetro de consulta y lo compara con un token de API de GitHub almacenado en el entorno.

Código inseguro (simplificado):

// insecure.php (ejemplo simplificado)$expected = getenv('GITHUB_API_TOKEN');// e.g. 'V1cHt2S67DADJIm9sX9yzCc272EkSC' $provided = $_GET['token'] ?? '';if ($provided === $expected) { // conceder acceso} PHP  

Explicaré por qué esto es problemático en la siguiente sección.

¿Cómo funciona un ataque de sincronización?

Si la implementación de la comparación de tokens compara carácter por carácter y aborta inmediatamente al primer error, entonces una petición con el primer carácter correcto tardará un poco más de media.

Por tanto, un primer carácter correcto conlleva de media un tiempo de procesamiento ligeramente superior al de un primer carácter incorrecto. Lo mismo ocurre con el segundo carácter y así sucesivamente.

Un atacante se aprovecha de esto probando todos los caracteres posibles para cada posición, midiendo los tiempos de respuesta muy a menudo y analizándolos estadísticamente. El carácter con el mayor tiempo medio/proporcionalmente mayor es probablemente el correcto. De este modo, el token se reconstruye paso a paso.

Por qué hash_equals() es la elección correcta

PHP proporciona una función de comparación de cadenas en tiempo constante con hash_equals(). Asegura que el tiempo de ejecución de la comparación no depende de prefijos comunes - siempre y cuando ambas cadenas tengan la misma longitud.

Alternativa segura (para Laravel, PHP, Wordpress):

// secure.php$expected = getenv('GITHUB_API_TOKEN'); $provided = $_GET['token'] ?? '';if (hash_equals($expected, $provided)) { // conceder acceso} PHP  

Nota: hash_equals() sólo es "independiente del tiempo" si las longitudes son iguales. Es una buena práctica diseñar tokens para que la longitud sea constante (por ejemplo, HMACs, UUIDs de longitud fija o cadenas Base64 aleatorias de longitud fija).

¿Lo sabías? Sólo UUID-V4 se genera de forma completamente aleatoria y, por lo tanto, se utiliza a menudo para los tokens de seguridad. Al no contener información relacionada con la hora o el dispositivo, ofrece un alto nivel de imprevisibilidad y, por lo tanto, protege contra ataques basados en patrones o predicciones. Esta es precisamente la razón por la que UUID-V4 es la opción preferida cuando se trata de identificadores seguros y difíciles de adivinar.

Medidas de defensa adicionales - algo más que hash_equals()

  1. Longitud constante del token
    Utilice tokens con una longitud fija, por ejemplo UUID-V4. Si un atacante adivina la longitud, esto es menos útil siempre que los propios caracteres sean seguros.
  2. Limitación de velocidad
    Limite las solicitudes por IP o por cuenta. Los ataques de sincronización requieren muchas mediciones; la limitación de la tasa aumenta significativamente el esfuerzo y los costes para el atacante.
  3. Registro y supervisión
    Reconozca patrones inusuales (muchos intentos de token, variación sistemática de ciertos parámetros) y reaccione automáticamente.
  4. Sal / HMAC / Firmas
    Utilice tokens firmados (HMAC con clave secreta) o tokens OAuth en lugar de comparar abiertamente claves estáticas sin procesar.
  5. TLS/HTTPS
    La encriptación protege los canales de comunicación - aunque no previene ataques de tiempo a los internos del servidor, es un requisito básico.
  6. Rotación de tokens
    La corta vida de los tokens reduce el beneficio de un token comprometido.

Conclusión

Los ataques de sincronización no son un problema puramente teórico: se han investigado en la práctica y pueden tener graves consecuencias, especialmente para puntos finales de acceso público. La buena noticia: para los desarrolladores de PHP/Laravel/Wordpress, la primera contramedida es muy sencilla:

  • Sustituir las comparaciones directas de cadenas sensibles por hash_equals().
  • Garantizar longitudes de token constantes, limitación de velocidad, registro y gestión segura de tokens.
Sobre el autor
Fundador y director general de Langmeier Software
No quiero complicar nada. No quiero desarrollar el software empresarial definitivo. No quiero figurar en una lista de las mejores tecnologías. Porque las aplicaciones empresariales no son eso. Se trata de asegurarse de que sus datos están perfectamente protegidos. Y se trata de asegurarse de que todo funciona sin problemas mientras usted mantiene el control total y puede centrarse en hacer crecer su negocio. La sencillez y la fiabilidad son mis principios rectores y me inspiran cada día.
 
Busque más:
PHP, Seguridad de los datos, Ciberseguridad
Artículos relacionados