JSON Web服务是否容易受到CSRF攻击?


80

我正在构建一个仅将JSON用于其请求和响应内容的Web服务(即,没有表单编码的有效负载)。

如果满足以下条件,Web服务是否容易受到CSRF攻击?

  1. POST没有顶级JSON对象(例如)的任何请求{"foo":"bar"}都将被400拒绝。例如,POST带有内容的请求42将因此被拒绝。

  2. POST内容类型以外的任何请求application/json都将被400拒绝。例如,POST内容类型的请求application/x-www-form-urlencoded将因此被拒绝。

  3. 所有GET请求都是Safe,因此不会修改任何服务器端数据。

  4. 客户端通过会话cookie进行身份验证,在客户端通过POST使用JSON数据(例如)提供正确的用户名/密码对后,Web服务会为客户端提供会话cookie {"username":"user@example.com", "password":"my password"}

补充问题:是PUTDELETE要求日益容易受到CSRF?我问是因为大多数(全部?)浏览器似乎都不允许以HTML形式使用这些方法。

编辑:添加了项目#4。

编辑:到目前为止,很多好评论和答案,但是没有人提供此Web服务容易受到的特定CSRF攻击。


通过会话和Cookie配对值对请求进行标记,对通过提交的JSON触发的任何指令进行消毒,添加盐以增加风味
Brandt Solovij 2012年

我认为这里没有足够的信息来提供良好的答案。您使用哪种身份验证方法?谁是Web服务的预期使用者(即,与您的服务位于同一主机上的网站的用户?)
McGarnagle 2012年

1
您当前的所有验证都非常明智,并且确实限制了您的攻击面,但是它们实际上并没有解决与CSRF漏洞有关的任何问题。
Cheekysoft 2012年


2
@DavidBalažic什么向量?如果您在谈论AJAX,则同源策略将阻止这种情况。
djsmith

Answers:


73

锻造任意介质类型任意CSRF请求实际上是唯一可能与XHR,因为窗体的方法仅限于GET和POST形式的POST邮件正文也只限于三种格式application/x-www-form-urlencodedmultipart/form-datatext/plain。但是,使用表单数据编码text/plain,仍然可以伪造包含有效JSON数据的请求

因此,唯一的威胁来自基于XHR的CSRF攻击。而且只有当它们来自相同的来源时,它们才会成功,因此基本上是从您自己的站点(例如XSS)获得的。注意不要误将禁用CORS(即不设置Access-Control-Allow-Origin:*)作为保护。CORS只是阻止客户读取响应。整个请求仍由服务器发送和处理。


9
正如我在您的链接答案中评论的那样,我断言,如果服务器不需要application / json,则可以使用类似于pentestmonkey.net/blog/csrf-xml-post-request的技术将text / plain用于JSON伪造。

8
直到今天,这个答案都是正确的,但很快就会错了。W3C正在考虑将enctype =“ application / json”添加到HTML标准中:darobin.github.io/formic/specs/json 因此,为了持久的安全性,请不要依赖POST正文的类型,请使用反CSRF令牌。
LordOfThePigs 2014年

@LordOfThePigs使用text / plain已经可以伪造有效的JSON 。
Gumbo 2014年

@Gumbo是正确的,但是您目前无法application/json在此答案中设置用于阻止CSRF攻击的enctype 。提议的标准将允许您将enctype设置为application/json,这将使答案中概述的内容类型检查无效,并向CSRF打开应用程序。
LordOfThePigs 2014年

9
草案似乎抢先了这一攻击。第5节指定application/json表单发布必须遵循相同的原始策略,这意味着攻击不比XHR强。
James_pic


1

可以使用Ajax对基于JSON的Restful服务进行CSRF。我在应用程序(使用Chrome和Firefox)上对此进行了测试。您必须将contentType更改为text / plain,将dataType更改为JSON才能使用预检请求。然后,您可以发送请求,但是为了发送会话数据,需要在ajax请求中设置withCredentials标志。我在这里对此进行了更详细的讨论(包括参考文献):

http://wsecblog.blogspot.be/2016/03/csrf-with-json-post-via-ajax.html


那是没有必要的。如果服务器将纯文本请求作为JSON读取,则编码为纯文本的形式足以伪造该请求,如Gumbo所提到的。API服务器应仅拒绝纯文本请求。
富兰克林于

-1

关于第3点,我有一些疑问。尽管由于它不会更改服务器端的数据而被认为是安全的,但仍然可以读取数据,并且存在被窃取的风险。

http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx/


1
仅当API返回的顶级对象是JSON数组时,此方法才有效,因为Javascript允许覆盖Array构造函数。顶级对象是安全的。有关更多信息,请访问flask.pocoo.org/docs/0.10/security/#json-security
btubbs 2015年

根据作者本人的说法,“我认为任何现代浏览器都不再具有此缺陷”。
富兰克林于

-6

如果满足以下条件,Web服务是否容易受到CSRF攻击?

是。仍然是HTTP。

PUT和DELETE请求是否容易受到CSRF的攻击?

似乎大多数(所有?)浏览器都不允许HTML形式的这些方法

您是否认为浏览器是发出HTTP请求的唯一方法?


3
仅仅因为服务使用HTTP并不会使它容易受到CSRF的攻击。您能否确定该服务容易受到攻击的实际CSRF攻击媒介?当然,我不认为浏览器是发出HTTP请求的唯一方法,而是浏览器是最常见的(唯一?)用户被欺骗而提出的伪造,跨站点请求,他们没有期望。
djsmith 2012年

换句话说,向我展示一个特定的CSRF攻击媒介,该媒介使用PUT诱骗用户向我的Web服务提交PUT请求(如上所述)。我相信这是不可能的。
djsmith 2012年

@symcbean:您能发表参考文献还是以其他方式捍卫您的答案?我尚未对此答案进行投票,我想请您先输入提示音。谢谢。
dotancohen

Google再次失败了吗?撇开内容类型的东西,旧版本的Flash(较新的Flash版本具有跨域控制模型-但它与HTML5不同)-罐子走私如何-pseudo-flaw.net/content/web-browsers/corrupted -jars(Java在主动上下文中执行,但可以在被动上下文中调用javascript)。然后是DNS重新绑定攻击和MITM攻击
symcbean 2013年

浏览器插件可以读取您的CSRF Coo​​kie并发送所需的任何标头,因此,即使事实上的标准CSRF强制机制也容易受到恶意浏览器插件的攻击。
djsmith 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.