I understand that Rails by default doesn't have CSRF
protection for HTTP GET
requests, because, it claims they are idempotent. However, there is sensitive information that is returned to the user from these GET requests, and, I would't want a malicious site retrieving this information.
What is the best way to protect HTTP GET
requests from CSRF
in Rails?
Briefly, Cross-Site Request Forgery (CSRF) is an attack that allows a malicious user to spoof legitimate requests to your server, masquerading as an authenticated user. Rails protects against this kind of attack by generating unique tokens and validating their authenticity with each submission.
When a CSRF token is generated, it should be stored server-side within the user's session data. When a subsequent request is received that requires validation, the server-side application should verify that the request includes a token which matches the value that was stored in the user's session.
Rails CSRF Token The server generates these tokens, links them to the user session, and stores them in the database. This token is then injected into any form presented to the client as a hidden field. When the client correctly submits the form for validation, it passes the token back to the server.
In a successful CSRF attack, the attacker causes the victim user to carry out an action unintentionally. For example, this might be to change the email address on their account, to change their password, or to make a funds transfer.
To be able to read the response to a CSRF attack’s request, an attacker would need to get the victim to execute his JavaScript code. And in that case, the access would be restricted by some Same Origin Policy.
Assuming the attacking request is really cross origin, the Same Origin Policy for DOM forbids access via DOM (e. g. when embedded using iframe
) and the Cross-Origin Resource Sharing (CORS) regulates cross-origin requests via XMLHttpRequest as follows:
If the request is a simple cross-origin request, i. e. simple method with only simple header fields, then that request will be sent (this is similar to HTML-based CSRF). But accessing a simple cross-origin request’s response depends on whether the response allows resource sharing.
Other cross-origin requests require a so called preflight before the actual request is sent. That request is sent to check whether the server allows requests from the origin the preflight is sent from. And only if the preflight succeeds and the response to the actual request allows resource sharing, the response can be accessed.
So to conclude: Unless your server supports CORS and explicitly allows sharing with any other origin (i. e. Access-Control-Allow-Origin: *
), a CSRF response – if the request was allowed at all – won’t be readable by the attacking site.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With