Cross-Site Request Forgery (CSRF) is a type of attack that occurs when a malicious Web site, email, blog, instant message, or program causes a user’s Web browser to perform an unwanted action on a trusted site for which the user is currently authenticated.
Key concepts of Cross-Site Request Forgery
- Malicious requests are sent from a site that a user visits to another site that the attacker believes the victim is validated against.
- The malicious requests are routed to the target site via the victim’s browser, which is authenticated against the target site.
- The vulnerability lies in the affected web application, not the victim’s browser or the site hosting the CSRF.
Preventing Cross-Site Request Forgery (CSRF) vulnerabilities
The most common method to prevent Cross-Site Request Forgery (CSRF) attacks is to append unpredictable challenge tokens to each request and associate them with the user’s session. Such tokens should at a minimum be unique per user session, but can also be unique per request. By including a challenge token with each request, the developer can ensure that the request is valid and not coming from a source other than the user.
The classic solution to CSRF has been a per-session token (known as the synchronizer token design pattern).
The basic flow using this solution is:
Step 1. When the user logs in, a randomized string (token) is then placed in the user session
Step 2. On every form for a non-idempotent request (essentially meaning any request that changes the server-side state – which should be your HTTP POSTs), the token is placed in the form when it is submitted
Step 3. The request handler for the non-idempotent request validates that the submitted token matches the token stored in the session. If either of the tokens is missing, or if they do notmatch, do not process the transaction
To use the Synchronizer Token Pattern. This solution is to ensure that each request requires, in addition to our session cookie, a randomly generated token as an HTTP parameter. When a request is submitted, the server must look up the expected value for the parameter and compare it against the actual value in the request. If the values do not match, the request should fail.