Cross-site request forgery, usually called CSRF (pronounced “sea-surf”), is one of the less famous but more clever web attacks. It works not by breaking into a site, but by tricking the site into thinking a legitimate user wanted to do something they did not actually want to do.
The attacker does not need access to the user’s password. The user does not need to be tricked into clicking a malicious link to their bank. The attacker just needs the user to visit a malicious page while logged into the target site. Things happen from there without the user’s knowledge.
This piece covers what CSRF actually is, how the attacks work, what they can do, and how to defend against them.
What CSRF Actually Is
The attack exploits how browsers handle authentication.
How Browser Authentication Works
When you log into a website, your browser stores authentication cookies. From that point, every request your browser makes to the site includes those cookies. The site sees the cookies and treats you as logged in.
This is convenient. You do not need to log in for every page you visit on the site. The cookies handle the authentication automatically.
The Vulnerability
The cookies get sent for every request to the site, regardless of where the request originated. If you click a link on a different site that triggers a request to your bank, your browser includes your bank’s authentication cookies in that request. Your bank sees the request as authenticated.
If the request does something (transfers money, changes settings, adds a new admin account), the bank does it because the request looks legitimate.
The Attack Pattern
The attacker creates a page (often on a site they control). The page contains code that triggers a request to the target site doing something the attacker wants done.
The attacker convinces the victim to visit the malicious page. This could be through a phishing email, a social media link, or just an ad on a website.
When the victim visits the page, their browser sends the request to the target site. The request includes the victim’s authentication cookies. The target site processes the request as if the victim authorized it.
The victim has no idea anything happened.
How CSRF Attacks Work in Practice
Several specific attack patterns illustrate how this works.
Hidden Forms
The simplest pattern. The attacker creates a page with a form that submits to the target site. The form action targets the URL that performs the desired action.
JavaScript on the page automatically submits the form when the visitor arrives. The form submission includes the visitor’s cookies.
Image Tags
For simpler actions that can be triggered with a GET request, an image tag works.
If the attacker can craft a URL that performs the action when visited, they put that URL in an image tag on their page. When the visitor’s browser tries to load the “image,” it sends the GET request with the visitor’s cookies.
This is why GET requests should never change state. Actions should require POST or other request types that browsers do not automatically send for image tags.
Auto-Submit Forms
JavaScript can submit forms automatically. The attacker’s page submits the form as soon as it loads. The visitor sees nothing visible, but the action happens.
Custom Request Construction
Modern JavaScript can make any kind of HTTP request. Attackers can construct precisely the request they need to trigger the desired action.
What CSRF Attacks Can Do
The damage depends on what actions are available to authenticated users.
Change Account Settings
Change the email address on the account. Once the email is changed, the attacker can request a password reset and gain full control.
Change the password directly if the site does not require the old password for the change.
Change other account details that affect security.
Make Purchases or Transactions
For e-commerce sites or financial services, transactions performed through CSRF can move money or order goods.
Post Content
Force the victim to post content they did not actually want to post. Comments, status updates, reviews. Often used for spam or harassment campaigns.
Add Permissions
For admin accounts, add additional admin users or grant elevated permissions to specific accounts. This creates persistent access for the attacker.
Delete Data
Delete content, accounts, or other valuable data.
Trigger Workflows
For sites with workflows or automation, trigger workflows that should require deliberate action.
How to Prevent CSRF
The defenses are well-established.
CSRF Tokens
The primary defense. Every state-changing form includes a hidden field with a token that is unique to the user’s session.
When the form gets submitted, the server checks that the token matches what it expects for that session. Attackers cannot generate valid tokens because they do not know the user’s session.
Without a valid token, the request gets rejected. The CSRF attack fails.
Modern frameworks and CMS platforms include CSRF token functionality. WordPress has nonces, which work similarly. Custom code needs to implement this pattern.
SameSite Cookies
Modern browsers support a SameSite attribute on cookies. Cookies marked as SameSite=Strict or SameSite=Lax are not sent on cross-site requests.
When the malicious page tries to trigger a request, the browser does not include the target site’s cookies. The request looks unauthenticated. The attack fails.
Most modern frameworks set SameSite by default for session cookies. Verify this is happening on your site.
Check the Referer Header
The Referer header tells the server where the request came from. Requests from external sites have a different Referer than requests from the site itself.
This is not foolproof (Referer headers can be missing or spoofed in some cases), but it adds another check.
Require Authentication for Sensitive Actions
For especially sensitive actions (changing passwords, modifying admin accounts), require the user to re-enter their password or provide other verification. CSRF cannot provide this kind of fresh authentication.
This adds friction for users but provides strong protection for the most damaging actions.
Use POST for State Changes
GET requests should not change anything on the server. POST or other appropriate methods should be used for actions.
This prevents simple image-tag attacks that rely on GET requests.
Custom Headers
For AJAX requests, requiring a custom header (like X-Requested-With) provides some protection. Cross-origin requests cannot set arbitrary headers without explicit cooperation from the target site.
Web Application Firewall
A WAF can detect some CSRF patterns and block them. This adds a layer of defense but is not as reliable as proper CSRF tokens.
Common Mistakes
People stumble in predictable ways with CSRF.
Skipping Protection on AJAX Endpoints
Sometimes CSRF protection gets added to forms but not to AJAX endpoints. AJAX endpoints are equally vulnerable. They need the same protection.
Trusting the Referer Alone
Referer headers can be missing in some cases (HTTPS to HTTP transitions, certain browser settings). Using Referer as the only defense leaves gaps.
Not Validating Tokens
Generating tokens but not actually validating them on submission provides no protection.
Reusing Tokens Across Sessions
If tokens are predictable or reused across sessions, attackers can sometimes obtain valid tokens. Tokens should be unique to each session and ideally to each action.
Using GET for Sensitive Actions
Even with CSRF tokens, using GET for state changes is risky. Sticking to POST for state changes is best practice.
Forgetting About Third-Party Embeds
If your site embeds third-party content (iframes, scripts), that content could potentially trigger CSRF against your site. Restrict what can be embedded and where.
How to Test for CSRF Vulnerabilities
If you want to evaluate CSRF risk on your site, several checks help.
Review Forms
Look at every form on your site that does something. Does it have a CSRF token? Does the server validate the token?
Forms without protection are CSRF-vulnerable.
Check AJAX Endpoints
For sites with AJAX, examine the API endpoints. Are they protected against CSRF?
Test With Crafted Requests
Try submitting forms or making requests without the CSRF token. If they succeed, the protection is missing or broken.
This kind of testing requires some technical knowledge but reveals vulnerabilities concretely.
Penetration Testing
Professional pen testing finds CSRF and other vulnerabilities that automated tools and review miss.
Closing Thoughts on Forged Request Defense
Cross-site request forgery is one of those vulnerabilities that requires no special skill to exploit but can cause significant damage. The defenses are equally straightforward but require discipline to implement.
For most sites, the defenses are part of using modern frameworks. CSRF tokens, SameSite cookies, proper authentication requirements. The frameworks handle most of this when used correctly.
The discipline is in not skipping the protection. Custom code that does not implement CSRF tokens. AJAX endpoints that get added without thinking about CSRF. Sensitive actions that should require re-authentication but do not.
Sites that follow modern development practices have most of the protection by default. Sites with custom code that lacks discipline have vulnerabilities that may not show up until exploited.
For business sites, the financial damage from CSRF can be real. Unauthorized purchases. Account takeovers through email changes. Modifications that should not have happened. The cost can extend beyond direct damage to customer trust and regulatory exposure.
If your site has custom code that handles user actions, audit it for CSRF protection. If your site uses third-party software, keep it current. If your site has not been tested specifically for CSRF, consider doing so. The work is bounded and the protection is real. Sites that take CSRF seriously close one of the more common vulnerabilities that attackers look for. Sites that ignore it remain vulnerable to attacks that require no sophistication beyond awareness of the technique.