Secure、HttpOnly 和 SameSite:修复 Cookie 属性
简短回答:会话和登录 Cookie 应设置 Secure(只通过 HTTPS 发送)、HttpOnly(JavaScript 无法读取,可限制 XSS 造成的损害)以及 SameSite=Lax 或 Strict(大多数跨站请求中不会发送,有助于防范 CSRF)。在创建 Cookie 的地方设置这些属性,或在 Web 服务器上添加作为兜底。
代码和配置保持英文。
查看你的网站发送了什么
curl -sI https://yourdomain.com | grep -i '^set-cookie'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
WordPress 的登录 Cookie 已经是 HttpOnly。确保后台只能通过 HTTPS 访问,这样它们也会带上 Secure:
define( 'FORCE_SSL_ADMIN', true );插件设置的 Cookie 取决于各个插件。如果某个 Cookie 缺少属性,请检查是否有更新,或使用下面的服务器端兜底方案。
nginx(作为反向代理)
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"如果 Cookie 来自经过代理的后端(例如位于 ProxyPass 之后的 PHP-FPM),而设置后没有任何变化,请改用 Header always edit。
不要弄坏功能
- 你自己的 JavaScript 必须读取的 Cookie(某些同意横幅、A/B 测试)不能设为 HttpOnly。
- 在第三方 iframe 中使用的 Cookie 需要
SameSite=None,并且必须同时设置Secure。 SameSite=Strict可能会让用户从邮件链接进入时处于未登录状态。Lax是更稳妥的默认值。
常见问题
分析类 Cookie 需要这些属性吗?
在 HTTPS 网站上需要 Secure。只有在没有脚本需要读取时才设 HttpOnly,而分析类 Cookie 很少满足这一点。
SameSite=Lax 足以防范 CSRF 吗?
它能阻止大多数跨站表单提交,但会修改数据的表单仍应使用 CSRF 令牌。
为什么修复后扫描器仍报告缺少属性?
通常是页面缓存或 CDN 仍在返回旧的响应,或者某个插件设置了自己的 Cookie。清除缓存后再检查 Set-Cookie 行。