Express.js
Cookies seguras
Explica cómo configurar cookies con HttpOnly, Secure, SameSite, Domain, Path y expiración, además de firma, rotación y riesgos de sesión.
- Última actualización
- Actualizada
- Nivel
- Aplicación
Express.js
Explica cómo configurar cookies con HttpOnly, Secure, SameSite, Domain, Path y expiración, además de firma, rotación y riesgos de sesión.
El servidor envía:
Set-Cookie: session=opaque-id; HttpOnly; Secure; SameSite=Lax; Path=/El navegador almacena la cookie y la adjunta automáticamente a requests que cumplen Domain, Path, Secure, SameSite y expiración.
HTTP es stateless. Las cookies permiten relacionar requests con una sesión, preferencia o token de corta duración sin que el código cliente construya manualmente cada header.
El envío automático también crea riesgo CSRF y amplía el impacto de una cookie robada.
Impide lectura mediante document.cookie. Reduce robo directo por XSS, pero un script malicioso todavía puede realizar requests autenticadas desde la página.
Solo envía por HTTPS. Detrás de proxy, Express necesita percibir correctamente el protocolo mediante trust proxy.
Strict: muy restrictivo; puede romper navegación legítima.Lax: permite algunos contextos de navegación top-level y bloquea buena parte de CSRF clásico.None: permite cross-site y exige Secure.No es una protección universal; evalúa el flujo real.
Sin Domain, la cookie es host-only. Definir .example.com la comparte con subdominios y amplía superficie.
Limita rutas en las que el navegador la envía. No es una frontera de seguridad fuerte porque otras rutas del mismo origen pueden establecer cookies con nombres relacionados.
Definen persistencia. Una cookie sin ambos suele ser de sesión del navegador, aunque el comportamiento de restauración varía.
__Host-: requiere Secure, Path=/ y ausencia de Domain.__Secure-: requiere Secure.Los prefijos ayudan a evitar configuraciones débiles en navegadores compatibles.
response.cookie('__Host-session', sessionId, {
httpOnly: true,
secure: true,
sameSite: 'lax',
path: '/',
maxAge: 1000 * 60 * 60,
});En desarrollo HTTP local, secure: true puede impedir que se envíe. Configura por entorno sin debilitar producción.
Debes usar atributos compatibles con los usados al crear:
response.clearCookie('__Host-session', {
httpOnly: true,
secure: true,
sameSite: 'lax',
path: '/',
});Borrar solo cambia el navegador; también revoca la sesión en el store.
Añade MAC para detectar modificación. El valor sigue visible.
Protege confidencialidad, pero necesita autenticación, gestión de nonce, rotación y claves. Evita criptografía casera.
Para sesiones suele ser preferible un ID opaco y estado en servidor.
Las cookies viajan en muchas requests. Guardar perfiles, permisos o JWT enormes:
Mantén el contenido mínimo.
Un subdominio comprometido puede intentar establecer una cookie con mismo nombre y distinto alcance. Prefijos __Host-, host-only cookies y separación de dominios reducen riesgo.
const session = await sessions.create({
userId: user.id,
userAgent: request.get('user-agent'),
});
response.cookie('__Host-session', session.id, cookieOptions);
response.status(204).end();La cookie contiene solo un identificador aleatorio. El servidor conserva identidad, expiración y revocación.
Si frontend y API son realmente cross-site, puede requerir SameSite=None, credentials CORS y protección CSRF explícita.
Path/Domain distintos pueden enviar varias. Evita configuraciones ambiguas.
Para cookies firmadas, acepta temporalmente claves anteriores y firma nuevas con la actual.
Sin trust proxy correcto, la app puede creer que la conexión no es segura y no establecer cookies Secure.
Max-Age suele ser más predecible que depender únicamente de fechas absolutas.
Verifica:
Cookies simplifican navegadores y sessions, pero se envían automáticamente y requieren CSRF. Bearer headers reducen ese vector, pero el almacenamiento accesible a JavaScript aumenta impacto de XSS.
__Host-?Sessions del lado del servidor utiliza una cookie opaca para resolver identidad y estado revocable.