03/19

Recently, I am learning Web security issues. Cross-Site Request Forgery (CSRF) forges users behaviors to utilize stored Cookies to act as the users or steal information.

The same-origin-policies (SOPs) is a mechanism enforced by browsers to protect their users. However, I find that it is hard to get a clear English description of SOPs behaviors as well as what SOPs can give and what it cannot give. After struggling couples of hours on this mechanism, I am trying to put my understand here to request for comments or corrections.

Scope: Script-Initiated Requests

SOPs is only enforced on the requests initiated by client-side scripts. Therefore, those CSRFs initiated by resource references, such as loading an "image" or an iframe will not be enforced on this rule. That is also the reason why we can reference arbitrary images from arbitrary external websites on our websites.

Browser: Enforcement after Requesting

For each script-initiated request, the browser will request to the server. However, before delivering the response back to the initiator, the browser will check if this request violates the same-origin policies. If it violates, the browser will not deliver back the information to the script. Note that the request is actually made by the browser to the server.

Why browsers cannot stop those requests before sending them out? Because we may also want to allow someone to do such kind of script-initiated requests (for example, at client-side API calls), which is called as cross-origin resource sharing (CORS). When a server responds the request, it includes headers like Access-Control-Allow-Origin to tell browsers which origins the server allows. This information can only be retrieved after making such request. That's why browsers have to request the "suspicious" requests.

SOPs: Avoid Information Leakage

So, what is protected then? When I first time got this formal name of CSRF, I was very anxious about someone making HTTP requests on my behalf. However, now we see that the browser does not stop this.

Well, the browser is actually protecting us from information leakage. Whether the request is initiated by a resource reference or by a script without a correct response due to browser's SOPs, the malicious script does not get any information from the other website. So, it is defending us from utilizing the Cookies stored in the browser to do unauthorized access.

Server: Origin Headers and CSRF Tokens

So, what can protect us from making unauthorized requests? As a part of the CORS standard, all state-modifying requests (POST/DELETE methods...) should include a Origin header for the server. The server then can determine if it should execute the request with its accepted origin lists on the server-side.

However, in the real Internet, state-modifying happens also in GET requests. The standard does not require browsers to send Origin header to the server, so the server needs a way to protect itself. There are multiple options, such as adding CAPTCHA or checking Referrer. Unfortunately, none of them solves the problem without changing the user behaviors.

SOPs + CSRF Tokens: Avoid Unauthorized Requests

CSRF Tokens solves this issue by creating in a preliminary page a token which won't be stored in the browser. A malicious script cannot get any information from the victim website due to SOPs, so it cannot get the token by requesting the preliminary page. Therefore, it cannot pass the CSRF token checking on the server-side.

Now, we see that the browser protects users in their privacy aspects, while the server protects users from unauthorized request.

Remark: I am sure that there should be inaccuracy or mistakes, as CSRF is not my expertise. Please correct me if there is anything wrong.