4

I have REST APIs which are behind a webserver, then there is a custom single page application frontend hosted on it (React). It goes like that:

  1. The user logs to the index page, if the session cookie is not present they gets redirected towards the login page
  2. The user logs and gets redirected to the index: all the requests will have this session cookie
  3. The custom frontend sends, along to every request, some custom header, say "X-FRONTEND: <app name>"
  4. The webserver will block each request not having the session cookie
  5. The APIs will block each request not having neither the cookie and the (fixed) header
  6. The server has CORS configurations so that accepts only requests coming from the same domain

I tried hypothesizing a couple of scenarios:

  • GET call hidden in a page. It will get blocked as the requests will not have the custom header
  • GET/<other method> call with the custom header hidden in page. It will get blocked as requires CORS to be performed as you'll go in JavaScript

What do you think about it?

1
  • I've always thought of CORS as a hack that browser vendors had to implement because web devs refuse to check the Referer header. You might consider checking that, too. Feb 26 at 20:35
3
+50

Any request that is made cross origin, cannot set a non-standard header. Unless you allow it using Cross-Origin Resource Sharing. This technique only works for javascript requests, not for requests that for example come from submitting a form. For the javascript case this technique is recommended by OWASP in the Cross-Site Request Forgery Prevention Cheat Sheet.

However, one issue that might come into play:
If there is any action that is immediately executed on your page through javascript when you visit it: This action will be executed when the user opens a link to your page.
As this action is executed on your page, the context is not cross-origin and the javascript call will add the header you defined. So make sure something like this does not happen.

2

all the requests will have this session cookie

The webserver will block each request not having the session cookie

Given the above, are you able to set SameSite=Strict on this cookie? If so, I believe you should be protected from CSRF altogether. No need for the custom header.

There is more info about SameSite in the link below. Hopefully it will be helpful.

https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-02#section-5.3.7.1

2
  • 2
    SameSite is new enough that some peoples' browsers still don't support it. Setting "strict" also is very inconvenient for linking into the site, as the user will always initially appear to not be logged in.
    – CBHacking
    Feb 27 at 1:46
  • 1
    Yes, it has some drawbacks. If OP can't use Strict or doesn't want to, the RFC I linked also contains some info on how to use Lax instead alongside some other defense-in-depth techniques.
    – jsaigle
    Feb 27 at 4:39
2

The method you are using is perfectly fine until or unless there is an XSS. But if there is an XSS the CSRF attack is immaterial. The proposed CSRF protection of validating a custom header and cookie is a known technique of Double submit cookie.

Django has a similar implementation as documented here CSRF Protection

The hypothesis you have mentioned where a GET request will be blocked, I couldn't find a reason for mentioning a GET request on behalf of CSRF.In REST APIs, the POST method is frequently used to create resources while the GET method is frequently used to request a representation of a resource. Normally a CSRF takes place where a state change is implemented for example deleting a post or creating a post. And these requests are supposed to be executed using a POST request and it should be done using a POST method. If you want to render a page CSRF attack cannot do harm to the webapp.

The second point again the GET/<anymethod>. As mentioned above CSRF is done where a state-changing function is present. Not at an endpoint where a normal GET request is done. But if the application is designed to transfer data using only GET request ( Not a secure practice )as mentioned in OWASP there is a chance for a CSRF. A valid hackerone report exploiting a deep link in android is a good example.

And if an attack is done using a custom header this will trigger an OPTIONS pre-flight request which in turn will prevent the CSRF in your situation since you have a CORS configuration to accept requests from the same domain.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.