What is CSRF?
Cross-Site Request Forgery (CSRF) is a common yet stealthy web security attack. It exploits the victim's browser identity, which has already logged into a specific website, to trick the user into initiating unintended operations against that site without the user's awareness. Such attacks typically target websites that rely on cookies for authentication; attackers do not need to steal users' passwords or session tokens, they only need to cause the victim to execute malicious requests unknowingly.
The core of CSRF lies in "trust". Modern web applications generally adopt the Same-Origin Policy to isolate pages from different sources, but this policy primarily targets read operations (such as GET requests) and is often less strict regarding state-changing operations (such as POST, PUT, DELETE). If a website relies solely on a Session ID stored in cookies to maintain user login status, an attacker can construct a malicious link or image to induce the victim to carry their original cookies when visiting that malicious resource, thereby executing arbitrary commands on the target site.
In practical scenarios, CSRF attacks are typically implemented through the following methods:
- Malicious Links: Attackers embed links pointing to malicious URLs within social media posts, emails, or instant messaging messages. When a user clicks such a link, their browser initiates a request to the target website. If the request contains a valid session cookie, the server assumes this is the user's genuine intent.
- Iframe Embedding: Attackers utilize
<iframe>tags to embed the victim's page or specific resources into their own malicious websites. When the victim browses their own site, the iframes automatically send requests to the attacker-controlled domain (unless configured with same-origin policy restrictions). - Automated Scanning Tools: Many automated crawlers and scanners traverse URLs across numerous websites, attempting to execute POST requests to trigger operations such as login, fund transfers, or data deletion. These tools often simulate browser behavior and carry cookies.
Why CSRF Attacks Are Hard for Users to Detect
CSRF attacks are dangerous precisely because they completely bypass user interaction confirmation mechanisms. Most modern websites display a "confirm dialog" (e.g., "Are you sure you want to change your password?") when submitting forms, effectively blocking CSRF requests. However, many backend APIs, image upload interfaces, or simple data query interfaces do not involve such secondary confirmations.
For example, assume User A is logged into a banking website. Attacker B can create an HTML file containing the following code:
<img src="https://bank.com/api/transfer?amount=1000&target=victim">
When User A visits this image, their browser automatically sends a POST request to the bank server to execute the transfer operation. Since the request carries a valid Session Cookie, the bank server believes this is User A's genuine instruction and completes the transfer. The entire process is transparent to User A until the funds are lost.
Core Strategies for Defending Against CSRF
To effectively defend against CSRF attacks, developers must introduce additional verification mechanisms at an architectural level and cannot rely solely on the same-origin policy or form submission methods. Currently, the most widely recognized effective defense solutions include:
1. Use Synchronizer Tokens
This is the most widely used defense method. The website generates a random token upon the user's first login and stores it both on the server side and on the client side (typically passed via an HttpOnly cookie). When performing any state-changing operation (such as submitting a form or calling an API), the frontend must send this token to the server as part of a hidden field or a request header.
If an attacker attempts to forge a request, they will be unable to retrieve the token stored in the HttpOnly cookie. Consequently, when the server verifies the request, it will find the token mismatched and reject the request.
2. Enable CORS Same-Origin Policy
Although Cross-Origin Resource Sharing (CORS) is primarily used to control cross-origin reads, configuring the Access-Control-Allow-Origin header value to be inconsistent with the current domain can prevent malicious websites from initiating requests to the target site via iframes. This method usually serves as an auxiliary defense mechanism and works better when combined with synchronizer tokens.
3. Enforce Strict Same-Origin Policy
Ensure that a website only allows resources from trusted domains to be embedded (via iframe). For untrusted third-party content, it should be prohibited from loading via iframes, thereby cutting off the path for attackers to initiate requests using the victim's page.
Best Practice Examples
When building backend interfaces, it is recommended to follow the following code logic to implement synchronizer token verification:
Frontend Form Submission Example:
<form action="/api/update-profile" method="POST">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
<!-- Other form fields -->
</form>
Backend Verification Logic Pseudocode:
def handle_update_profile(request):
# 1. Retrieve the CSRF Token from headers or form data
token = request.headers.get('X-CSRF-Token') or request.form.get('csrf_token')
# 2. Look up the corresponding valid token on the server side
expected_token = session.get_csrf_token()
# 3. Verify if the tokens match
if token != expected_token:
return jsonify({"error": "Invalid CSRF token"}), 403
# 4. Execute business logic
update_user_data(request)
Through these mechanisms, even if an attacker can access the victim's cookies, they cannot construct valid request parameters because they lack the server-side verified token. This concept of "double verification" is key to securing web applications. Developers should assume that users may be subject to CSRF attacks when designing any feature involving state changes and implement strict token verification accordingly.