What is CSRF?
A cross site request forgery (CSRF) attack occurs when a web browser is tricked into executing an unwanted action in an application that a user is logged in.
1 GET http://bank-zyz.com/transfer?from=UserA&to=UserB&amt=100 HTTP/1.1
Then a malicious actor can embed a request with similar signatures inside an innocent looking hyperlink.
1 <a href="http://bank-xyz.com/transfer?from=UserA&to=MaliciousActor&amt=10000 HTTP/1.1></a>
If User A clicks on the hyperlink, the web browser sends the request together with the session cookie. The funds are then unintentionally transferred out of User A’s account.
When the same-origin-policy does not help with CSRF
The same-origin policy prevents a page from accessing results of cross domain requests. It prevents a malicious website from accessing another website’s resources such as static files and cookies.
Even though the policy prevents cross-origin of resources, it does not prevent the requests from being sent.
In the Bank XYZ example, a
GET request with relevant cookies triggers the server to transfer the funds before returning the 200 OK response. As shown in the diagram below, the same-origin policy only prevents the access of resouces, which in this case is reading the HTTP response. Since the request (with cookies) can still be sent, the hyperlink can still trigger the transfer of funds.
Image by Author - The policy would only prevent a cross-origin access of HTTP response (Step 3)
Note: For more complex HTTP requests, a preflight
OPTIONS request is sent beforehand to check for relevant CORS headers. In that scenario, an unexpected cross-origin request will not reach Bank XYZ’s website at all.
How the same-origin-policy actually mitigates CSRF
To prevent CSRF, Bank XYZ can generate an unpredictable token for each client which is validated in the subsequent requests. For example, a hidden HTML field can allow the token to be included in subsequent form submissions.
1 <input type="hidden" name="csrf-token" value="CIwNZNlR4XbisJF39I8yWnWX9wX4WFoz" />
Other websites running in User A’s browser do not have to the form field due to the same-origin-policy. So malicious scripts from other origins can no longer make the same request to transfer funds.