Concepto
Un timing attack es un ataque donde un adversario mide el tiempo de ejecución de una operación para inferir información (p.ej. una contraseña o clave API).
El problema
Comparación ingenua (==)
if token == expected:
return True
return False
Riesgo: La comparación de strings en Python termina cuando encuentra el primer byte diferente:
- Token correcto: “abc123” vs “abc123” → 6 comparaciones byte a byte
- Token incorrecto byte 1: “xbc123” vs “abc123” → 1 comparación (mismatch en posición 0, termina)
- Token incorrecto byte 2: “axc123” vs “abc123” → 2 comparaciones (mismatch en posición 1, termina)
Ataque:
for i in range(256):
for j in range(256):
token = bytes([i, j] + [0] * 30) # Probar todos los valores
t_start = time.perf_counter()
response = request(token=token)
t_end = time.perf_counter()
if t_end - t_start > threshold:
print(f"Byte {i},{j} es correcto (tarda más)")
break
Midiendo el tiempo de respuesta, el atacante puede adivinar byte a byte qué es el token correcto.
La solución: hmac.compare_digest()
import hmac
if hmac.compare_digest(provided, expected):
return True
return False
Cómo funciona:
- Compara todos los bytes sin importar dónde esté la diferencia
- Tarda siempre el mismo tiempo (en el mejor de los casos)
- Implementado en C, resistente a optimizaciones del compilador
RFC 5234 (HMAC) + CWE-208 (Information Exposure Through Timing Discrepancy) recomiendan esto.
En CreaRack Pro
Antes de Etapa 3 (vulnerable)
core/workspace_api.py (_check_key):
def _check_key(request) -> bool:
if not WORKSPACE_API_KEY:
return False
return request.headers.get("X-Workspace-Key") == WORKSPACE_API_KEY # ⚠️ Timing attack
config/urls.py (_InternalToolsAuth.authenticate):
if token == expected: # ⚠️ Timing attack
return token
return None
Después de Etapa 3 (mitigado)
core/workspace_api.py:
import hmac
def _check_key(request) -> bool:
"""Validate workspace API key from header (constant-time compare)."""
if not WORKSPACE_API_KEY:
return False
provided = request.headers.get("X-Workspace-Key", "")
return hmac.compare_digest(provided, WORKSPACE_API_KEY) # ✅ Constant-time
config/urls.py:
import hmac as _hmac
class _InternalToolsAuth(HttpBearer):
def authenticate(self, request, token):
expected = (_os.environ.get("INTERNAL_TOOLS_TOKEN") or "").strip()
if not expected or len(expected) < 32:
return None
if _hmac.compare_digest(token or "", expected): # ✅ Constant-time
return token
return None
Impacto de seguridad
| Aspecto | Antes | Después |
|---|---|---|
| Exposición a timing attacks | ✅ Vulnerable | ✅ Mitigado |
| Tiempo de comparación | Variable (1-N bytes) | Constante |
| Overhead | Ninguno | Mínimo (C-level) |
| Compatibilidad | N/A | Python 3.3+ (stdlib) |
Cuándo usar hmac.compare_digest()
✅ Siempre que compares:
- API keys / tokens
- Passwords (junto con hashing, p.ej. bcrypt)
- HMAC tags
- Signatures
- Cualquier secreto de longitud fija
❌ No necesario para:
- Comparaciones de valores públicos (IDs, timestamps)
- Búsquedas de texto (donde el atacante no controla el input)
Limitaciones
-
Solo mitiga timing attacks
- No protege contra ataques de fuerza bruta (iterate 2^128 claves)
- La defensa complementaria es: tasa límite (rate limit), tiempos de espera exponencial
-
Asume tokens de igual longitud
hmac.compare_digest("abc", "abcdefgh") # Devuelve False rápido (longitud diferente)- Solución: Validar longitud antes
-
Depende del contexto
# ❌ MAL: Timing attack aún posible en la rama principal if not token: return None return hmac.compare_digest(token, expected) # ✅ BIEN: Mismo tiempo de cómputo provided = request.headers.get("X-Workspace-Key", "") return hmac.compare_digest(provided or "", expected)
En CreaRack, se rellena con default "" para evitar esta rama.
Referencias
- RFC 5234: HMAC-based Extract-and-Expand Key Derivation Function
- CWE-208: Observable Timing Discrepancy
- Python
hmac.compare_digest()docs - Auditoría Suprema Etapa 3
Véase también
- [[feature—config-ia—auditoria-suprema-etapa-3]]
- [[concept—security—key-management]]
- [[entity—core—service—anonymize-for-ai]]
- [[decision—20260611—agent-jwt-secret-dedicada]]
- [[concept—security—data-isolation]]