元标记中带有令牌的 CSRF 保护 - 为啥不能被盗?

Posted

技术标签:

【中文标题】元标记中带有令牌的 CSRF 保护 - 为啥不能被盗?【英文标题】:CSRF Protection with tokens in meta tag - why can't it be stolen?元标记中带有令牌的 CSRF 保护 - 为什么不能被盗? 【发布时间】:2015-05-08 07:20:11 【问题描述】:

在 ajax 调用中包含 csrf 预防令牌的建议是将它们作为元标记包含在您的页面中,然后可以访问并包含在标题中。 http://docs.spring.io/spring-security/site/docs/3.2.0.CI-SNAPSHOT/reference/html/csrf.html

这怎么不能被利用?例如,如果 example.com 在元标记中包含 csrf 令牌,我是否可以不只是创建一个恶意站点,其中包含一些将调用 example.com 的 javascript,然后解析响应,找到元标记,然后将令牌值注入我的恶意页面表单?

【问题讨论】:

【参考方案1】:

由于 http://en.wikipedia.org/wiki/Same-origin_policy ,在爱丽丝的浏览器中运行的脚本chuck.com 无法读取 carol.com 的内容。

chuck.com 上的脚本可以 POST 到 carol.com,但无法读取和解析其内容。

【讨论】:

【参考方案2】:

CSRF 令牌对于每个会话都是唯一的。生成后,它只能使用一次,与特定会话相关联。

恶意的人可能会生成一个,但它是特定于他们的浏览器会话的。简而言之,他们只会利用它来利用自己。

至于通过 JavaScript 产生攻击,这确实是一个与 CSRF 不同的问题。 CSRF 是一种类似this one from Wikipedia 的攻击:

<img src="http://bank.example.com/withdraw?account=Alice&amount=1000000&for=Mallory"/>

防止恶意 JavaScript 是另一回事。站点通过清理用户输入、iframe 沙盒和依赖 same-origin policy 来保护自己免受 XSS 和其他类型的 JavaScript 注入。

TL;DR

如果您在自己的网站上运行其他人不受信任的 JavaScript,那么您遇到的问题比 CSRF 更大。

【讨论】:

我认为 csrf 令牌在每个会话中都是唯一的,所以会话中的每个请求都会具有相同的令牌?对于经常返回浏览器的最终用户来说,轮换令牌并不是很友好。 There seems to be some debate 关于 CSRF 令牌应该多久刷新一次,但我倾向于同意每个会话/登录一次应该没问题。不过,我在问题中掩盖了您的攻击向量-为了清楚起见,我已经更新了我的答案,并希望现在这是一个可以接受的答案。

以上是关于元标记中带有令牌的 CSRF 保护 - 为啥不能被盗?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Spring Boot 在 html 元标记中获取 csrf 令牌

将 csrf 令牌存储在元标记中是一种好习惯吗?

当 POST 是唯一方法时,如何使用 jQuery 从标头中检索 csrf 令牌?

一个令牌与多个令牌以防止 CSRF 攻击

将 csrf 令牌传递给 Stripe

HTTP层 —— CSRF保护