指南 · 约 3 分钟阅读

Secure、HttpOnly 和 SameSite:修复 Cookie 属性

简短回答:会话和登录 Cookie 应设置 Secure(只通过 HTTPS 发送)、HttpOnly(JavaScript 无法读取,可限制 XSS 造成的损害)以及 SameSite=Lax 或 Strict(大多数跨站请求中不会发送,有助于防范 CSRF)。在创建 Cookie 的地方设置这些属性,或在 Web 服务器上添加作为兜底。

更新于 · HackGrade

代码和配置保持英文。

查看你的网站发送了什么

Terminal
curl -sI https://yourdomain.com | grep -i '^set-cookie'

PHP 会话

php.ini
session.cookie_secure = 1
session.cookie_httponly = 1
session.cookie_samesite = "Lax"
PHP 7.3+
setcookie('name', $value, [
    'expires'  => time() + 3600,
    'path'     => '/',
    'secure'   => true,
    'httponly' => true,
    'samesite' => 'Lax',
]);

WordPress

WordPress 的登录 Cookie 已经是 HttpOnly。确保后台只能通过 HTTPS 访问,这样它们也会带上 Secure:

wp-config.php
define( 'FORCE_SSL_ADMIN', true );

插件设置的 Cookie 取决于各个插件。如果某个 Cookie 缺少属性,请检查是否有更新,或使用下面的服务器端兜底方案。

nginx(作为反向代理)

nginx 1.19.3+
proxy_cookie_flags ~ secure httponly samesite=lax;

Apache

Apache mod_headers
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 行。

参考资料

相关指南

免费 · 即时 · 无需注册

抢在别人之前了解你的评级。

被动扫描。未经你的许可,不会进行任何攻击性检测。

免费开始。付费套餐每月 12 美元起,或 29 美元购买单次报告。 查看价格