【问题标题】:CSRF protection with CORS Origin header vs. CSRF token使用 CORS Origin 标头与 CSRF 令牌的 CSRF 保护
【发布时间】:2014-09-01 01:12:28
【问题描述】:

这个问题仅是关于防止跨站请求伪造攻击。

具体是关于:通过 Origin 标头 (CORS) 进行的保护是否与通过 CSRF 令牌进行的保护一样好?

例子:

所以:

  • 如果我们不检查 Origin 标头(服务器端),并且没有 CSRF 令牌,我们就有一个 CSRF 安全漏洞。
  • 如果我们检查一个 CSRF 令牌,我们是安全的(但它有点乏味)。
  • 如果我们确实检查了 Origin 标头,来自 evil.com 客户端代码的请求应该被阻止,就像使用 CSRF 令牌时一样 - 除非,如果 evil.com 的代码可以以某种方式设置来源标头。

我知道,如果我们相信 W3C 规范能够在所有现代浏览器中正确实现(我们可以吗?)

但是其他类型的请求呢?表格提交?正在加载 script/img/... 标签?或者页面可以用来(合法地)创建请求的任何其他方式?或者也许是一些已知的 JS hack?

注意:我不是在谈论

  • 本机应用程序,
  • 被操纵的浏览器,
  • example.com 页面中的跨站点脚本错误,
  • ...

【问题讨论】:

  • 我相信很多代理都会剥离原始标头。
  • 对于表单提交和 img/script 标签,我们应该依赖 CSP,但不确定旧浏览器。
  • @thefourtheye:由于连接是通过 TLS 启动的,因此如果代理可以在他/她的中间人,那么用户将面临比 CSRF 更紧迫的问题。
  • @thefourtheye,他们为什么要剥夺Origin?这将否定 CORS 保护。
  • 我喜欢这个问题及其答案,因为它们是关于特定事物的,但它们也让我想起了 CSRF 和 CORS 之间的区别。 (我承认这些是不容易混淆的概念......但我仍然设法混淆它们。)

标签: javascript security cors csrf


【解决方案1】:

知道,如果我们相信 W3C 规范能够在所有现代浏览器中正确实现(我们可以吗?)

p>

最终,您必须“信任”客户端浏览器才能安全地存储用户数据并保护会话的客户端。如果您不信任客户端浏览器,那么您应该停止将网络用于静态内容以外的任何内容。即使使用 CSRF 令牌,您也相信客户端浏览器会正确遵守 Same Origin Policy

虽然以前存在浏览器漏洞,例如 IE 5.5/6.0 中的漏洞,攻击者可以绕过同源策略并执行攻击,但您通常可以期望这些漏洞在发现后立即被修补,并且大多数浏览器自动更新,这种风险将大部分得到缓解。

但是其他类型的请求呢?表格提交?加载 script/img/... 标签?或者页面可以用来(合法地)创建请求的任何其他方式?或者也许是一些已知的 JS hack?

Origin 标头通常仅针对 XHR 跨域请求发送。图片请求不包含标头。

注意:我不是在说

  • 本机应用程序,

  • 被操纵的浏览器,

  • example.com 页面中的跨站点脚本错误,

我不确定这是否属于受操纵的浏览器,但old versions of Flash 允许设置任意标头,这将使攻击者能够从受害者的机器发送带有欺骗性referer 标头的请求,以便执行攻击。

【讨论】:

  • Flash 示例是一个很好的例子——也许其他插件也有类似的漏洞。如果 Alice 使用现代浏览器等,我只能(不幸地)保护 Alice 免受 CSRF 的影响,这很清楚。但是,即使作为具有安全意识的用户,她也可能安装了 3rd 方插件,尤其是当它们来自大型(值得信赖的)公司时,这并非不合理。即使他们可能会编写安全的插件,我也不是 100% 相信,如果他们也考虑 CSRF!因此,除非浏览器沙箱限制插件违反 SOP(可能吗?),否则我宁愿建议坚持使用 CSRF 令牌。
  • @ChrisLercher:是的,现代插件似乎更强大了。但是,随时可能发布新版本,允许攻击者以绕过浏览器保护的方式利用它。处理它的最佳方法(例如令牌/标头)将取决于您的数据的敏感性以及这种风险是否可以接受。 Flash 确实遵守 SOP,但 Flash 插件的来源是加载它的站点(而不是调用站点,如 JavaScript)。有一个crossdomain.xml可以实现跨域通信。
【解决方案2】:

Web 内容不能篡改 Origin 标头。此外,在同源策略下,一个源甚至无法将自定义标头发送到其他源。 [1]

因此,检查 Origin 标头在阻止攻击方面与使用 CSRF 令牌一样好。

依赖它的主要问题是它是否允许所有合法请求工作。提问者知道这个问题,并设置了问题排除了主要情况(没有旧浏览器,只有HTTPS)。

浏览器供应商遵循这些规则,但插件呢?他们可能不会,但这个问题无视“被操纵的浏览器”。浏览器中允许攻击者伪造 Origin 标头的错误怎么办?也可能存在允许 CSRF 令牌跨源泄漏的错误,因此需要更多的工作来证明一个比另一个更好。

【讨论】:

  • 我刚刚测试了 Firefox 47,它没有发送跨域表单帖子的原始标头(一种攻击 REST 服务的常见方法,它不为 XHR 启用 CORS),所以我如果用户使用的是 Firefox,则认为源头检查不会有效。
  • 作为参考,Bugzilla 跟踪了 Firefox 未发送“Origin”标头的问题:bugzilla.mozilla.org/show_bug.cgi?id=446344 在这种情况下,您可以回退到检查“Referer”标头,但根据我的经验,一些 Firefox 用户由于隐私问题而阻止“Referer”标头(尽管恕我直言,剥离路径和查询就足够了)。
【解决方案3】:

解释术语

我认为问题应该是同源策略 vs CSRF 令牌。因为 CORS 是一种允许两个不同域相互通信的机制(通过放宽同源策略),而 同源策略CSRF em> 令牌限制域相互通信。

GET 方法永远不会保存

所有浏览器都实现same-origin policy。此策略通常避免域 A 上的 Web 应用程序可以向域 B 上的应用程序发出 HTTP 请求。但是,它并不限制所有请求。例如同源策略not restrict embed tags 是这样的:

<img src="https://dashboard.example.com/post-message/hello">

响应是否为有效图像无关紧要 - 请求仍在执行。这就是为什么不能使用 GET 方法调用 Web 应用程序上的状态更改端点很重要的原因。

预检

您可以使用CORS 来避免同源策略,并让域 A 向域 B 发出否则会被禁止的请求。 在发送实际请求之前,将发送preflight request 以检查服务器是否允许域 A 发送此请求类型。如果是,域 A 将发送原始请求。

例如,如果没有设置 CORS,则预检将限制域 A 的 Javascript XMLHttpRequests,而不在域 B 上执行请求。

为什么你需要 CSRF 令牌,尽管有同源政策

如果同源策略适用于所有类型的请求,那么您是对的,不需要使用 CSRF 令牌,因为您将受到同源策略的全面保护。然而,这种情况并非如此。 有几个 HTTP 请求不发送预检请求!

具有特定标头和特定内容类型的 GET、HEAD 和 POST 请求不会发送预检请求。此类请求称为simple requests。这意味着请求将被执行,如果请求不被允许,那么将返回一个不允许的错误响应。但问题是,这个简单的请求是在服务器上执行的。

不幸的是,一个普通的&lt;form action="POST"&gt; 创建了一个简单的请求!

由于这些简单的请求,我们必须使用 CSRF 令牌保护 POST 路由(GET 路由不需要 CSRF,因为它们无论如何都可以被嵌入式标签读取,如上所示。只要确保你没有状态改变的get方法)。

【讨论】:

    猜你喜欢
    • 2013-07-20
    • 2014-01-23
    • 2016-05-19
    • 2017-03-19
    • 2011-09-07
    • 2014-06-24
    • 2014-05-01
    • 2019-05-11
    • 2012-11-04
    相关资源
    最近更新 更多