阿里云主机折上折
  • 微信号
您当前的位置:网站首页 > Cookie 的安全配置(HttpOnly, Secure, SameSite)

Cookie 的安全配置(HttpOnly, Secure, SameSite)

作者:陈川 阅读数:33740人阅读 分类: 前端安全

HttpOnly 属性

HttpOnly 是 Cookie 的一个重要安全属性,用于防止跨站脚本攻击(XSS)窃取 Cookie。当设置 HttpOnly 为 true 时,JavaScript 无法通过 document.cookie 访问该 Cookie,只能由浏览器在 HTTP 请求中自动发送。

// 设置 HttpOnly Cookie 的示例(Node.js Express)
res.cookie('sessionID', 'abc123', {
  httpOnly: true,
  maxAge: 24 * 60 * 60 * 1000 // 1天有效期
});

实际应用场景:

  1. 会话标识符(Session ID)必须设置 HttpOnly
  2. 身份验证令牌(Authentication Token)应该启用此属性
  3. 敏感数据存储的 Cookie 都需要此保护

测试方法:

  • 在浏览器控制台输入 document.cookie,HttpOnly 的 Cookie 不会显示
  • 使用开发者工具的 Application 面板可以查看所有 Cookie 及其属性

Secure 属性

Secure 属性确保 Cookie 只通过 HTTPS 加密连接传输,防止中间人攻击窃取明文 Cookie。在 HTTP 站点上,浏览器会拒绝发送带有 Secure 属性的 Cookie。

// 同时设置 Secure 和 HttpOnly
res.cookie('userToken', 'xyz789', {
  secure: true,
  httpOnly: true,
  sameSite: 'strict'
});

部署注意事项:

  1. 生产环境必须启用 HTTPS
  2. 开发环境可能需要根据情况禁用 Secure 以便测试
  3. 混合内容(HTTPS 页面加载 HTTP 资源)可能导致 Secure Cookie 失效

常见问题解决:

  • 本地开发时 Chrome 对 localhost 的特殊处理
  • 代理服务器导致的协议不匹配问题
  • 证书无效导致的 Secure Cookie 被拒绝

SameSite 属性

SameSite 控制 Cookie 的跨站发送行为,是防御 CSRF 攻击的重要机制。有三个可选值:

  • Strict:完全禁止第三方上下文发送
  • Lax:允许部分安全请求(如导航跳转)发送
  • None:允许跨站发送(必须同时设置 Secure)
// 不同 SameSite 策略的示例
res.cookie('preferences', 'dark_mode', {
  sameSite: 'lax',
  httpOnly: false // 允许前端 JavaScript 访问
});

res.cookie('csrfToken', 'qwerty', {
  sameSite: 'strict',
  httpOnly: true
});

浏览器兼容性处理:

  • Chrome 80+ 默认将没有 SameSite 的 Cookie 视为 Lax
  • 需要支持旧版浏览器时应显式设置 SameSite=None; Secure
  • iOS 12 等系统存在已知的实现差异

组合安全策略

最佳实践是将三个属性组合使用:

// 高安全要求的 Cookie 配置
res.cookie('auth', 'jwt_token', {
  httpOnly: true,
  secure: true,
  sameSite: 'strict',
  path: '/api',
  domain: 'example.com',
  maxAge: 3600000
});

特殊场景处理:

  1. 跨域单点登录(SSO)需要 SameSite=None
  2. 内嵌 iframe 的业务场景要考虑 Cookie 访问策略
  3. 移动端 WebView 可能需要额外配置

实际部署案例

电商网站 Cookie 配置示例:

// 用户会话 Cookie
res.cookie('session', encryptedSession, {
  httpOnly: true,
  secure: true,
  sameSite: 'lax',
  path: '/'
});

// CSRF 防护 Token
res.cookie('XSRF-TOKEN', randomToken, {
  secure: true,
  sameSite: 'strict',
  path: '/checkout'
});

// 第三方支付回调需要的 Cookie
res.cookie('payment_callback', callbackId, {
  secure: true,
  sameSite: 'none',
  httpOnly: true
});

调试技巧:

  1. 使用 Chrome 的 Application 面板查看 Cookie 实际生效属性
  2. 通过 curl -I 检查 Set-Cookie 响应头
  3. 网络抓包验证 Cookie 传输情况

Cookie 安全与隐私法规

GDPR 和 CCPA 等法规对 Cookie 使用的要求:

  1. 必须明确告知用户 Cookie 用途
  2. 非必要 Cookie 需要用户同意
  3. 提供 Cookie 管理选项

合规配置示例:

// 仅当用户同意时设置分析 Cookie
if (userConsent.analytics) {
  res.cookie('_ga', trackingId, {
    sameSite: 'lax',
    secure: true,
    maxAge: 63072000 // 2年
  });
}

常见漏洞模式

  1. 敏感 Cookie 未设置 HttpOnly 导致 XSS 窃取:
// 错误示例:身份验证 Cookie 可被 JavaScript 访问
res.cookie('auth_token', token, { httpOnly: false });
  1. SameSite 配置不当引发 CSRF:
// 危险:允许跨站发送且未使用 Secure
res.cookie('user_prefs', prefs, { sameSite: 'none' });
  1. 过长的过期时间增加安全风险:
// 不推荐:会话 Cookie 有效期过长
res.cookie('session', sessionId, { 
  maxAge: 365 * 24 * 60 * 60 * 1000 // 1年
});

服务器端配置示例

Nginx 设置安全 Cookie:

location / {
  add_header Set-Cookie "sessionid=12345; Path=/; HttpOnly; Secure; SameSite=Lax";
  proxy_pass http://backend;
}

Apache 配置示例:

Header always edit Set-Cookie ^(.*)$ "$1; HttpOnly; Secure; SameSite=Strict"

客户端检测方法

JavaScript 检测 Cookie 安全性:

function checkCookieSecurity(name) {
  const cookies = document.cookie.split(';');
  const target = cookies.find(c => c.trim().startsWith(`${name}=`));
  
  if (!target) return 'Not Found';
  
  const secure = /;\s*Secure/i.test(target);
  const httpOnly = !document.cookie.includes(name);
  const sameSite = target.match(/;\s*SameSite=(\w+)/i);
  
  return {
    secure,
    httpOnly,
    sameSite: sameSite ? sameSite[1] : 'Not Set'
  };
}

浏览器兼容性矩阵

浏览器版本 HttpOnly 支持 Secure 强制要求 SameSite 默认值
Chrome 80+ 完全支持 是(SameSite=None时) Lax
Firefox 79+ 完全支持 Lax
Safari 13+ 完全支持 Strict
Edge 85+ 完全支持 Lax
iOS 13+ 完全支持 部分支持 Lax

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

前端川

前端川,陈川的代码茶馆🍵,专治各种不服的Bug退散符💻,日常贩卖秃头警告级的开发心得🛠️,附赠一行代码笑十年的摸鱼宝典🐟,偶尔掉落咖啡杯里泡开的像素级浪漫☕。‌