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 TestResultado Esperado
API key valida200 OK con datos
API key faltante401 Unauthorized
API key invalida/expirada401 o 403
API key revocada401 Unauthorized
API key de ambiente incorrecto401/403
Rate limit excedido para la key429 Too Many Requests
API key en URL vs headerAmbos 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):

  1. Usuario hace clic en “Iniciar sesion con Google”
  2. La app redirige al servidor de autorizacion de Google
  3. Usuario inicia sesion y otorga permisos
  4. Google redirige de vuelta con un codigo de autorizacion
  5. La app intercambia el codigo por un access token (servidor a servidor)
  6. La app usa el access token para llamar APIs

Client Credentials Flow (servidor a servidor, sin usuario):

  1. La app envia client_id y client_secret al servidor de auth
  2. El servidor de auth retorna un access token
  3. 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 TestResultado Esperado
Access token valido200 OK
Access token expirado401 Unauthorized
Flujo de refresh tokenNuevo access token emitido
Refresh token expiradoForzar re-autenticacion
Scope invalido403 Forbidden
Token con scope insuficiente403 con error de scope
Token revocado401 Unauthorized
Usar access token despues de logout401 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

ClaimNombreProposito
subSubjectIdentificador del usuario
iatIssued AtCuando se creo el token
expExpirationCuando expira el token
issIssuerQuien creo el token
audAudiencePara quien esta destinado el token
roleRolePermisos 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: none evita 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

  1. Configura testing de JWT: Usa jwt.io para crear y decodificar JWTs. Modifica claims y observa que pasa cuando envias tokens alterados.
  2. 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.
  3. 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.
  4. 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