With an increasing number of breaches, intrusions, and data thefts, securing a web application is extremely important.

On the other hand, programmers often do not have a strong grasp of how attacks work and how to mitigate them. This post attempts to close that gap a little.

CSRF

Cross-Site Request Forgery is an attack where a third party forces a user to execute actions against a site where they are currently logged in.

Here is an example illustrating how this works:

  1. You visit evil.com
  2. evil.com has a hidden form that submits on page load to mybank.com/transfer-funds. Since you are logged in to mybank.com, this request is made with your mybank.com cookies and will silently initiate a money transfer out of your account.
  3. Since 'evil.com' and 'mybank.com' are different origins, the browser refuses to provide the response to evil.com (because of CORS), but the attacker doesn't care, the money's already been transferred.

Now if mybank.com implements CSRF protection correctly:

  1. Each time mybank.com serves a form to a user, it generates a CSRF token and inserts it into a hidden field in the form
  2. If a POST request is received, it checks the CSRF token against its database - if this is present and valid then the request goes through. If the CSRF token is missing or incorrect it is rejected.

CSRF attacks target state-changing requests and not the direct theft of data because the attacker does not see the response of the forged request. The CSRF token provides security by being a stateless token that is never stored in the cookies or permanent storage - doing so would defeat the purpose of the token.

CSRF protection support needs to be added to your application code and cannot be added at the proxy server layer (eg. in Nginx). A detailed look at CSRF from OWASP

It is good practice to always use the SameSite directive with cookies as this provides protection against CSRF attacks.

CORS

Cross-Origin Request Sharing only applies in a browser context and is a security mechanism to allow one origin to make a request to another origin. All browsers follow the Single Origin Policy, meaning by default scripts cannot make requests to other origins - but if the server provides properly configured CORS headers this policy can be selectively relaxed. Thus CORS is a way of selectively loosening security and not of tightening it.

When a website makes an XHR request to another origin, the browser initiates a preflight OPTIONS request first - and the original request is only made if the server responds to this preflight with a list of allowed origins, and this list contains the origin of the current page.

Note that CORS preflight requests are not made for GET HEAD POST requests with default headers.

Some key headers sent as a response to an OPTIONS request: