CSRF 攻击是不是适用于 API?
Posted
技术标签:
【中文标题】CSRF 攻击是不是适用于 API?【英文标题】:Do CSRF attacks apply to API's?CSRF 攻击是否适用于 API? 【发布时间】:2012-05-31 06:20:37 【问题描述】:我正在编写一个 Django RESTful API 来支持 ios 应用程序,并且每当我编写处理 POST 请求的方法时,我都会遇到 Django 的 CSRF 保护。
我的理解是 iOS 管理的 cookie 不会被应用程序共享,这意味着我的会话 cookie 是安全的,没有其他应用程序可以使用它们。这是真的?如果是这样,我可以将我的所有 API 函数都标记为 CSRF-exempt 吗?
【问题讨论】:
【参考方案1】:这不是 CSRF 保护的目的。 CSRF 保护是为了防止将数据直接发布到您的站点。换句话说,客户端实际上必须通过批准的路径发布,即查看表单页面,填写它,提交数据。
API 几乎排除了 CSRF,因为它的全部目的通常是允许第 3 方实体访问和操作您网站上的数据(CSRF 中的“跨站点”)。所以,是的,我认为通常任何 API 视图都应该是 CSRF 豁免的。但是,您应该仍然遵循最佳实践并保护每个通过某种形式的身份验证(例如 OAuth)实际进行更改的 API 端点。
【讨论】:
用户注册呢?这是我的大事,因为我现在写它的方式,没有 CSRF 和(显然)没有登录,没有什么可以阻止有人用虚假注册淹没我的服务。 简单。你不允许。据我所知,没有任何 API 可以让您真正使用 API 创建帐户。您通过他们的网站创建帐户,然后使用 API 密钥对您的请求进行身份验证。 那么 Twitter et al.支持通过原生 iOS 视图注册?我的直觉告诉我这是一个 API 调用,但出于安全原因,我认为情况并非如此。 这不是真的。 CSRF 攻击依赖于存储为 cookie 的当前经过身份验证的会话令牌,因此浏览器将在向站点发布数据时重用此会话令牌。仅仅因为您的 API 暴露给第三方并不意味着您不想对其进行身份验证,因此您至少应该在基于会话令牌进行身份验证时验证 CSRF 令牌。 为防止用户向注册发送垃圾邮件,您可能需要使用验证码,或让用户验证他们的电话号码。【参考方案2】:如果您还使用自己的 API 来支持网站,它们确实适用。
在这种情况下,您仍然需要某种形式的 CSRF 保护,以防止有人在其他网站中嵌入请求,从而对经过身份验证的用户帐户产生偷渡效应。
Chrome 似乎默认拒绝跨域 POST 请求(其他浏览器可能不那么严格),但允许跨域 GET 请求,因此您必须确保 API 中的任何 GET 请求没有副作用。
【讨论】:
您可以通过使用javascript提交表单来进行跨域发布。 @NickRetallack 幸运的是,没有任何表单可以发布带有任何自定义标头的跨域。因此,只需为 POST 提供一个自定义标头即可。【参考方案3】:CSRF 攻击依赖于将所有请求隐式发送到特定域的 cookie。如果您的 API 端点不允许基于 cookie 的身份验证,那么您应该很好。
即使您使用基于 cookie 的身份验证,您的 cookie 也是安全的,因为 iOS apps do not share cookies。但是,除非您通过要求不寻常的用户代理标头故意阻止 Web 浏览器,否则另一方可能会构建使用您的 API 的基于浏览器的应用程序,如果您的 API 支持基于 cookie 的身份验证并且不支持,那么该应用程序将容易受到 CSRF 攻击'不应用 CSRF 保护。
【讨论】:
【参考方案4】:这个当前接受的答案(2012 年 5 月)大部分是正确的,除非您使用基于会话的身份验证。还值得一提的是CORS的作用。
简单的场景是您访问foo.com
,网站执行JavaScript 向api.com/users/123
发出基于AJAX 的DELETE 请求,最终代表您删除用户。现在这并不总是可能的,因为 CORS —— 浏览器将阻止 foo.com
向 api.com
发出请求,除非 api.com
明确将 foo.com
列入白名单。
这还假设您为 API 使用 基于会话的身份验证,而不是 基于令牌的身份验证。在基于会话的身份验证中,任何登录到 api.com
的用户都可以在保持登录状态时执行请求。如果您有基于令牌的身份验证(每个请求必须使用包含身份验证令牌的 HTTP Authorization
标头制作)那么你就安全了。基于会话的身份验证通过 cookie 隐式发送身份验证令牌。
更糟糕的情况是,如果您的一个受信任的 CORS 域遭到入侵 - 假设您有一个不清理 JavaScript 的表单,并且用户设法通过该表单将 JS 注入您的站点。如果您使用基于会话的身份验证,则访问该页面的经过身份验证的用户将看到 JavaScript 运行并发出 API 请求。如果您对 API 使用基于会话的身份验证,这可能是灾难性的并且非常有可能。
【讨论】:
【参考方案5】:根据DRF documentation,,只要服务器使用经过身份验证的会话(而不是每次都询问密码),API 就容易受到 CSRF 攻击
解决办法是
-
确保“安全”HTTP 操作,例如
GET
、HEAD
和
OPTIONS
不能用于更改任何服务器端状态。
确保任何“不安全”的 HTTP 操作(例如 POST
、PUT
、PATCH
和 DELETE
)始终需要有效的 CSRF 令牌。
【讨论】:
API 客户端(即移动应用、Ajax 调用)如何提供有效的 CSRF 令牌? @HassanTareq CSRF token 可以在登录客户端时收到django-rest-framework.org/topics/api-clients/… 如果您知道,相同的标题名称“X-CSRFToken”是否适用于 (C#) RestSharp 和 (Java) Retrofit?以上是关于CSRF 攻击是不是适用于 API?的主要内容,如果未能解决你的问题,请参考以下文章