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

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

如果下列情况属实,Web 服务是否容易受到 CSRF 攻击?

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

  2. 任何内容类型不同于 application/jsonPOST请求都将被400拒绝。例如,内容类型为 application/x-www-form-urlencodedPOST请求将因此被拒绝。

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

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

附带问题: PUTDELETE请求是否容易受到 CSRF 的攻击?我这样问是因为看起来大部分(所有?)浏览器不允许在 HTML 表单中使用这些方法。

编辑: 添加项目 # 4。

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

39827 次浏览

Is a web service vulnerable to CSRF attack if the following are true?

Yes. It's still HTTP.

Are PUT and DELETE requests ever vulnerable to CSRF?

Yes

it seems that most (all?) browsers disallow these methods in HTML forms

Do you think that a browser is the only way to make an HTTP request?

Forging arbitrary CSRF requests with arbitrary media types is effectively only possible with XHR, because a form’s method is limited to GET and POST and a form’s POST message body is also limited to the three formats ABC0, ABC1, and text/plain. However, with the form data encoding text/plain it is still possible to forge requests containing valid JSON data.

So the only threat comes from XHR-based CSRF attacks. And those will only be successful if they are from the same origin, so basically from your own site somehow (e. g. XSS). Be careful not to mistake disabling CORS (i.e. not setting Access-Control-Allow-Origin: *) as a protection. CORS simply prevents clients from reading the response. The whole request is still sent and processed by the server.

I have some doubts concerning point 3. Although it can be considered safe as it does not alter the data on the server side, the data can still be read, and the risk is that they can be stolen.

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

It is possible to do CSRF on JSON based Restful services using Ajax. I tested this on an application (using both Chrome and Firefox). You have to change the contentType to text/plain and the dataType to JSON in order to avaoid a preflight request. Then you can send the request, but in order to send sessiondata, you need to set the withCredentials flag in your ajax request. I discuss this in more detail here (references are included):

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

Yes, it is possible. You can setup an attacker server which will send back a 307 redirect to the target server to the victim machine. You need to use flash to send the POST instead of using Form.

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

It also works on Chrome.