⚠️ Lab Environment Only: All CSRF techniques in this guide are practised against your local DVWA instance at 127.0.0.1. CSRF attacks against systems you do not own or have explicit written authorisation to test are illegal. All exercises target your local DVWA only.
CSRF is the attack that turns a logged-in user’s own browser into a weapon against them — changing passwords, transferring funds, deleting accounts — without them clicking anything unusual or noticing anything wrong. The browser fires the forged request automatically. DVWA CSRF Lab walks you through all four security levels, from completely unprotected to the correct token-based implementation that defeats it entirely.
🎯 What You’ll Master in Lab 4
Understand why browsers automatically send cookies with cross-origin requests — the root cause of CSRF
Build a malicious HTML PoC that changes the DVWA admin password without user interaction
Test the Medium security referer-check approach and understand why it is insufficient
Analyse the High and Impossible source code to understand correct anti-CSRF token implementation
Identify the modern browser-level defence: SameSite cookie attribute
Complete Lab 1 (DVWA Setup) before starting this lab. Navigate to http://127.0.0.1/dvwa/vulnerabilities/csrf/ with Security Level set to Low.
How CSRF Works — The Browser as a Weapon
CSRF exploits a fundamental browser behaviour: when your browser loads any resource — an image, a page, a form submission — it automatically sends all relevant cookies for that domain with the request. This is what keeps you logged in as you navigate between pages. But it also means any page you visit can cause your browser to make authenticated requests to other sites you are currently logged into, without your knowledge or consent.
securityelites.com
CSRF Attack — 4-Step Flow
1
Victim logs into DVWA
Browser stores session cookie: PHPSESSID=abc123 for 127.0.0.1
2
Attacker sends victim a link to malicious page
http://attacker.com/win-prize.html — contains a hidden DVWA password-change request
Browser loads the img tag → sends GET to DVWA password URL with session cookie attached
4
DVWA processes the request — password changed
DVWA sees valid session cookie + password parameters → accepts request. Attacker knows the new password.
📸 CSRF four-step flow — the victim never clicks anything suspicious, types any credentials, or sees any sign of the attack. The browser fires the forged request automatically when loading the img tag on the attacker’s page.
💡 The Root Cause: CSRF works because browsers trust the session cookie to identify the user, and cookies are sent automatically with every request to their domain — including requests initiated by a completely different website. The application has no way to tell whether the request came from the real form or from an attacker’s page unless it requires a secret token that only the real form knows.
🛠️ EXERCISE 1 — BROWSER ONLY (CREATE CSRF POC)
Build the malicious HTML page and change the DVWA admin password via CSRF
1. Log into DVWA as admin (security level: Low)
2. Open csrf_poc.html in the browser (File → Open File)
3. The img tag fires automatically — you will see a 1×1 pixel request
4. Navigate to DVWA CSRF module — it should confirm “Password Changed”
5. Log out and try logging in with password “hacked”
6. Reset the database (DVWA Setup page) to restore the original password
✅ What you just learned: A legitimate-looking page with a hidden 1×1 image changed the DVWA admin password without any visible user action. In a real scenario this page would arrive via phishing email, a malicious ad, or a stored XSS injection. DVWA cannot distinguish the forged request from a legitimate one — both carry the same valid session cookie.
📸 Screenshot the “Password Changed” DVWA confirmation and share in #dvwa-csrf on Discord.
🧠 QUICK CHECK
Why does CSRF work even though the attacker never has access to the victim’s session cookie?
Medium Security — Referer Check and Its Limits
At Medium security, DVWA adds a check: it reads the HTTP Referer header and rejects requests that do not appear to come from the DVWA domain. This represents a developer who has heard that referer checking prevents CSRF — but the implementation has significant weaknesses.
MEDIUM SECURITY — REFERER CHECK SOURCE
# Medium security adds this check (from source/medium.php):
// Referer contains the server name — proceed with password change
}
# WEAKNESS 1: stripos checks if server name appears ANYWHERE in referer
# Bypass: name your attacker page to include the target domain:
http://attacker.com/127.0.0.1/csrf_poc.html
# The path contains “127.0.0.1” — stripos finds it — check passes!
# WEAKNESS 2: Referer header can be stripped/modified by browsers,
# proxies, and privacy tools — making it an unreliable defence
# LESSON: Referer checking is a partial mitigation, not a solution.
# Only unpredictable per-session tokens reliably prevent CSRF.
🧠 EXERCISE 2 — THINK LIKE A HACKER (3 MIN)
Why is checking the Referer header fundamentally insufficient for CSRF protection?
⏱️ Time: 3 minutes · No tools required
Think through all the ways the Medium security referer check fails:
1. Browser privacy settings (can you rely on browsers sending Referer?)
2. HTTP vs HTTPS transitions (what happens to Referer across protocols?)
3. The stripos bypass shown above (contains vs equals check)
4. Corporate proxies and VPNs (do they strip Referer?)
5. What would happen if you used a POST form vs GET request?
For each point: does the referer check protect against it?
✅ What you just learned: Referer checking fails as a CSRF defence because: browsers do not always send it (Referrer-Policy header, privacy modes, HTTPS→HTTP transitions); proxies strip it; and contains-based checks have trivial bypasses. A defence that depends on a header the browser may or may not send — and that can be manipulated — is not a reliable security control. Only unpredictable per-request tokens that the server issues and verifies are reliable.
📸 Write your answers and share in #dvwa-csrf on Discord.
High Security — Token Protection
At High security, DVWA adds a user_token hidden field to the password change form. This is an anti-CSRF token — a unique, unpredictable value tied to the user’s session. The server rejects any request that does not include the correct token value.
An attacker cannot directly forge a valid token because the same-origin policy prevents cross-origin JavaScript from reading the token from DVWA’s page. However, if there is a stored XSS vulnerability on the DVWA domain, that XSS can be used to steal the token and include it in a subsequent forged request — this is the classic XSS-CSRF chained attack.
HIGH SECURITY — TOKEN FLOW IN DVWA
# High security password change URL requires user_token:
# Token is a random hex value issued per page load:
# e.g. user_token=a3f8b2d1c4e5f6a7b8c9d0e1f2a3b4c5
# An attacker cannot guess this token (32 hex chars = 128-bit entropy)
# An attacker cannot read this token via JS (same-origin policy)
# BYPASS (requires same-domain XSS):
# Inject JS on DVWA domain that reads the token from the CSRF page,
# then fires the password change request with the valid token.
# This is covered in the XSS lab — outside scope of this lab.
Impossible Security — What Actually Works
The Impossible level takes a different approach that makes CSRF attacks completely useless: it requires the user to enter their current password before setting a new one. An attacker forging a request cannot know the victim’s current password, so the forged request will always fail — regardless of whether tokens are used.
GET ?password_new=X&password_conf=X&Change=Change → Any page can fire this. Zero friction for attacker.
🟡 MEDIUM — Referer check (insufficient)
Checks if server_name appears in Referer header → Bypass: name attacker page to contain target domain in path
🔵 HIGH — Anti-CSRF token
Requires user_token per request, checked server-side → Bypass only possible with same-domain XSS to steal token
🟢 IMPOSSIBLE — Current password required + PDO
Requires current_password input, validated via PDO parameterised query → CSRF useless — attacker cannot know victim’s current password
📸 Security level defence progression — Low has nothing, Medium uses an unreliable header, High uses proper tokens, Impossible eliminates the attack vector entirely by requiring knowledge the attacker cannot have.
🔥 EXERCISE 3 — KALI TERMINAL (SOURCE CODE REVIEW)
Read all four CSRF source files and document each security gap
⏱️ Time: 10 minutes · Target: Your DVWA Docker container
# 1. What protection is added vs the previous level?
# 2. What specific line implements the protection?
# 3. What is the residual weakness?
# 4. How would you bypass it (if applicable)?
✅ What you just learned: The Impossible level’s requirement for current_password is the key insight. CSRF cannot forge what the attacker does not know. Many real-world applications apply exactly this principle — requiring current password for sensitive operations like email or password changes. This is a defence-in-depth measure that works even if your token implementation is later bypassed via XSS.
📸 Screenshot the Impossible-level source showing current_password check and share in #dvwa-source-review on Discord. Tag #dvwalab4
Modern CSRF Defence — SameSite Cookies
Modern browsers now support the SameSite cookie attribute, which is the browser-level defence against CSRF. When set to Strict or Lax, the browser simply does not send the cookie with cross-site requests at all — eliminating the root cause of CSRF rather than trying to detect or reject forged requests after the fact.
Strict→ Cookie NOT sent on any cross-site request (most secure)
Lax→ Cookie sent on top-level navigation GET requests only (good default)
None→ Cookie sent on all requests (requires Secure flag — old behaviour)
# In PHP ini / .htaccess:
session.cookie_samesite = Strict
# As of 2021, Chrome sets Lax as default for cookies without SameSite.
# This means many CSRF attacks fail automatically in modern browsers.
# However — do not rely on browser defaults. Always set it explicitly.
⚠️ Defence in Depth: Use both anti-CSRF tokens AND SameSite cookies. SameSite protects modern browsers; tokens protect older browsers and non-browser clients. Requiring current password for sensitive operations adds a third layer that defeats CSRF even if both other defences fail.
🧠 QUICK CHECK — Lab 4 Final
Why does the Impossible level make CSRF attacks useless even without using an anti-CSRF token?
From PoC HTML to token analysis — all 4 security levels done.
❓ Frequently Asked Questions – DVWA CSRF Lab
What is a CSRF attack?
CSRF (Cross-Site Request Forgery) tricks an authenticated user’s browser into sending unauthorised requests to a web application they are logged into. Because browsers automatically include session cookies with every request to a domain, the application cannot distinguish a legitimate request from a forged one unless it requires an anti-CSRF token that must be explicitly included by the real form.
What is the difference between CSRF and XSS?
XSS injects malicious scripts into a web page that execute in the victim’s browser, stealing cookies or performing actions. CSRF forges requests from the victim’s browser to a target application without injecting any code — it exploits the trust the application places in the browser’s session. XSS can be chained with CSRF to steal anti-CSRF tokens from protected forms.
How do anti-CSRF tokens prevent this attack?
Anti-CSRF tokens are unique, unpredictable values tied to the user’s session and embedded in every state-changing form. The server verifies the token matches. An attacker cannot forge a valid token because the same-origin policy prevents cross-origin JavaScript from reading the value. Without a valid token, the forged request is rejected.
Does HTTPS prevent CSRF?
No — HTTPS encrypts the connection but does not prevent CSRF. Browsers include cookies with cross-origin requests regardless of HTTPS. Real prevention requires anti-CSRF tokens, SameSite cookie attributes (Strict or Lax), and Origin/Referer header validation — all three for defence in depth.
What makes DVWA Impossible level safe from CSRF?
It requires the user to enter their current password before setting a new one, validated via PDO parameterised queries. A CSRF attacker cannot know the victim’s current password, so the forged request always fails regardless of whether a token is included or not. This current_password requirement is the cleanest CSRF defence for sensitive operations.
What DVWA lab comes after CSRF?
Lab 5 covers File Inclusion (LFI/RFI) — injecting file paths into vulnerable PHP include statements to read arbitrary server files or execute remote code. It builds on the same source-code review methodology used in this lab to understand what correct path handling looks like.
DVWA Lab 3: Command Injection 2026— The previous lab — inject OS commands through web forms, establish a reverse shell, and analyse all four security levels.
Bug Bounty Day 7: XSS Hunting— XSS is CSRF’s most dangerous enabler — a stored XSS on the target domain can steal anti-CSRF tokens and bypass High security.
DVWA Labs Hub— The complete 30-lab DVWA series covering every vulnerability module from brute force through to advanced chaining techniques.
PortSwigger: CSRF Complete Guide— The definitive CSRF reference with free interactive labs covering token bypass, SameSite edge cases, and multi-step CSRF attacks.
CSRF is the vulnerability that developers most consistently underestimate because the proof of concept looks so simple — a one-line HTML file. But I have found CSRF in bank password change forms, e-commerce checkout flows, and admin panel user-creation endpoints. The impact of each was severe. What I want every student to take from this lab is not just how to build the PoC, but why the Impossible level’s current_password approach is so elegant — it defeats CSRF entirely by requiring knowledge the attacker cannot possess, no token system required.
Leave a Reply