Secure, HttpOnly y SameSite: corrige los atributos de las cookies
Respuesta corta: las cookies de sesión y de inicio de sesión deberían tener Secure (solo se envían por HTTPS), HttpOnly (JavaScript no puede leerlas, lo que limita el daño de un XSS) y SameSite=Lax o Strict (no se envían en la mayoría de las peticiones entre sitios, lo que ayuda contra el CSRF). Configúralos donde se crea la cookie, o añádelos en el servidor web como alternativa.
El código y la configuración se mantienen en inglés.
Mira lo que envía tu sitio
curl -sI https://yourdomain.com | grep -i '^set-cookie'Sesiones de PHP
session.cookie_secure = 1
session.cookie_httponly = 1
session.cookie_samesite = "Lax"setcookie('name', $value, [
'expires' => time() + 3600,
'path' => '/',
'secure' => true,
'httponly' => true,
'samesite' => 'Lax',
]);WordPress
Las cookies de inicio de sesión de WordPress ya son HttpOnly. Asegúrate de que el panel de administración funcione solo por HTTPS para que también sean Secure:
define( 'FORCE_SSL_ADMIN', true );Las cookies que crean los plugins dependen de cada plugin. Si a alguna le faltan atributos, busca una actualización o usa la alternativa en el servidor que verás más abajo.
nginx (como proxy inverso)
proxy_cookie_flags ~ secure httponly samesite=lax;Apache
Header edit Set-Cookie "^((?!.*;\s*Secure).*)$" "$1; Secure"
Header edit Set-Cookie "^((?!.*;\s*HttpOnly).*)$" "$1; HttpOnly"
Header edit Set-Cookie "^((?!.*;\s*SameSite).*)$" "$1; SameSite=Lax"Si las cookies vienen de un backend detrás de un proxy (por ejemplo, PHP-FPM detrás de ProxyPass) y no cambia nada, usa Header always edit en su lugar.
No rompas nada
- Las cookies que tu propio JavaScript tiene que leer (algunos banners de consentimiento, pruebas A/B) no pueden ser HttpOnly.
SameSite=Nonees necesario para cookies que se usan dentro de iframes de terceros, y exigeSecure.SameSite=Strictpuede cerrar la sesión de los usuarios cuando llegan desde un enlace en un correo.Laxes la opción por defecto más segura.
Preguntas frecuentes
¿Las cookies de analítica necesitan estos atributos?
Secure sí, en un sitio HTTPS. HttpOnly solo si ningún script necesita leerlas, algo poco habitual en analítica.
¿SameSite=Lax basta contra el CSRF?
Bloquea la mayoría de los envíos de formularios entre sitios, pero los formularios que modifican datos deberían seguir usando tokens CSRF.
¿Por qué un escáner sigue indicando que falta un atributo después de corregirlo?
A menudo una caché de páginas o una CDN sirve la respuesta antigua, o un plugin crea su propia cookie. Vacía la caché y vuelve a revisar las líneas Set-Cookie.