⚠️ Lab Environment Only: All techniques in DVWA Source Code Review Lab use DVWA running on your own local machine. Never apply these techniques against systems you do not own or have explicit written authorisation to test. SecurityElites.com accepts no liability for misuse.
Most people who use DVWA never click the View Source button. They set the security level to Low, fire payloads until something works, screenshot the output, and move on. I understand why — the exploitation is the exciting part. But that habit builds a practitioner who needs trial and error on every engagement rather than one who reads the code, understands the vulnerability, and constructs the right payload on the first attempt.
On a white-box web application assessment last year, the client gave me access to the PHP source code alongside the running application. The codebase had 40,000 lines. I found three critical SQL injection points in eleven minutes — not by running SQLMap, but by searching the source for the pattern $_GET and $_POST variables being concatenated into query strings. The source told me exactly which parameters to target, what the query structure was, and what payload would extract the data. DVWA’s View Source button teaches exactly that skill — reading what the application actually does with your input before you decide what to send it. Lets start with our DVWA Source Code Review Lab.
🎯 What You’ll Master in Lab 27
Use DVWA’s View Source to read PHP backend code across all security levels
Identify the vulnerable code pattern for SQL injection, XSS, command injection, and file inclusion
Compare Low, Medium, High, and Impossible source — understand what each level adds
Map source code findings directly to targeted exploit payloads
Identify bypassable blacklists in Medium security and construct bypass payloads from the source
Write source-informed remediation recommendations for a professional report
⏱️ Lab 27 · 3 exercises · DVWA running locally
✅ Prerequisites
DVWA running locally —
DVWA Lab Setup Guide
if you need it
DVWA SQL Injection Lab
— you need to have exploited SQLi first; today you will read the source that makes it vulnerable
Labs 1 through 26 taught you to exploit every major vulnerability class in DVWA. Lab 27 turns that around — instead of probing from outside, you read the code that makes each one exploitable. The DVWA lab series covers 30 labs total. Lab 28 is the final pentest report exercise where you document everything. Understanding the source code behind each vulnerability is what makes your Lab 28 report findings technically precise rather than generic.
The View Source Button — How DVWA Exposes Its Own Code
Every DVWA module has two buttons at the bottom of the page: View Source and View Help. View Source is the one that changes how you think about web application security testing. It shows you the exact PHP code processing your input for the current security level. More importantly, Compare All Levels shows Low, Medium, High, and Impossible in the same window — four versions of the same feature, each representing a different developer’s approach to the same security problem.
The way I use these buttons on every DVWA module: first I exploit the Low level by trial and error to build intuition. Then I open View Source and read exactly why the payload worked. Then I look at Medium and High to understand what the developer changed — and whether those changes are sufficient. The Impossible level is what I read when writing the remediation section of a report: it shows the correct fix rather than leaving me to write “use parameterised queries” without showing the client what that looks like in their specific code.
if (!in_array($_GET[‘page’], $allowed)) { die(‘Not allowed’); }
🧠 EXERCISE 1 — THINK LIKE A HACKER (15 MIN · DVWA REQUIRED)
Read the Source Before You Attack — SQL Injection Source Analysis
⏱️ 15 minutes · DVWA running locally
This exercise builds the source-first habit. Before you send a single SQLi payload, you will read the code, identify the vulnerability, and predict exactly what payload will work — then confirm it. This is white-box testing methodology applied to DVWA.
Step 1: Open DVWA and navigate to SQL Injection.
Set security to Low. DO NOT submit any input yet.
Click “View Source” at the bottom of the page.
Step 2: Read the PHP source carefully. Find these things:
— Where does the user input enter the code? ($_GET or $_POST?)
— What is the input variable name?
— Is the input sanitised before use? (Any mysql_real_escape_string,
intval, prepared statements, or validation functions?)
— What SQL query is constructed? Write it out exactly.
— What is the query doing? (SELECT? WHERE clause? JOIN?)
Step 3: Based only on the source code, answer these questions:
— What type of SQL injection does this allow? (UNION? Boolean? Error?)
— What column does the WHERE clause filter on?
— How many columns does the SELECT return?
— What database table is being queried?
Step 4: Construct your test payload purely from reading the source.
Without guessing or trying random payloads, write the exact UNION
injection payload that will work based on what you read.
Predict the output before submitting.
Step 5: Submit your payload and compare to your prediction.
Did the source tell you what you needed to know?
What would have taken longer using trial-and-error only?
Step 6: Now click “Compare All Levels.”
Look at Medium security. What changed?
What did the developer add? Is it sufficient?
Test whether the Medium protection is bypassable.
✅ You just practiced white-box exploitation — reading the code first, then confirming the exploit. The key observation from Step 3 is that the source tells you the exact column count, query structure, and table name before you send a single packet. That information would take 5-15 minutes of trial-and-error in black-box testing. The Medium comparison in Step 6 shows the classic blacklisting mistake — if Medium escapes single quotes but not double quotes, or escapes certain characters but not others, you can read exactly what is blocked and craft a bypass that avoids the blocked characters without guessing.
📸 Screenshot the DVWA source code alongside your working payload. Share in #dvwa-labs on Discord.
SQL Injection Source Review — Low to Impossible
The DVWA SQL injection module is the clearest illustration of how security level changes the underlying code. Reading all four levels back to back shows a progression from completely unsanitised input to correctly parameterised queries — and at Medium and High, the partial fixes that look like security but are not.
DVWA SQL INJECTION — ALL FOUR SECURITY LEVELS
# ── LOW: Raw variable in query — no protection ─────────────────
$id = $_GET[‘id’];
$query = “SELECT first_name, last_name FROM users WHERE user_id = ‘$id’;”;
Payload: 1′ UNION SELECT user, password FROM users– –
Result: Dumps all usernames and password hashes immediately
# ── MEDIUM: Basic escaping via mysqli_real_escape_string ────────
$id = $_POST[‘id’]; // Changed to POST — harder to test in URL bar
$query = “SELECT first_name, last_name FROM users WHERE user_id = $id;”;
# KEY: No quotes around $id in the query — escaping quotes is irrelevant
Payload: 1 UNION SELECT user, password FROM users– –
Result: Numeric injection — no quotes needed, escaping doesn’t help
# ── HIGH: Query via SESSION variable — subtle and bypassable ────
$id = $_SESSION[‘id’]; // Input comes from a different page
$query = “SELECT first_name, last_name FROM users WHERE user_id = ‘$id’ LIMIT 1;”;
# LIMIT 1 breaks UNION injection — only one row returned
# But: LIMIT comes after the injection point, comment removes it
Payload: 1′ UNION SELECT user, password FROM users– –
Comment removes LIMIT 1 — still injectable via the session input page
# ── IMPOSSIBLE: Prepared statement with type enforcement ────────
$data = $db->prepare(‘SELECT first_name, last_name FROM users WHERE user_id = ? LIMIT 1;’);
$data->bind_param(‘i’, $id); // ‘i’ forces integer — no strings allowed
$data->execute();
No injection possible — the query structure is fixed at prepare time
$id is treated as a value, never as SQL syntax
securityelites.com
DVWA Source Comparison — SQLi Low vs Impossible
LOW — VULNERABLE
$id = $_GET[‘id’];
$query = “SELECT … WHERE user_id = ‘$id’;”;
↑ Direct concatenation — injectable
IMPOSSIBLE — SECURE
$stmt = $db->prepare(“… WHERE id = ?”);
$stmt->bind_param(‘i’, $id);
↑ Parameterised — input is a value, not SQL
Medium bypass insight: mysqli_real_escape_string escapes quotes but the query has no quotes around $id — numeric injection bypasses the entire protection
📸 DVWA SQL injection source code comparison showing Low (raw concatenation, fully injectable) versus Impossible (parameterised query, injection impossible). The Medium level escape function protects against quote-based injection but the missing quotes around the variable in the query string mean numeric injection bypasses it entirely — a textbook example of why blacklist protections fail and parameterised queries are the only correct fix.
XSS Source Review — Where Output Goes Unescaped
XSS vulnerabilities in PHP come from user input reaching HTML output without encoding. The source review shows you exactly where that happens — and more importantly, what encoding function would fix it. Reading the output context (is the input inside a tag attribute? Inside a script block? In plain HTML?) determines which encoding is correct.
DVWA XSS REFLECTED — SOURCE REVIEW ALL LEVELS
# ── LOW: Raw echo — no encoding ────────────────────────────────
Command injection vulnerabilities in PHP appear whenever user input reaches a function that executes shell commands: shell_exec(), exec(), system(), passthru(), or the backtick operator. The source review shows you which function is used and how the input is passed to it — which determines what shell metacharacters will chain additional commands.
DVWA COMMAND INJECTION — SOURCE REVIEW
# ── LOW: Raw passthrough to shell_exec ─────────────────────────
$target = $_REQUEST[‘ip’];
if (stristr(php_uname(‘s’), ‘Windows NT’)) {
$cmd = shell_exec(‘ping ‘ . $target);
} else {
$cmd = shell_exec(‘ping -c 4 ‘ . $target);
}
Payload: 127.0.0.1 ; whoami OR 127.0.0.1 && cat /etc/passwd
# ── MEDIUM: Blacklist ; and && — pipe and newline still work ──
if (!is_numeric($check) || $check > 255) { die(‘Invalid input’); }
}
Only valid IP address octets pass — no shell metacharacters possible
⚡ EXERCISE 2 — KALI TERMINAL (20 MIN)
Source-Informed Bypass — Command Injection Medium and High from Source
⏱️ 20 minutes · DVWA running locally · Kali terminal for reference
This exercise applies source-informed bypass methodology to Command Injection. You will read the Medium and High source code, identify the exact characters the blacklist misses, and construct bypass payloads derived directly from the source — not from a payload list.
Step 1: Navigate to DVWA → Command Injection → set Medium security.
Click View Source. Read the blacklist carefully.
Write down every character or string that IS blocked.
Write down every character or string that is NOT blocked.
Step 2: From your list of unblocked characters, identify which
shell metacharacters can chain commands. Write the bypass payload
using only unblocked characters. Test it.
Step 3: Switch to High security. Click View Source.
Read the extended blacklist. Identify the ONE character sequence
that is blocked versus the ONE that is NOT.
(Hint: look very carefully at pipe-related entries.)
Step 4: Construct your High bypass payload from what you found.
The bypass is one character different from a blocked sequence.
Test it: submit 127.0.0.1[YOUR_BYPASS]id in the IP field.
Step 5: Compare Low, Medium, and High source in Compare All Levels.
For each level, answer:
— What type of protection was used? (Escaping? Blacklist? Whitelist?)
— What is the fundamental flaw in Medium and High’s approach?
— What ONE change to High security would close all these bypasses?
Step 6: Read the Impossible source code.
Write a one-sentence explanation of why Impossible cannot be bypassed
using the same techniques, even with the most creative payload.
✅ You just derived both Medium and High bypasses directly from the source code without a payload list. The High bypass (pipe without trailing space) is the most instructive — the developer blocked “| ” but not “|”, demonstrating that blacklists fail because attackers read the exact code the blacklist lives in. The Impossible comparison in Step 6 explains why: whitelist validation rejects anything that is not a valid IP address before it ever reaches the shell command, making the metacharacter question irrelevant. That is what goes in the remediation section of a professional report.
📸 Screenshot your High-level bypass output showing command execution. Share in #dvwa-labs on Discord.
File Inclusion Source Review — Path Traversal in PHP
File inclusion vulnerabilities in PHP come from the include() or require() functions accepting user input as the filename. The Low source shows the most dangerous version — raw include with no validation. The source review tells you whether the application is vulnerable to Local File Inclusion only (LFI) or also Remote File Inclusion (RFI), which depends entirely on the PHP configuration and what the code does with the input.
DVWA FILE INCLUSION — SOURCE REVIEW ALL LEVELS
# ── LOW: Direct include — both LFI and RFI possible ────────────
Only four specific filenames accepted — no traversal or inclusion possible
⚡ EXERCISE 3 — KALI TERMINAL (20 MIN)
Complete Source Review Across All Four Vulnerability Classes
⏱️ 20 minutes · DVWA running locally
This exercise builds your source review pattern recognition across all four DVWA vulnerability classes. You will read source, classify the vulnerability type, identify the specific flaw, and write the remediation — the exact output that goes into a professional pentest report’s findings section.
Step 1: Open DVWA and set security to Low.
For each of the four modules below, click View Source and fill in
the Source Review Worksheet:
MODULE: SQL Injection
Vulnerable function/pattern: ___________
Input variable and source ($_GET/$_POST): ___________
Query structure: ___________
Payload that will work based on source alone: ___________
Impossible-level fix (one sentence): ___________
MODULE: XSS Reflected
Output context (HTML/attribute/script): ___________
Encoding function missing: ___________
Payload that will work: ___________
Impossible-level fix (one sentence): ___________
MODULE: File Inclusion
PHP include function: ___________
LFI payload for /etc/passwd: ___________
Is RFI possible? Why/why not from source: ___________
Impossible-level fix (one sentence): ___________
Step 2: Compare your answers for each “Impossible-level fix” sentence
to what the Impossible source actually implements.
How close were you? What did you miss?
Step 3: Write a three-sentence executive summary that explains
why Low security has critical vulnerabilities using language
a non-technical stakeholder would understand.
Avoid jargon: no “SQLi”, no “concatenation”, no “sanitisation”.
✅ The Source Review Worksheet from this exercise is the foundation of every technical finding in a white-box assessment report. The four patterns you identified — concatenated queries, unencoded output, shell passthrough, and raw include — are the same patterns you will search for in real PHP codebases on professional engagements. The Step 3 executive summary exercise is the hardest part: explaining a prepared statement vs concatenation without using the word “injection” to a CFO is the communication skill that makes the difference between a technically correct report and a persuasive one.
📸 Screenshot your completed Source Review Worksheet. Share in #dvwa-labs on Discord. Tag #lab27complete
The difference between a good pentest finding and a great one is the remediation section. A generic finding says “use parameterised queries.” A source-informed finding says “the vulnerable query on line 47 of /dvwa/vulnerabilities/sqli/source/low.php concatenates $id directly into the query string — replace this with a PDO prepared statement as implemented in the Impossible security level.” The second version tells the developer exactly what to change and shows them the correct implementation.
DVWA’s Impossible level is the remediation reference. For every finding in Lab 28, I will expect you to cite the Impossible source as the model for the fix. Reading it here in Lab 27 means you already have the language ready for the report.
📋 DVWA Source Review — Lab 27 Reference Card
View source buttonBottom of every DVWA page → opens PHP for current level
Compare all levelsShows Low / Medium / High / Impossible side by side
SQLi vulnerable pattern$query = “… WHERE id = ‘$id’;” — variable in string
SQLi secure pattern$stmt = $db->prepare(“… WHERE id = ?”); bind_param()
XSS vulnerable patternecho … $name … — no htmlspecialchars
SQL injection, XSS, command injection, and file inclusion source patterns across all four DVWA security levels — vulnerable to secure. Medium and High bypass methodology derived directly from the blacklist code. Impossible-level fix language ready for the report. Lab 28 is the final exercise: the complete penetration test report documenting everything from Lab 1 through Lab 27 in a professional deliverable format.
🧠 Lab 27 Check
DVWA Command Injection at Medium security uses str_replace to remove ‘&&’ and ‘;’ from the input. You review the source and notice the pipe character ‘|’ is not in the blacklist. What payload do you submit and what does this demonstrate about blacklist-based input validation?
Source code review (white-box testing) is analysing application source code to identify security vulnerabilities before or alongside exploitation. Unlike black-box testing where you discover vulnerabilities by probing, source code review lets you read exactly how the application processes input — making vulnerability identification faster and exploit construction more precise.
How do you view source code in DVWA?
Every DVWA module has a View Source button at the bottom of the page. It shows the PHP source code for the current security level. The Compare All Levels button shows Low, Medium, High, and Impossible side by side — allowing direct comparison of what controls each level adds and whether those controls are sufficient or bypassable.
What makes PHP code vulnerable to SQL injection?
PHP code is vulnerable when user-supplied input is concatenated directly into SQL query strings without parameterisation. The vulnerable pattern: $query = “SELECT * FROM users WHERE id = ” . $_GET[‘id’]. The secure pattern uses prepared statements: $stmt = $pdo->prepare(“SELECT * FROM users WHERE id = ?”); $stmt->execute([$_GET[‘id’]]).
What is the difference between Low, Medium, and High security in DVWA?
Low has no input validation — raw user input goes directly into queries and commands. Medium adds partial protections like basic escaping or blacklisting specific characters — these are consistently bypassable by reading what is not blocked. High applies more complete blacklists but still has logical gaps. Impossible implements correct secure coding: parameterised queries, strict whitelist validation, and htmlspecialchars output encoding.
Why should pentesters review source code before exploiting?
Reading source tells you what the input is used for, what validation exists, and what payload will work on the first attempt. On a timed engagement, source code review is the most efficient path from potential vulnerability to confirmed exploit. The source also directly informs the remediation section — you can cite the exact vulnerable line and the exact fix rather than writing generic recommendations.
How does DVWA source code review prepare you for real engagements?
DVWA source review builds pattern recognition that transfers directly to real PHP codebases. Concatenated queries, unescaped output, unsanitised shell commands, and raw file includes appear in real applications. When you see those patterns in a production codebase during a white-box assessment, you recognise them immediately because you have read the same patterns in DVWA dozens of times.
← Previous
Lab 26 — Authentication Bypass
Next →
Lab 28 — Pentest Report
📚 Further Reading
DVWA SQL Injection Lab— The exploitation side of what you just reviewed — combining exploit knowledge with source code understanding produces the most precise SQL injection methodology.
DVWA Command Injection Lab— The original command injection exploitation lab — revisit after Lab 27 to see how source review changes how you approach the bypass methodology.
DVWA Lab Setup Guide 2026— Complete DVWA installation and configuration guide — required reading if your DVWA instance is not currently running.
OWASP Code Review Guide— The industry standard methodology for security-focused source code review — covers PHP, Java, .NET and the full taxonomy of code-level vulnerability patterns.
DVWA GitHub Repository— Official DVWA source code — reading the complete PHP files for each vulnerability module gives you the full picture beyond what the View Source button shows.
ME
Mr Elite
Owner, SecurityElites.com
The eleven-minute source review that found three critical SQL injection points — I still have the screenshots. The client’s codebase was not obfuscated, not minified, not compiled. It was plain PHP with $_GET variables going into query strings. The developers were not incompetent — they had written what they knew, which did not include prepared statements. DVWA’s Impossible level shows the exact change that would have prevented all three findings. That is why Lab 27 exists: not to make you a PHP developer, but to make you the kind of security professional who can point at the specific line, explain why it is vulnerable, and show the developer what to replace it with.