快速说明:这与具有自定义标头(并且没有验证令牌)的CSRF保护不是重复的,尽管有些重叠。那篇文章讨论了如何在Rest端点上执行CSRF保护,而不讨论是否确实必要。确实,我在该站点上阅读的许多CSRF / Rest问题都涉及通过CSRF令牌保护端点,而没有实际讨论是否有必要。因此存在这个问题。

Rest API端点是否需要CSRF保护?可以肯定的是,我非常确定REST端点上的CSRF令牌会给予零附加保护。因此,在REST端点上启用CSRF保护只会向您的应用程序引入一些无用的代码,我认为应该跳过这些代码。我可能会丢失一些东西,因此这个问题出现了。我认为这将有助于记住为什么首先需要CSRF保护以及它所针对的攻击媒介的原因:

为什么CSRF?使浏览器能够通过发送cookie来自动显示任何请求的登录凭据。如果会话ID存储在cookie中,浏览器将自动将其与所有返回原始网站的请求一起发送。这意味着攻击者实际上不必知道身份验证详细信息即可采取行动作为受害者用户。相反,攻击者只需诱使受害者浏览器发出请求,身份验证请求的凭据将免费使用。

输入REST API

其余的API端点与其他请求有一个非常重要的区别:它们是无状态的,绝不接受/使用cookie或会话中的数据。结果,遵循标准的REST API会自动免受此类攻击。即使浏览器发送了cookie,与cookie关联的所有凭据也将被完全忽略。 REST API调用的身份验证以完全不同的方式完成。最常见的解决方案是具有某种身份验证密钥(OAuth令牌等),该身份验证密钥随标头一起发送,或者可能在请求主体本身中发送。 ,并且由于浏览器本身不知道身份验证令牌是什么,因此即使有人被诱骗访问API端点,浏览器也无法自动提供身份验证证书。结果,无cookie的REST端点完全不受CSRF攻击。

还是我缺少了什么?

评论

某些REST API限制了每个ip的调用,这可能是实现csrf保护有意义的边缘情况。

感谢您输入@ Xavier59。您是否需要澄清:为什么速率限制需要CSRF保护?

因此,我不确定这是否一定适用于您的情况,但是假设您使用google作为oauth提供程序。您的用户登录到某些恶意网站,该网站也使用google作为oauth提供程序。恶意网站可能会为您的网站使用用户的令牌(ish,取决于客户端设置等)。详情请参阅:spring.io/blog/2011/11/30/cross-site-request-forgery-and-oauth2

@ConorMancone如果站点A的REST API将每个ip的调用限制为1 /秒,则攻击者可能会欺骗Bob进入攻击者站点B,后者每秒发送数十个请求。这可能会导致Bob的ip被该REST API禁止,或者阻止他正确使用REST API。我同意这有点牵强,但并非完全不可能。

@ Xavier59这在某种程度上等同于尝试通过在高流量网站上获取带有该网站作为其源属性的img标签来对网站进行DDoS。它不一定牵强。话虽这么说,我不明白为什么CSRF令牌会做任何事情来减轻这种攻击。

#1 楼

我原本的目标不是自我回答,但经过更多阅读后,我想出了一个我认为是全面的答案,这也解释了为什么有些人可能仍然对REST端点上的CSRF保护感兴趣。

没有cookie =没有CSRF

就这么简单。浏览器发送cookie和所有请求。 CSRF攻击取决于此行为。如果您不使用Cookie,并且不依赖Cookie进行身份验证,那么绝对没有CSRF攻击的空间,也没有理由进行CSRF保护。如果您有cookie,尤其是将它们用于身份验证,则需要CSRF保护。如果您仅想知道“我的API端点需要CSRF保护吗?”您可以在这里停下来并留下答案。否则,细节将摆在魔鬼面前。

对paj28的提示:虽然cookie是CSRF攻击的主要攻击媒介,但是如果您使用HTTP /基本身份验证,则也容易受到攻击。更一般而言,如果浏览器能够自动传递应用程序的登录凭据,则CSRF很重要。以我的经验,cookie是用于使CSRF发生的最常用技术,但是使用其他一些身份验证方法也可能导致相同的漏洞。

REST =无状态

如果您问某人“什么是REST”,您将获得讨论各种不同属性的各种答案。您可以看到很多,因为有人在堆栈溢出时问了这个问题:https://stackoverflow.com/questions/671118/what-exactly-is-restful-programming

我一直依赖的REST的一个特性是它是无状态的。应用程序本身具有状态。如果您无法将数据存储在某个地方的数据库中,则您的应用程序将受到很大限制。但是,在这种情况下,无状态具有非常具体且重要的意义:REST应用程序不会跟踪客户端应用程序的状态。如果您正在使用会话,那么(几乎可以肯定)您正在跟踪客户端状态,并且您不是REST完整的应用程序。因此,使用通过cookie跟踪的会话(特别是用于登录)的应用程序不是REST-full应用程序(IMO),并且即使看起来像REST应用程序,也肯定容易受到CSRF攻击。

我认为值得一提的是,客户端无状态对于REST应用程序很重要的一个原因是,中间人缓存响应的能力也是REST范式的理想组成部分。只要应用程序正在跟踪客户端状态,就无法进行缓存。永远不需要会话,不需要Cookie,因此永远不需要CSRF安全性。但是,至少有一个用例仍然喜欢使用cookie:持久登录。

考虑一个典型的客户端(在这种情况下为浏览器,而不是移动设备)Web应用程序。从登录开始,登录使用REST API来验证用户凭据,作为回报,将获得一个令牌来授权将来的请求。对于单页应用程序,您可以只将该令牌保留在内存中,但是这样做会在用户关闭页面时有效地注销用户。因此,最好将状态保存在比单个浏览器会话持续时间更长的地方。本地存储是一种选择,但也容易受到XSS攻击:成功的XSS攻击可能导致攻击者获取您的登录令牌并将其发送给攻击者,以供其自行决定。因此,我看到一些建议使用Cookie来存储登录令牌。使用cookie可以设置仅http标志,这将阻止应用程序在设置cookie后读取它。结果,在发生XSS攻击时,攻击者仍可以代表您拨打电话,但他们无法一起摆脱授权令牌。 Cookie的这种使用不会直接违反REST的无状态要求,因为服务器仍未跟踪客户端状态。我只是在cookie中而不是在标题中查找身份验证凭据。应用程序来平衡各种安全性和可用性问题。我个人会尝试避免将cookie与REST API一起使用,但是很可能仍然有理由使用它们。无论哪种方式,总的答案都很简单:如果您使用Cookie(或浏览器可以自动执行的其他身份验证方法),则需要CSRF保护。如果您不使用Cookie,那么您就不会使用。

评论


您几乎可以找到。 HTTP基本身份验证和基于IP的身份验证等可能会受到CSRF的攻击。相反,如果Cookie仅是使用该服务的定制客户端而不是浏览器,则它可能是安全的。那可能不会影响您的决定,但值得牢记。我发现人们试图将什么是“适当的REST”定义为IT领域建设性最低的讨论之一。实际上,大多数服务都需要身份验证,而会话是进行身份验证的合理方法。

–paj28
17年8月7日在17:48

谢谢@ paj28。 HTTP基本认证值得一提。我认为这不那么常见(这就是为什么我忘记提及它的原因),但是当您尝试提出一个全面的答案时,最好提及例外。

– Conor Mancone
17年8月7日在17:59

我没有得到您的第三点,如果我将令牌存储在会话cookie中,是否还需要csrf保护?

– Rathma
17年12月20日在8:47

一个小小的澄清:“没有cookie =没有CSRF”-我也这样认为,但是在Kerberos / NTLM本机浏览器支持(SPNEGO)下,一个kerberos令牌被发送到一组列入白名单的域。这些案例还应具有CSRF保护,因为它在本质上与cookie相同,即“某些内容会根据请求自动发送内容”,因此我认为如果您提交的表单的目标是使用Kerberos的API端点内部网络,这里也存在CSRF风险,不是吗?

–伊朗棉兰
19年7月16日在22:28

另一个关于“没有cookie =没有CSRF”的问题-如果您将会话令牌存储在URL中(不好的主意,但是确实发生了),那么就很容易像欺骗cookie中的会话令牌一样诱骗用户提交表单。这将需要事先了解令牌(浏览器历史记录/代理日志/服务器日志),这是一个障碍,但在某些情况下可行。非常具体的情况,但我认为值得一提。

–adamczi
20 Mar 16 '20在9:42

#2 楼


“浏览器无法自动提供身份验证凭据,即使通过某种方式被诱骗访问了API端点也是如此”


使用集成的Windows / Kerberos身份验证的专用网络上要小心。在这种情况下,如果配置为这样做,浏览器将自动提供凭据(kerberos或NTLM令牌)。

评论


是的owasp.org/index.php/Top_10_2007-Cross_Site_Request_Forgery“仅基于自动提交的凭据对请求进行授权,例如,如果当前登录到应用程序,则为会话cookie;如果未登录到应用程序,则为“记住我”功能,或者使用Kerberos如果Intranet的一部分参与与Active Directory的集成登录,则存在令牌。”

–伊朗棉兰
19年7月16日在22:39

#3 楼

是否需要CSRF保护取决于两个因素:-

请求是否在执行状态更改操作(与REST API无状态性不同)-状态更改操作是将更改以下内容的任何操作应用程序的状态..例如删除某物,添加某物,更新某物。这些是应用程序将用来更改用户支持状态的操作。所有“发帖”请求和一些“获取”请求将属于此类别。 REST API可以更改状态。

浏览器是否提供了身份验证(不限于cookie)-CSRF之所以发生,是因为浏览器在请求中包含了身份验证信息,而不管请求是否由请求者启动。用户或其他打开的标签页。因此,浏览器可以自行包含信息的任何身份验证都需要CSRF保护。这包括基于cookie的会话和基本身份验证。

对于属于以上2类的所有请求,都需要CSRF保护。

#4 楼

我要在其他答案中添加的一件事是,仅在所涉及的Cookie的域和路径中才需要CSRF保护。或换一种说法:

授权!=身份验证
Cookies ==身份验证
令牌==授权

这与持久性登录的实现有关(您的第3点)。如果您将cookie附加到login.example.com(托管登录UI和/authorize端点),则可以每隔几分钟运行一次隐式OAuth流,而无需重新登录(例如,没有密码对话框)。客户端可以继续将获取的访问令牌发送给api.example.com,而无需CSRF,因为不会将cookie发送到该主机。但是您的登录/身份验证服务器最好是防弹的(并受CSRF保护)。

#5 楼


Rest API终结点与其他请求有一个非常重要的区别:它们特别是无状态的,绝不接受/使用cookie或会话中的数据。


如果这是定义“ REST API”的方式,则不可能使用CSRF。 CSRF,也称为“会议骑马” [citation],如果没有要“骑马”的会议,显然将不起作用。

评论


如果您不同意我的部分陈述,我将很高兴听到。 IMO,无状态是REST API的主要目标。会话肯定会使API状态化。 Cookies ...从技术上讲,我想您可以使用Cookies而不是在状态服务器端进行存储,这取决于您如何使用它们。

– Conor Mancone
17年8月3日在20:44

好吧,我宁愿回答这个问题,也不愿争论术语。但是HATEOS中的S和REST中的S都代表状态。只要客户端状态不保留在服务器上,我认为您就不会“违反” REST方法的精神。

–吴宗宪
17年8月7日在16:13

我绝对同意你的看法。我不是想争论术语。问题的一部分是我对最初的问题还不够清楚:我专门谈论的是客户端状态,而不是应用程序状态。

– Conor Mancone
17年8月7日在17:40

是的,国家转移,这是重点。状态未存储在服务器端。客户端将其状态告知服务器。只有通过常规Web浏览器访问api时,CSRF才有意义。当今的浏览器甚至不支持某些HTTP方法(例如DELETE,PUT / PATCH),这使得该API仅可用于独立的HTTP客户端。

–Sebi2020
18/09/13在1:54



#6 楼

答:如果将令牌存储在localStorage中,并使用JS将其附加到您的请求中,它将自动保证CSRF保护(根据攻击的性质)

附录:
使用仅HTTP的cookie而不是localStorage更为安全(在XSS的情况下,使用CSRF保护的方式似乎会产生问题):实际上并非如此。对于通过漏洞利用XSS来控制您网站上JS的攻击者来说,这只会变得更加困难。 br />
XSS是应用程序级别的漏洞,但可以通过使用声明限制令牌的功能(将其限制在最低限度内)来减轻其影响

评论


欢迎。作为问答站点,我们不同于讨论站点。答案需要单独作为问题的答案,而不是对其他答案的评论。

– schroeder♦
20-2-7在10:01

@schroeder谢谢。长期潜伏在第一次的海报上,最初我想发表评论,但那需要最低的声誉。但是,该注释导致我在最后一句中对OP问题提出了最初的答案:“我应该使用csrf保护吗” =>如果令牌存储并由JS附加到标头,则否

–雷维尔
20-2-7在10:08

我只能说:继续为网站做出贡献,以获得足够的声望,以释放发表评论的能力。您已迈出“潜伏”的第一步。继续 :)

– schroeder♦
20-2-7在10:09

我建议您删除对其他答案的评论,并确保该答案直接解决了问题。

– schroeder♦
20-2-7在10:12

可以,但是我认为这很重要,因为这可以使一切有所不同(推理导致答案)。我将澄清结论

–雷维尔
20-2-7在10:14



#7 楼

我想补充一些对现有答案的特定警告。尽管Conor认为Cookie是沿着所有请求发送的本地存储身份验证数据的唯一形式是正确的,但它们并不是网站使用的本地存储身份验证数据的唯一形式。这意味着,如果站点决定将其JWT /会话令牌保留在LocalStorage或SessionStorage之类的内容中,则有时仍可以通过javascript自动将其删除,然后在无需用户交互的情况下使用它们。这意味着有时仍然可以通过将用户重定向到与域匹配的前端URI(然后发送凭据)来“一旦删除”来执行CSRF攻击。如果您已经反映了XSS,则可以通过更直接的方式来完成此操作,但是在某些情况下,这是不必要的,并且这些页面和脚本已经存在。 REST API;无论前端与之交互的端点上都没有令牌。

评论


哇,太和气了!如此琐碎,如果可以以某种方式将JS注入目标站点,则任何会话都可能被盗。

–peterh-恢复莫妮卡
20年8月13日在6:31

@ peterh-ReinstateMonica很可爱,但是正如我在帖子中所说,这不是我的意思。前端位于其余API的前面并不少见,这些终结点在加载时已经执行了可变操作,而无需您向其中注入代码,这并不罕见。

–迪恩·瓦伦丁
20年8月13日在7:02