CSRF 攻击适用于 API 吗?

我正在编写一个 Django RESTful API 来支持一个 iOS 应用程序,每当我编写处理 POST 请求的方法时,都会遇到 Django 的 CSRF 保护。

我的理解是,iOS 管理的 cookie 不会被应用程序共享,这意味着我的会话 cookie 是安全的,没有其他应用程序可以使用它们。这是真的吗?如果是这样,我可以将所有 API 函数标记为 CSRF 豁免吗?

34288 次浏览

这不是 CSRF 保护的目的。CSRF 保护是为了防止直接张贴数据到您的网站。换句话说,客户端实际上必须通过一个批准的 路径发布,也就是说,查看表单页面,填写表单,提交数据。

API 很大程度上排除了 CSRF,因为它的全部用途通常是 允许第三方实体访问和操作站点上的数据(CSRF 中的“交叉站点”)。所以,是的,我认为任何 API 视图都应该被 CSRF 豁免。但是,您的 应该仍然遵循最佳实践并保护每个通过某种形式的身份验证(如 OAuth)实际进行更改的 API 端点。

如果你也使用你的 API 来支持一个网站,它们确实适用。

在这种情况下,您仍然需要某种形式的 CSRF 保护,以防止有人将请求嵌入其他站点,从而对经过身份验证的用户的帐户产生驱动效应。

Chrome 似乎默认拒绝跨源的 POST 请求(其他浏览器可能没有这么严格) ,但允许 GET 请求跨源,所以你必须确保你的 API 中的任何 GET 请求没有副作用。

CSRF 攻击依赖于将 cookie 与所有请求一起隐式发送到特定域。如果您的 API 端点不允许基于 Cookie 的身份验证,那么您应该没有问题。

即使您使用基于 Cookie 的身份验证,您的 Cookie 也是安全的,因为 IOS 应用程序不共享 cookie。然而,除非你故意要求一个不寻常的用户代理头来阻止浏览器,否则另一方可以建立一个使用你的 API 的基于浏览器的应用程序,如果你的 API 支持基于 cookie 的认证并且不应用 CSRF 保护,那么这个应用程序将很容易受到 CSRF 攻击。

这个目前被接受的答案(2012年5月)大部分是正确的,除了在使用基于会话的身份验证时。同样值得一提的是 CORS的作用。

简单的场景是,您访问 foo.com,网站执行 JavaScript 向 api.com/users/123发出基于 AJAX 的 DELETE 请求,并最终以您的名义删除用户。现在这并不总是可能的,因为 CORS-浏览器会阻止 foo.comapi.com发出请求,除非 api.com显式地将 foo.com列入白名单。

这还假设您在 API 中使用的是 基于会话的身份验证,而不是 基于令牌的认证。在基于会话的身份验证中,任何登录到 api.com的用户都可以在请求保持登录状态时执行请求。如果您具有基于令牌的身份验证(每个请求必须使用包含 auth 令牌的 HTTPAuthorization标头进行创建) ,那么您是安全的。基于会话的身份验证通过 cookie 隐式发送身份验证令牌。

一个稍微糟糕一点的场景是,如果您信任的 CORS 域之一被破坏了——比如您有一个表单没有清理 JavaScript,而一个用户设法通过该表单将 JS 注入到您的站点中。如果使用基于会话的身份验证,那么访问该页面的经过身份验证的用户将看到运行 JavaScript 并发出 API 请求。如果对 API 使用基于会话的身份验证,那么这可能是灾难性的,而且非常有可能发生。

根据 DRF 文档, API,只要服务器使用经过身份验证的会话(而不是每次询问密码) ,就容易受到 CSRF 攻击

解决办法就是

  1. 确保“安全”的 HTTP 操作,如 GETHEADOPTIONS不能用于更改任何服务器端状态。
  2. 确保任何“不安全”的 HTTP 操作(如 POSTPUTPATCHDELETE)始终需要有效的 CSRF 令牌。