CSRF 保护如何为我提供比 CORS 控制更高的安全性(前端/后端位于两个不同的域)?

Posted

技术标签:

【中文标题】CSRF 保护如何为我提供比 CORS 控制更高的安全性(前端/后端位于两个不同的域)?【英文标题】:How does CSRF protection give me greater security than CORS control with front-end/back-end being on two different domains? 【发布时间】:2015-06-03 17:44:33 【问题描述】:

如果我有:

一个域上的 Web 前端。 另一个域上的 REST API。 通过将标头 Access-Control-Allow-Origin 设置为 Web 前端域,将 REST API 服务器配置为仅允许来自 Web 前端域的跨源请求。

除了需要跳过更多的障碍之外,CSRF 还提供了哪些额外的安全性?如果不先将他们的代码注入 Web 前端,攻击者就无法 POST 到我的后端,对吧?

On this question,克里斯普拉特说,"[...]So, yes, I think as a rule any API view should be CSRF exempt.[...]"。这个概念有效吗?它是否包括我的拓扑?

在我的配置中,正确配置了 CORS,我是否需要使用 Cookie 来装饰来自 Web 前端的 GETPOSTPUTDELETE 请求 数据元素 CSRF 令牌?

: 开明的人可能会将此问题视为重复问题,但我已阅读this, this, this, this, this, this, 和this, 我仍然需要一些帮助。请帮助我进一步充实这个想法。

【问题讨论】:

服务器端的 REST API 会拒绝不正确的 CORS 请求吗?如果没有,您仍然容易受到 CSRF 的攻击。 我正在使用django-corsheaders。我相信当有无效的 CORS 标头时它会拒绝,但我不确定。 你可以自己测试一下:做一个简单的GET或者POST,请求中不应该包含任何CORS头,看看会不会被拒绝。 嗯。我使用了mitmdump,它看起来确实只在客户端强制执行。 Django + Django Rest Framework 正在愉快地发送数据。因此,如果我的用户使用的是"old" 浏览器,那么他们将很容易受到攻击,除非我以某种方式更改服务器配置。 CSRF 旨在触发服务器端操作和/或读取它们的响应。至少对于前者来说,用户的浏览器是否支持 CORS 并不重要。 【参考方案1】:

在从域加载的页面的上下文中,CORS 仅控制浏览器是否可以读取来自另一个域的 XHR 响应。它不控制浏览器可以向哪些域发出请求。也就是说,CORS 将针对您的标头设置的任何 Origins 放宽 Same Origin Policy - 但同源策略中的任何内容都没有说明不能首先发出请求。

其他域仍然可以 GET 和 POST 到您的域,只是除非 CORS 允许,否则您的站点生成的任何响应都无法在客户端脚本中读取。 The actual GET and POST is still received by your server and processed.

因此,您仍然需要 CSRF 预防 - 即使对于使用符合 CORS 的浏览器的用户也是如此。

【讨论】:

谢谢 SilverlightFox。你的措辞终于让我明白了。我确信这只是我的密度,但我很欣赏这个解释。【参考方案2】:

在 CSRF 攻击中,攻击者的网站使用您浏览器中仍然有效的身份验证 cookie 发布到网站或 API。

如果您将 CORS 设置为仅允许来自您的站点的请求,则请求将失败,因为任何现代浏览器都会添加一个表示攻击者站点的原始标头。

但这取决于您的所有用户都使用符合 CORS 的浏览器这一事实。由于 CORS 仍然很新,所以我不会假设。如果使用 cookie 进行身份验证,我建议将 CSRF 保护添加到您的 API。

但更好的解决方案是不要将您的 API 建立在 cookie 身份验证上,而是使用不易受到 CSRF 攻击的基于令牌的安全性。

【讨论】:

cookie/session vs token 的关键在于 Web 客户端前端真的很像普通网站。唯一的区别是前端和后端被分成两个域。用户正在通过登录表单向后端提交凭据,就像任何其他登录网站一样。 所以您的用户进行了两次身份验证?一个用于前端,一次用于 API?这有点不合常规。 没有。在 API 上进行身份验证就是身份验证。前端向后端发出 AJAX 请求进行身份验证,并将该身份验证用作前端和 API 身份验证。

以上是关于CSRF 保护如何为我提供比 CORS 控制更高的安全性(前端/后端位于两个不同的域)?的主要内容,如果未能解决你的问题,请参考以下文章

如何为新的应用获取更高的关键字排名

如何为Kafka集群选择合适的Partitions数量

如何为Kafka集群选择合适的Partitions数量

CSRF 保护 - JWT 和 CORS 白名单组合是不是足够?

CORS 如何为用户提供至少一些安全性?

如何为 AWS API Gateway 自定义授权方配置 CORS?