1

I have a JSON API built for a SPA which accepts only requests with "Accept: application/json" header. So submitting the following form in the browser will cause "Not Acceptable." HTTP error.

<form method="POST" action="https://api.example.domain/resource">
    <input type="password" name="password" value="CSRF">
    <input type="submit" value="Click!">
</form>

Is it means that the API has an immune to CSRF types of attack or am I missing something?

tooleks
  • 557
  • 5
  • 17

2 Answers2

3

It should be quite secure, but still, there's a chance that the API is vulnerable.

If an attacker could find an XSS vulnerability in the website he could be able to add the header: Accept: application/json using JavaScript and then perform the CSRF attack.

For that reason, the recommendable is to rely on some headers that can't be set by JavaScript because they are on the 'forbidden' headers list, only browsers can modify them so no XSS vulnerability can be used in here.

You will find more information in OWASP: https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet

Jorge Cabrera
  • 331
  • 5
  • 16
  • 1
    Hi Jorge, thanks for a beautiful article you've shared. So, if the REST API will set the `Access-Control-Allow-Origin: https://domain.name` header into each response should I also check `Origin` and `Referer` headers or it will be enough? – tooleks Aug 26 '17 at 20:53
  • Seems enough to me. However, the best way to proceed when adding security to your web applications is to follow OWASP guidelines. Even if you think it is already secure enough you could be missing something. So, I would recommend you to still use `Origin` or `Referer` header and even the Synchronizer Tokens – Jorge Cabrera Aug 27 '17 at 16:59
1

I don't think it will be secure because you can't implement all the prevention methods at a time. Of course adding the CORS support, HTTP Only flags and other methods might prevent you from getting hacked but you are not completely safe.

Instead of re-inventing the wheel by implementing all the prevention methods, I think its better to use an existing standard wrapper or middleware to prevent CSRF attacks on your application. These piece of codes sanitizes the input a lot more better than you can do.

You can use one of the best (my favorite wrapper), https://github.com/ring-clojure/ring-anti-forgery to prevent the CSRF attacks. If you are using node for your backend purposes here is another best middleware, https://github.com/expressjs/csurf .

I won't say its impossible to code whole thing by yourself to prevent CSRF attacks, but I think its smart way to use the existing standard pieces of code and focus on developing the functionalities will save a hell lot more of time.

Rewanth Tammana
  • 1,453
  • 17
  • 20
  • Hi Rewanth, thanks for your answer. The main issue with it that the frontend application is an absolutely separate application, so I can't use this solution (the CSRF token hidden field injection by the backend) because the backend does not render the frontend HTML it only provides the REST API. – tooleks Aug 27 '17 at 12:20