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

Posted

技术标签:

【中文标题】JSON Web 服务是不是容易受到 CSRF 攻击?【英文标题】:Are JSON web services vulnerable to CSRF attacks?JSON Web 服务是否容易受到 CSRF 攻击? 【发布时间】:2012-06-16 00:46:40 【问题描述】:

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

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

    任何没有*** JSON 对象的 POST 请求,例如,"foo":"bar",都将被 400 拒绝。例如,内容为 42POST 请求将因此被拒绝.

    任何内容类型不是application/jsonPOST 请求都将被拒绝并返回400。例如,内容类型为application/x-www-form-urlencodedPOST 请求将因此被拒绝。

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

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

辅助问题:PUTDELETE 请求是否容易受到 CSRF 的攻击?我问是因为似乎大多数(所有?)浏览器都不允许在 html 表单中使用这些方法。

编辑:添加项目 #4。

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

【问题讨论】:

通过会话和cookie配对值标记您的请求,清理您通过提交的JSON触发的任何指令,添加盐以增加风味 我认为这里没有足够的信息来提供一个好的答案。您使用什么身份验证方法?谁是 Web 服务的预期消费者(即,与您的服务在同一主机上的站点的用户?) 您当前的所有验证都是完全合理的,并且确实限制了您的攻击面,但它们实际上并没有解决与 CSRF 漏洞有关的任何问题。 见security.stackexchange.com/questions/10227/csrf-with-json-post @DavidBalažic 什么载体?如果您在谈论 AJAX,同源策略会阻止这种情况发生。 【参考方案1】:

只有使用 XHR 才能有效地伪造具有任意媒体类型的任意 CSRF 请求,因为 form’s method is limited to GET and POST 和 form’s POST message body is also limited to the three formats application/x-www-form-urlencoded, multipart/form-data, and text/plain。但是,with the form data encoding text/plain it is still possible to forge requests containing valid JSON data。

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

【讨论】:

正如我评论您的链接答案时,我断言如果服务器不需要 application/json,则 text/plain 确实可以用于 JSON 伪造,使用类似于 pentestmonkey.net/blog/csrf-xml-post-request 的技术。跨度> 这个答案直到今天都是正确的,但很快就会出错。 W3C 正在考虑将 enctype="application/json" 添加到 HTML 标准中:darobin.github.io/formic/specs/json 所以不要依赖 POST 正文的类型来获得持久的安全性,使用反 CSRF 令牌。 @LordOfThePigs 已经可以使用 text/plain 伪造有效的 JSON。 @Gumbo 正确,但您目前无法将 enctype 设置为 application/json,这在此答案中用于阻止 CSRF 攻击。提议的标准将允许您将 enctype 设置为 application/json,这将破坏答案中概述的内容类型检查并将应用程序开放给 CSRF。 草案似乎先发制人了这次攻击。第 5 节规定 application/json 表单帖子必须符合同源策略,这意味着攻击不比 XHR 更强。【参考方案2】:

是的,这是可能的。您可以设置一个攻击者服务器,它将向目标服务器发送回一个 307 重定向到受害机器。您需要使用 flash 发送 POST 而不是使用 Form。

参考:https://bugzilla.mozilla.org/show_bug.cgi?id=1436241

它也适用于 Chrome。

【讨论】:

【参考方案3】:

可以使用 Ajax 在基于 JSON 的 Restful 服务上执行 CSRF。我在一个应用程序上测试了这个(同时使用 Chrome 和 Firefox)。 您必须将 contentType 更改为 text/plain 并将 dataType 更改为 JSON 以避免预检请求。然后你可以发送请求,但是为了发送 sessiondata,你需要在你的 ajax 请求中设置 withCredentials 标志。 我在这里更详细地讨论这个(包括参考):

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

【讨论】:

那是不必要的。如果服务器将明文请求读取为 JSON,则编码为明文的表单足以伪造此类请求,正如 Gumbo 所提到的。 API 服务器应该简单地拒绝明文请求。【参考方案4】:

我对第3点有一些疑问。虽然它不会改变服务器端的数据,可以认为是安全的,但数据仍然可以读取,并且存在被盗的风险。

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

【讨论】:

仅当 API 返回的***对象是 JSON 数组时才有效,因为 javascript 允许覆盖 Array 构造函数。***对象是安全的。更多信息请访问flask.pocoo.org/docs/0.10/security/#json-security。 根据作者自己的说法,“我认为任何现代浏览器都没有这个缺陷了”。【参考方案5】:

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

是的。它仍然是 HTTP。

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

是的

似乎大多数(所有?)浏览器都不允许在 HTML 表单中使用这些方法

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

【讨论】:

服务使用 HTTP 不会使其易受 CSRF 攻击。你能确定一个实际的 CSRF 攻击向量,如上所述,该服务易受攻击吗?当然,我不认为浏览器是发出 HTTP 请求的唯一方法,但浏览器是最常见的(仅?)用户被欺骗发出他们没有的伪造的跨站点请求期待。 换句话说,向我展示一个特定的 CSRF 攻击向量,它使用 PUT 诱骗用户向我的 Web 服务提交 PUT 请求(如所述)。我相信这是不可能的。 @symcbean:您能否发布参考资料或以其他方式捍卫您的答案?我没有对这个答案投票,我希望你先插话。谢谢。 谷歌又倒闭了吗?撇开内容类型不谈,旧版本的 Flash(更新版本的 Flash 具有跨域控制模型 - 但它与 HTML5 不同) - jar 走私怎么样 - pseudo-flaw.net/content/web-browsers/corrupted-jars(Java 在活动上下文中执行,但可以调用 javascript在被动语境中)。然后是 DNS 重新绑定攻击和 MITM 攻击 浏览器插件可以读取您的 CSRF cookie 并发送他们想要的任何标头,因此即使是事实上的标准 CSRF 强制机制也容易受到恶意浏览器插件的攻击。

以上是关于JSON Web 服务是不是容易受到 CSRF 攻击?的主要内容,如果未能解决你的问题,请参考以下文章

json.loads() 是不是容易受到任意代码执行的影响?

Unity Web 游戏是不是容易受到跨站点脚本的影响

利用Window.Opener绕过CSRF保护

在浏览器中存储令牌

漏洞通报|WebSphere Application Server容易受到XML外部实体(XXE)注入漏洞

什么是CSRF 攻击