Understanding CSRF in depth
Provides an in-depth exploration of Cross-Site Request Forgery (CSRF) attacks, explaining their mechanics, demonstrating examples, and detailing various prevention methods to enhance web application security.
Provides an in-depth exploration of Cross-Site Request Forgery (CSRF) attacks, explaining their mechanics, demonstrating examples, and detailing various prevention methods to enhance web application security.
When working on web development, especially with cookies, we often hear phrases like "this setting helps prevent CSRF". However, many people only have a vague idea of what "CSRF" really means.
Today, we'll take a deep dive into CSRF (Cross-Site Request Forgery), a common web security flaw. This will help us handle CSRF-related issues more effectively.
CSRF (Cross-Site Request Forgery) is a type of web attack where attackers trick authenticated users into performing unintended actions. In simple terms, it's "hackers pretending to be users to carry out unauthorized actions".
To understand CSRF, we need to grasp a few key concepts:
The same-origin policy is a security feature in browsers that limits how a document or script from one origin can interact with resources from another origin.
An origin consists of a protocol (like HTTP or HTTPS), domain name, and port number. For example, https://example.com:443 is one origin, while https://demo.com:80 is another.
The same-origin policy restricts data access between pages from different origins, meaning:
However, to maintain the openness and interoperability of the Web (like loading resources from CDNs or sending requests to third-party APIs for logging), the same-origin policy doesn't restrict cross-origin network requests:
<script>, <img>, <link>, <iframe> tags)The automatic cookie sending mechanism is an important feature of browsers. When a browser sends a request to a domain, it automatically attaches all cookies for that domain. This process is automatic and doesn't require any JavaScript code or user interaction.
This mechanism allows websites to easily remember users' login status because each request automatically carries the user's identity information.
Bold
For example, when you log into a bank website (bank.com) and get an identity cookie, then when you click to view your statement, the browser automatically finds all cookies matching bank.com and attaches them to the statement request. The bank's server can then identify you from the backend and return your statement information.
The user logs into the target website (like a bank site) and gets an authentication cookie. This step uses the automatic cookie sending mechanism. After the bank site sets an identity authentication cookie, the browser will automatically attach this cookie to every request sent to that site.
Without logging out, the user visits a malicious website. At this point, due to the same-origin policy, the malicious site can't directly read or modify the bank site's cookie. This protects the user's identity information from being directly stolen.
The malicious site includes a request to the target site (like a transfer operation).
Although the same-origin policy restricts cross-origin access, it allows cross-origin network requests, such as requests initiated through <img>, <form> tags. Attackers exploit this "loophole".
The user's browser automatically sends this request, along with the target site's cookie. This is the core of the CSRF attack. It takes advantage of both the same-origin policy allowing cross-origin requests and the automatic cookie sending mechanism (even requests triggered by malicious sites will carry cookies matching the domain).
The target site receives the request, verifies the cookie is valid, and executes the operation. The server can't tell if this request comes from a legitimate user action because the attached cookie is valid.
Let's illustrate how a CSRF attack happens with a specific example. We'll use a fictional bank website bank.com as an example.
First, the user visits https://bank.com and logs into their account.
After successful login, the server sets an authentication cookie, for example:
The user performs a transfer operation on the bank website, say transferring $1000 to Alice. This operation might send a request like this:
Now, suppose an attacker creates a malicious website https://evil.com containing the following HTML:
When the user clicks the https://evil.com link without logging out of their bank account, because they're already logged into bank.com, the browser has a valid session_id cookie.
After the evil page loads, it automatically submits the hidden form, sending a transfer request to https://bank.com/transfer.
The user's browser automatically attaches the bank.com cookie to this request. The bank.com server receives the request, verifies the cookie is valid, and then executes this unauthorized transfer operation.
Here are several commonly used CSRF defense methods. We'll explain in detail the principle of each method and how it effectively prevents CSRF attacks:
CSRF tokens are one of the most common and effective methods to defend against CSRF attacks. Here's how it works:
Because the CSRF token is a unique value bound to the user's session, and the attacker can't know or guess this value (as it's different for each session), even if the attacker tricks the user into sending a request, the request will be rejected by the server due to the lack of a valid CSRF token.
Implementation example:
On the server side (using Node.js and Express):
In frontend JavaScript:
Referer headerThe Referer header contains the URL of the page that initiated the request. By checking the Referer header, the server can determine if the request comes from a legitimate source.
Since CSRF attacks usually come from different domains, the Referer header will show the attacker's domain name. By verifying whether the Referer is the expected value, requests from unknown sources can be blocked.
However, it's worth noting that this method is not entirely reliable, as some browsers might not send the Referer header, and users can disable the Referer header through browser settings or plugins.
Implementation example:
SameSite cookie attributeSameSite is a cookie attribute used to control whether cookies are sent with cross-site requests. It has three possible values:
Strict: Cookies are only sent in same-site requests.Lax: Cookies are sent in same-site requests and top-level navigation.None: Cookies are sent in all cross-site requests (must be used with the Secure attribute).When SameSite is set to Strict, it can completely prevent third-party websites from sending cookies, thus effectively preventing CSRF attacks.
If SameSite is set to Lax, it protects sensitive operations while allowing some common cross-site use cases (like entering a website from external links).
Implementation example:
For AJAX requests, custom request headers can be added. Due to the restrictions of the same-origin policy, attackers cannot set custom headers in cross-origin requests. The server can check for the presence of this custom header to verify the legitimacy of the request.
Implementation example:
On the frontend:
On the server side:
Double cookie verification is an effective CSRF defense technique. Its core principle is that the server generates a random token, sets it as both a cookie and embeds it in the page (usually as a hidden form field). When the browser sends a request, it automatically includes the cookie, while the page's JavaScript sends the token as a request parameter. The server then verifies if the token in the cookie matches the token in the request parameters.
Although attackers can include the target website's cookie in cross-site requests, they cannot read or modify the cookie's value, nor can they access or modify the token value in the page. By requiring the request to include tokens from both the cookie and parameters, it ensures the request comes from a source with permission to read the cookie, thus effectively defending against CSRF attacks.
For particularly sensitive operations (like changing passwords or making large transfers), users can be required to re-authenticate. This provides users with an additional security checkpoint. Even if a user successfully initiates a CSRF attack, they cannot pass the re-authentication step.
Implementation suggestions:
Through this in-depth discussion, we hope you now have a more comprehensive understanding of CSRF attacks. We've not only learned about how CSRF works but also explored various effective defense measures. All these methods can effectively enhance the security of web applications.
Hope this knowledge will help you better handle CSRF-related issues in your daily development and build more secure web applications.