对于仅使用 JSON 的后端 REST 应用程序,CSRF 是强制性的吗?

Posted

技术标签:

【中文标题】对于仅使用 JSON 的后端 REST 应用程序,CSRF 是强制性的吗?【英文标题】:Is CSRF mandatory for a backend REST application consuming JSON only? 【发布时间】:2016-03-05 21:24:43 【问题描述】:

许多资源声称 (source1) (source2)

对于 RESTful Web 服务公开的资源,确保任何 PUT、POST 和 DELETE 请求都受到保护以防止跨站点请求伪造非常重要。

CSRF 对所有应用程序都是强制性的,对网络安全的担忧最少

但是the Spring Security docs说:

对普通用户可以通过浏览器处理的任何请求使用 CSRF 保护。如果您只创建一个非浏览器客户端使用的服务,您可能希望禁用 CSRF 保护

那么,是否可以为应用程序禁用 CSRF?

只公开一个 REST API 仅使用 JSON(检查请求 Content-Type 标头)

【问题讨论】:

那么,应用程序是做什么的?如果它接受的 json 类似于"command":"nuke the universe",您可能需要对其进行保护,以确保隔壁的鼻涕虫小脚本小子无法发出该命令... 它不提供 html 并且只使用 JSON 的事实并不重要。重要的是:针对 REST 服务的请求是否应该来自浏览器客户端。 @JBNizet 它们来自在浏览器中运行的 javascript,但不是来自提交 HTML 表单,因为不可能提交内容类型为 application/json 的表单。 【参考方案1】:

这取决于您的 API 的客户端。 CSRF 攻击基于客户端在 HTTP 请求中自动发送请求 URL 的 cookie(授权)这一事实。如果你的客户端没有这样做(通常浏览器会自动这样做),你应该没问题。

原因是:如果您的 API 使用者未通过 cookie(由浏览器自动存储)在您的应用程序中进行身份验证/授权,则攻击者无法使用任何其他网页进行成功的 CSRF 攻击(从其他网页发送 HTTP 请求)带有来自浏览器的 API cookie 的页面)。

换句话说,我无法想象你会以这样的方式编写 API 客户端,它可以向你的 API 发送请求,存储 cookie(你的身份验证),还可以以某种方式向你展示一些“愚蠢”用户的内容交互 - 使用来自先前 API 请求的 cookie(您的身份验证)向您的 API 发送请求。

【讨论】:

嗯...在利用方面确实很重要。在浏览器中发送 application/json 请求的唯一方法是使用 Javascript,但是同源策略会阻止 JS 向不同来源的主机发出请求并切换到使用 CORS,CORS 向我的 REST 发出预检请求然后我的 REST 可以拒绝它。 你是说内容类型?好吧,部分但总的来说,我看不出如何在没有像浏览器一样的客户端的情况下成功进行 CSRF 攻击 - 换句话说,它存储 cookie(授权你)并且可以向你的 API 以及任何恶意网页(即重新获取 API 请求的 cookie) Cookies 不必参与 CSRF 攻击。我使用 HTTP Basic auth 登录 mybank.com(假设),我进入 evil.com 那里有
mybank.com/withdraw"> 并且我单击在 evil.com 上提交它仍然是 CSRF 攻击尽管没有涉及cookies。
我编写了 cookie(您的身份验证),HTTP 基本是标头的特殊情况,其工作方式与浏览器中的 cookie 类似(它被浏览器自动添加到 HTTP 请求中)... 阅读“在其他词”部分... 是的,但是如果您的 API 端点依赖于 cookie/或某种机制来重新建立会话,那么重要的是什么。如果您没有使用 cookie 并且使用了一些客户端无法轻松构建或浏览器无法自动发送的身份验证令牌,则不需要 csrf。因为没有机制可以用纯无状态的 rest API 识别旧会话,所以在这种情况下可以禁用 csrf【参考方案2】:

这很容易解释:

基于Http Session 生成一个 CSRF 令牌。如果您的 API 正在持有 http 会话,您希望使用 CSRF 令牌保护它,但是大多数 REST 服务被设计为无状态,在这种情况下,您不能/不应该/不会使用一个 CSRF 令牌。

【讨论】:

不确定这是否正确。你想如何在没有浏览器(或自动发送 cookie 的客户端)的情况下攻击类似 API(例如使用承载令牌)的 HTTP 会话? BUT most REST services are designed to be stateless 这不是真的,大多数时候我们需要 http 会话来确定哪个用户发出请求,如果您的服务易受 CSRF 攻击,攻击者可以代替真实用户发出请求(通常发生在浏览器端) Rest API 应该是无状态的,并且每个请求都会发送会话识别加密的 jwt 令牌以重新建立它。在这种情况下,不需要 csrf,因为攻击者无法利用自动的用户代理发送会话识别信息。如果您的其余 API 设置了任何与会话相关的 cookie,可以帮助应用程序将其与会话相关联,那么您需要 csrf,因为浏览器会自动发送 cookie。

以上是关于对于仅使用 JSON 的后端 REST 应用程序,CSRF 是强制性的吗?的主要内容,如果未能解决你的问题,请参考以下文章

通过 REST 与 Keycloak 保护的后端进行后端到后端通信

如何仅使用 Sails.js 的 REST API 作为混合 HTML5 应用程序的后端

使用 Django Rest Framework 构建的后端 Json 在前端以某种方式未定义,使用 React 构建

使用 Django Rest Framework 自定义 JSON 回调

我是否需要为SPA保护仅支持GET的REST API

如何保护仅服务于我的前端的自己的后端 API?