Cookies y seguridad HTTP
Cómo se le devuelve la memoria a un protocolo que no la tiene, qué atributos protegen una cookie, y las cuatro piezas de seguridad que viven en las cabeceras: BASIC, CORS, HSTS y CSP.
HttpOnly, Secure y SameSite
Tres atributos más no controlan el alcance sino la seguridad, y son los que caen en el examen. Cada uno tapa un agujero distinto.
| Atributo | Qué impide | Contra qué ataque |
|---|---|---|
| HttpOnly | Que el código JavaScript de la página pueda leer la cookie | Robo de sesión mediante scripts inyectados (XSS) |
| Secure | Que la cookie viaje por una conexión sin cifrar | Interceptación del identificador de sesión en la red |
| SameSite | Que la cookie se envíe en peticiones originadas por otro sitio | Peticiones falsificadas desde otro dominio (CSRF) |
SameSite admite tres valores: Strict no la envía nunca desde otro sitio, ni siquiera al llegar por un enlace; Lax, que es el comportamiento por defecto de los navegadores actuales, la envía solo en navegaciones de primer nivel; y None la envía siempre, pero entonces es obligatorio marcar también Secure.
La sesión propiamente dicha suele ser un identificador aleatorio dentro de la cookie, mientras que los datos del usuario se guardan en el servidor. La alternativa sin sesión, en la que el propio testigo lleva dentro la información firmada, es JWT, y se estudia en el tema de servicios web del bloque de Desarrollo.
Para el examen
HttpOnly: impide leerla desde JavaScript; protege del XSS
Secure: la limita a HTTPS
SameSite: la defensa contra el CSRF
Autenticación BASIC
Es el esquema de autenticación más antiguo del protocolo y sigue cayendo porque su funcionamiento es muy preguntable. El servidor responde 401 con la cabecera WWW-Authenticate indicando el esquema Basic, el navegador muestra su propia ventana de usuario y contraseña, y repite la petición añadiendo la cabecera Authorization.
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="Zona de administración"
GET /admin HTTP/1.1
Host: www.llegandoalcorte.com
Authorization: Basic ZGllZ286c3UtY29udHJhc2XDsWE=Lo que viaja detrás de la palabra Basic es el usuario y la contraseña unidos por dos puntos y codificados en Base64. Base64 no es cifrado: es una representación reversible que cualquiera puede deshacer al instante. Por eso BASIC solo es admisible sobre HTTPS, donde lo que protege el secreto es TLS y no el esquema.
El reto de BASIC es siempre un 401 con WWW-Authenticate. El 403 no forma parte de este intercambio: es la respuesta a alguien ya identificado que no tiene permiso.
Para el examen
Cómo manda las credenciales: en Base64
Qué NO es Base64: cifrado
Sin HTTPS: van prácticamente en claro
CORS y la petición de comprobación previa
Por defecto el navegador aplica la política del mismo origen: el código de una página solo puede leer respuestas de su propio origen, entendido como la terna de esquema, dominio y puerto. CORS es el mecanismo con el que un servidor autoriza expresamente a que otro origen lea sus respuestas.
Para las peticiones que pueden tener efectos, el navegador no se arriesga: antes de mandarlas envía una petición de comprobación previa, el preflight, con el método OPTIONS. En ella anuncia qué método y qué cabeceras piensa usar, mediante Access-Control-Request-Method y Access-Control-Request-Headers. El servidor contesta con Access-Control-Allow-Origin, Access-Control-Allow-Methods y Access-Control-Allow-Headers, y solo si la respuesta autoriza lo pedido el navegador envía la petición de verdad.
OPTIONS /api/intentos HTTP/1.1
Origin: https://app.llegandoalcorte.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://app.llegandoalcorte.com
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Headers: content-type
Access-Control-Max-Age: 600Dos precisiones que se prestan a confusión. La autorización va por recurso, no por servidor entero. Y el rechazo no tiene un código propio: si el servidor no devuelve las cabeceras de autorización, la respuesta puede ser perfectamente un 200 y es el navegador quien bloquea el acceso al contenido. El 405 aparece en un caso distinto, cuando el servidor ni siquiera admite el método OPTIONS y por tanto el preflight no llega a responderse.
Para el examen
Qué bloquea la política del mismo origen: las peticiones entre orígenes distintos
Quién autoriza la excepción: el SERVIDOR, con Access-Control-Allow-Origin
Comprobación previa: va con el método OPTIONS
HSTS: obligar a ir siempre por HTTPS
Redirigir de HTTP a HTTPS con un 301 resuelve el caso normal pero deja una rendija: esa primera petición ha viajado en claro, y quien esté en medio de la red puede interceptarla antes de que llegue la redirección.
HSTS cierra esa rendija con la cabecera Strict-Transport-Security. Cuando el navegador la recibe, apunta durante el tiempo indicado en max-age que ese dominio solo se visita por HTTPS, y a partir de ese momento convierte internamente cualquier dirección http del sitio antes de enviar nada. El añadido includeSubDomains extiende la regla a todos los subdominios.
Strict-Transport-Security: max-age=31536000; includeSubDomainsEl 301 es la redirección, no HSTS, y no es un error pese a lo que sugiere el nombre de la familia. HSTS es la cabecera que hace que la próxima vez ni siquiera haya que redirigir.
Para el examen
Qué es: una cabecera de respuesta
Qué obliga: a usar solo HTTPS en ese dominio durante el plazo indicado
Qué evita: el ataque de degradación a HTTP
CSP: de dónde puede cargar la página
La política de seguridad de contenido, o CSP, es más restrictiva y más fina que CORS, y ataca otro problema. CORS decide quién puede leer una respuesta; CSP decide de qué orígenes puede la propia página cargar cada tipo de recurso.
Se declara con la cabecera Content-Security-Policy, cuyo valor es una lista de directivas separadas por punto y coma. Cada directiva es un tipo de recurso terminado en -src, y a su lado van los orígenes permitidos: script-src para el código, style-src para las hojas de estilo, img-src para las imágenes, y default-src como valor de reserva para lo que no se haya nombrado.
Content-Security-Policy: default-src 'self'; script-src 'self'; img-src 'self' data:; style-src 'self'Su utilidad principal es frenar el cross site scripting: si un atacante consigue inyectar una etiqueta de script que apunta a un servidor suyo, el navegador se niega a cargarla porque ese origen no está en la lista. La protección no depende de que el servidor haya filtrado bien la entrada.
Para el examen
Qué declara: de qué orígenes puede cargar la página guiones, estilos e imágenes
Contra qué protege: es la defensa de fondo frente al XSS