Autenticacion vs. Autorizacion
Antes de profundizar en los mecanismos, entiende los dos conceptos:
- Autenticacion (AuthN) — “Quien eres?” Verificar la identidad del cliente que hace el request.
- Autorizacion (AuthZ) — “Que puedes hacer?” Determinar a que recursos y acciones tiene acceso el cliente autenticado.
Un usuario puede estar autenticado (logueado) pero no autorizado (sin permisos) para eliminar la cuenta de otro usuario. Testear ambos aspectos es critico.
Autenticacion con API Key
La forma mas simple de autenticacion de API. El servidor emite una clave unica que el cliente incluye con cada request.
Como Funciona
GET /api/weather?city=London HTTP/1.1
Host: api.weather.com
X-API-Key: sk_live_abc123def456
O como query parameter (menos seguro):
GET /api/weather?city=London&api_key=sk_live_abc123def456
Testing de API Keys
| Escenario de Test | Resultado Esperado |
|---|---|
| API key valida | 200 OK con datos |
| API key faltante | 401 Unauthorized |
| API key invalida/expirada | 401 o 403 |
| API key revocada | 401 Unauthorized |
| API key de ambiente incorrecto | 401/403 |
| Rate limit excedido para la key | 429 Too Many Requests |
| API key en URL vs header | Ambos deberian funcionar (o URL deberia ser rechazado) |
Preocupaciones de Seguridad
- Las API keys nunca deberian estar en URLs (aparecen en logs del servidor y el historial del navegador)
- Las keys deberian transmitirse solo sobre HTTPS
- Las keys deberian tener permisos con scope (solo lectura vs lectura-escritura)
Basic Authentication
Envia usuario y contrasena codificados en Base64 con cada request. Simple pero no muy seguro.
Como Funciona
GET /api/users HTTP/1.1
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
El valor despues de “Basic” es username:password codificado en Base64. No esta encriptado — cualquiera que intercepte el request puede decodificarlo.
Testing de Basic Auth
# Codificar credenciales
echo -n "admin:secret123" | base64
# Resultado: YWRtaW46c2VjcmV0MTIz
# Usar en request
curl -H "Authorization: Basic YWRtaW46c2VjcmV0MTIz" https://api.example.com/users
Escenarios de test: credenciales validas, contrasena incorrecta, usuario inexistente, credenciales vacias, Base64 malformado.
OAuth 2.0
El estandar de la industria para autorizacion. OAuth 2.0 permite a aplicaciones de terceros acceder a recursos del usuario sin compartir contrasenas.
Flujos de OAuth 2.0
Authorization Code Flow (mas comun para apps web):
- Usuario hace clic en “Iniciar sesion con Google”
- La app redirige al servidor de autorizacion de Google
- Usuario inicia sesion y otorga permisos
- Google redirige de vuelta con un codigo de autorizacion
- La app intercambia el codigo por un access token (servidor a servidor)
- La app usa el access token para llamar APIs
Client Credentials Flow (servidor a servidor, sin usuario):
- La app envia client_id y client_secret al servidor de auth
- El servidor de auth retorna un access token
- La app usa el token para llamar APIs
Tokens clave en OAuth 2.0:
- Access Token — vida corta, usado para acceder APIs (15 min a 1 hora)
- Refresh Token — vida larga, usado para obtener nuevos access tokens (dias a meses)
Testing de OAuth 2.0
| Escenario de Test | Resultado Esperado |
|---|---|
| Access token valido | 200 OK |
| Access token expirado | 401 Unauthorized |
| Flujo de refresh token | Nuevo access token emitido |
| Refresh token expirado | Forzar re-autenticacion |
| Scope invalido | 403 Forbidden |
| Token con scope insuficiente | 403 con error de scope |
| Token revocado | 401 Unauthorized |
| Usar access token despues de logout | 401 Unauthorized |
JSON Web Tokens (JWT)
JWT es un formato de token compacto y autocontenido comunmente usado para autenticacion. Permite al servidor verificar el token sin consultar una base de datos.
Estructura de JWT
Un JWT tiene tres partes separadas por puntos: header.payload.signature
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFsaWNlIn0.signature
Header (algoritmo y tipo):
{
"alg": "HS256",
"typ": "JWT"
}
Payload (claims — datos del usuario):
{
"sub": "1234567890",
"name": "Alice",
"role": "admin",
"iat": 1716239022,
"exp": 1716242622
}
Signature (verificacion):
HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
Claims Importantes de JWT
| Claim | Nombre | Proposito |
|---|---|---|
sub | Subject | Identificador del usuario |
iat | Issued At | Cuando se creo el token |
exp | Expiration | Cuando expira el token |
iss | Issuer | Quien creo el token |
aud | Audience | Para quien esta destinado el token |
role | Role | Permisos del usuario (personalizado) |
Testing de Autenticacion JWT
Tests de validacion de token:
- Token valido — 200 OK
- Token expirado — 401 Unauthorized
- Payload alterado (claims modificados) — 401 (firma invalida)
- Firma faltante — 401
- Token firmado con secret incorrecto — 401
- Token con
alg: none— 401 (test de seguridad critico)
Tests del ciclo de vida del token:
- Verificar que el token contiene los claims esperados despues del login
- Verificar que tokens expirados son rechazados
- Testear que el flujo de refresh genera un nuevo token valido
- Verificar que tokens antiguos son invalidos despues del cambio de contrasena
- Testear que el token funciona en diferentes endpoints de la API
Decodificar JWT para testing (usa jwt.io o linea de comandos):
# Decodificar payload (parte del medio)
echo "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFsaWNlIn0" | base64 -d
Vulnerabilidades Comunes de Autenticacion para Testear
1. Autenticacion Rota
- Puedes acceder a endpoints protegidos sin ningun token?
- La API acepta tokens despues de que deberian estar invalidados?
- Las contrasenas se transmiten en texto plano?
2. Manipulacion de Tokens
- Puedes modificar claims del JWT y seguir accediendo a recursos? (verificacion de firma debil/faltante)
alg: noneevita la verificacion de firma?- Puedes usar un token de un ambiente en otro?
3. Proteccion contra Fuerza Bruta
- Hay bloqueo despues de multiples intentos fallidos de login?
- Se aplican rate limits a endpoints de autenticacion?
- Los mensajes de error revelan si un usuario existe?
4. Gestion de Sesiones
- Los tokens se invalidan al hacer logout?
- El cambio de contrasena invalida tokens existentes?
- Pueden existir multiples sesiones activas simultaneamente?
Ejercicio Practico
- Configura testing de JWT: Usa jwt.io para crear y decodificar JWTs. Modifica claims y observa que pasa cuando envias tokens alterados.
- Testea flujos de autenticacion: Usando una API publica que requiera autenticacion (GitHub API con personal access tokens), testea escenarios de auth valida, invalida y faltante.
- Crea una matriz de test: Para una API imaginaria con roles admin y user, crea una matriz de endpoints x roles x status codes esperados.
- Testea expiracion de token: Si esta disponible, obtene un token de vida corta y verifica que es rechazado despues de la expiracion.
Puntos Clave
- La autenticacion verifica identidad (quien eres); la autorizacion verifica permisos (que puedes hacer)
- Las API Keys son simples pero limitadas — mejores para comunicacion servidor-a-servidor y rate limiting de APIs publicas
- OAuth 2.0 es el estandar para acceso de terceros con multiples flujos para diferentes casos de uso
- Los JWTs son tokens autocontenidos con header, payload y signature — el payload es legible por cualquiera
- Siempre testea el ciclo de vida completo: tokens validos, expirados, revocados, alterados y faltantes