This lab teaches SQL injection techniques that defeat high-security defenses, focusing on cookie-based injection, second-order injection, and time-based blind techniques against DVWA's High security mode. The article explains why mysql_real_escape_string() fails to protect all code paths and demonstrates how sanitization at insertion does not guarantee safety at retrieval. Mastering these techniques is critical because real applications commonly miss alternative injection channels and reuse database values in subsequent queries without parameterization.
- Cookie injection bypasses sanitized parametersDVWA High reads the user ID from a PHP session cookie rather than URL parameters, then passes it unsanitized through a different code path to the SQL query. An attacker can modify the cookie value directly in Burp Suite (e.g., id=1' UNION SELECT user,password FROM users-- -) before the server processes it, bypassing the sanitization applied to form inputs. This demonstrates that sanitization on one input pathway does not automatically protect when the same data arrives through an alternative channel.
- Second-order injection exploits gaps between operationsSecond-order SQL injection stores a malicious payload safely in the database during insertion (because sanitization works at that point), then retrieves and reuses that stored value in a later query without re-sanitizing. The DVWA example registers a username as admin'-- -, which is stored safely with escaped quotes, but when an UPDATE query retrieves that username and concatenates it into the WHERE clause, the literal quote executes and the comment removes the limiting condition, changing all users' passwords instead of one. This pattern occurs whenever retrieved database values are concatena
- mysql_real_escape_string() function and its limitsmysql_real_escape_string() escapes single quotes, double quotes, backslashes, null bytes, carriage returns, and line feeds so that 1' OR '1'='1 becomes 1' OR '1'='1, preventing injection through that specific path. However, the function only protects input paths where it is explicitly applied; if called on URL parameters but not cookies or headers, alternative injection paths remain open. Additionally, it offers no protection for second-order injection because the sanitized data is stored and then used in later queries where no sanitization is applied.
- Time-based blind confirms vulnerability without outputTime-based blind SQL injection uses AND SLEEP(5) or similar database delays to confirm vulnerability when no visible results or error messages are displayed. If a query response takes approximately 5 seconds after injecting this payload, the database executed the injection, proving vulnerability. More granularly, conditional sleep queries like IF(SUBSTRING(database(),1,1)='d',SLEEP(5),0) extract data character by character by measuring response delays—a 5-second delay indicates the first character is 'd', allowing complete data reconstruction despite no direct output.
- sqlmap configuration for high-security injection pointssqlmap by default does not test cookie parameters; reaching DVWA High injection requires --level=2 to include cookies and HTTP headers in scanning scope, --risk=2 for more aggressive test cases, and marking the injection point with an asterisk (id=1*) to specify the exact parameter location. The --technique=T flag limits testing to time-based blind methods when output-based extraction is unavailable. This configuration difference reflects that high-security defenses alter which extraction techniques remain available, not whether injection itself is possible.
- Parameterized queries required at every SQL callParameterized queries separate SQL structure from data values so that user-controlled content can never alter query syntax, regardless of content. The critical principle is that this protection must apply at the point of SQL execution, not just user input—both INSERT and UPDATE statements in the code must use parameterized syntax. The DVWA second-order vulnerability exists precisely because the INSERT was correctly parameterized but the UPDATE concatenated the retrieved username. Even data retrieved from the database must be treated as untrusted if it originated from any user-controlled input,
- Architectural trust of database values is incorrectA common developer misconception is that data stored in the database is inherently safe to use in subsequent queries without parameterization or validation. The article emphasizes that an attacker controls database contents at registration or initial insertion time—if that input was stored safely through sanitization rather than parameterization, the stored value still contains the injected payload and becomes an injection vector when retrieved and concatenated into later queries. The database is a transport mechanism, not a sanitization boundary.
Bottom line: SQL injection at high security requires exploiting alternative injection paths (cookies, headers) and gaps between sanitization points (second-order injection), but all variants stem from concatenating user-controlled data into SQL queries and are prevented only by parameterized queries applied at every SQL call, not by sanitization of individual input channels. Developers must treat database-retrieved values as untrusted and parameterize every query that uses any variable data, regardless of it
FREE
Part of the DVWA Lab Series — 30 Labs
' payloads, WAF-like filtering removes obvious keywords, and the application’s SQL logic is restructured to reduce direct injection surfaces. This lab teaches the techniques that work when the obvious paths are closed: second-order injection that stores and later executes payloads, blind injection that confirms vulnerabilities through timing and boolean responses when direct output is suppressed, and the cookie-based injection path specific to DVWA High that demonstrates how sanitisation in one code path can miss another.🎯 What You’ll Master in Lab 21
⏱️ 55 min lab · 3 terminal exercises · Localhost DVWA only
📋 Prerequisites — Complete Before Lab 21
- Lab 7: DVWA SQL Injection Low/Medium — foundational SQL injection payloads and UNION-based extraction; Lab 21 builds directly on this
- Lab 20: DVWA CSRF Advanced — cross-layer vulnerability chaining context; Lab 21’s second-order injection shows the same stored-then-triggered pattern
📋 DVWA SQL Injection High Security 2026
- Why High Security Is Different — What mysql_real_escape_string() Does
- The Cookie-Based Injection Path in DVWA High
- Second-Order SQL Injection — Store, Retrieve, Execute
- Time-Based Blind Injection — Confirm When Output Is Gone
- Using sqlmap at High Security Level
- What Properly Fixes SQL Injection — Parameterised Queries
Why High Security Is Different — What mysql_real_escape_string() Does
DVWA Low security concatenates user input directly into the SQL query with no filtering whatsoever. Medium security applies basic filtering but using methods that can be bypassed. High security uses PHP’s mysql_real_escape_string() function to sanitise input before it reaches the query. This function escapes the characters that SQL injection depends on: single quotes, double quotes, backslashes, null bytes, carriage returns, and line feeds. A payload like 1' OR '1'='1 becomes 1\' OR \'1\'=\'1 after escaping — the escaped quotes cannot close the SQL string context, so the injection fails.
For most input paths, mysql_real_escape_string() is effective when used correctly. The DVWA High security implementation has a specific architectural decision that creates an alternative injection path: rather than using the URL parameter directly, the application stores the user ID in a PHP session cookie and reads the SQL query parameter from that cookie. The session storage and retrieval introduces a path where the value is used without consistent sanitisation — this is the bypass specific to DVWA High.
$query = “SELECT … WHERE
user_id = ‘$id'”;
// $id goes in raw — injectable
$id = mysql_real_escape_string($id);
$query = “SELECT … WHERE
user_id = ‘$id'”;
// Read from COOKIE not GET!
The Cookie-Based Injection Path in DVWA High
DVWA High security’s SQL injection page reads the user ID from a PHP session cookie named id. When you submit the form by clicking “Submit”, the value you entered is stored in this cookie, and the page then reads that cookie value to run the SQL query. The sanitisation applies to the form input at submission time. However, between form submission and the SQL query execution, the value passes through the cookie — and if you intercept and modify the cookie directly in Burp Suite before the query runs, you can inject into the cookie value without going through the sanitised form input path.
⏱️ 20 minutes · Kali + DVWA + Burp Suite
📸 Screenshot the Burp intercept showing cookie modification and the user/password output. Post to #lab-21-sqli-high on Discord.
Second-Order SQL Injection — Store, Retrieve, Execute
Second-order SQL injection (also called stored SQL injection) is the most conceptually advanced variant in this lab series. It exploits the gap between two separate operations: input sanitisation at insertion time and input usage at retrieval time. A common scenario: a registration form sanitises a username correctly — the SQL INSERT statement is safe, no injection occurs. The sanitised username is stored in the database as-is, including any SQL characters that were escaped at insert time. Later, the application retrieves that username and uses it in another SQL query — a profile update, an audit log query, or a report — without re-sanitising, because the developer assumes data from the database is already safe. The payload stored safely executes at retrieval.
In DVWA’s context, this pattern appears in the Change Password functionality. If a username like admin'-- - is registered (successfully, because the INSERT sanitises it), and then used in a later UPDATE or SELECT query without sanitisation, the stored value becomes an injection vector. The practical exploitation in DVWA High demonstrates this by registering a specially crafted account name and then triggering the vulnerable retrieval operation.
mysql_real_escape_string() applied: admin\’– –
INSERT INTO users (username) VALUES (‘admin\’– -‘);
✓ Stored safely as: admin’– – (literal quote in DB)
// Returns: admin’– – (literal, unsanitised)
$query = “UPDATE users SET pass=’$pass’ WHERE username=’$username'”;
// Becomes: WHERE username=’admin’– -‘
✗ INJECTED: comment truncates WHERE clause, updates ALL users
⏱️ 20 minutes · Kali + DVWA + Burp Suite
📸 Screenshot the admin login confirmation after the second-order injection changed their password. Post to #lab-21-sqli-high on Discord.
Time-Based Blind Injection — Confirm When Output Is Gone
Blind SQL injection is used when the application doesn’t display query results — no UNION SELECT output, no error messages, just a generic response. Time-based blind injection confirms a vulnerability by causing the database to sleep for a measurable duration when a condition is true. If the query pauses for 5 seconds after injecting AND SLEEP(5), the database executed the injection — proving vulnerability even with no visible output.
Using sqlmap at High Security Level
sqlmap needs extra configuration flags to test DVWA High security effectively. The default scan level may not test cookie parameters. Use --level=2 (or higher) to include cookies and HTTP headers, --risk=2 to include more aggressive tests, and explicitly specify the cookie string with the injection parameter via -p id to tell sqlmap which parameter to target.
⏱️ 15 minutes · Kali + DVWA
📸 Screenshot sqlmap’s output showing the technique used and the dumped credentials. Post to #lab-21-sqli-high on Discord. Tag #lab21-complete
What Properly Fixes SQL Injection — Parameterised Queries
Every SQL injection variant covered in this lab — direct injection, second-order, time-based blind, cookie-based — has the same root cause: user-controlled data is concatenated into SQL queries as a string. The fix for all variants is the same: parameterised queries (prepared statements). The SQL structure is defined separately from data values, and the database driver ensures data values can never alter the query structure regardless of what they contain.
The critical implication for second-order injection: parameterised queries must be applied at the point of SQL query execution, not just at the point of user input. The DVWA second-order vulnerability exists because the UPDATE query concatenates a retrieved username. The data came from the database — but that does not make it safe, because an attacker controlled its contents at registration time. The rule is absolute: every SQL query that uses any variable value — regardless of origin, even if retrieved from your own database — must use parameterised queries.
$q = “INSERT INTO users (user)
VALUES (‘$user’)”;
// Retrieve and re-use
$u = get_user_from_db();
$q = “UPDATE SET pass=’$p’
WHERE user=’$u'”;
Both queries concatenate — both injectable
$s=$pdo->prepare(“INSERT INTO
users (user) VALUES (?)”);
$s->execute([$user]);
// Retrieve and re-use
$u = get_user_from_db();
$s=$pdo->prepare(“UPDATE SET
pass=? WHERE user=?”);
$s->execute([$p,$u]);
🧠 QUICK CHECK — DVWA SQL Injection High
📋 Lab 21 Key Concepts — SQL Injection High Security
🏆 Mark Lab 21 Complete — DVWA SQL Injection High Security
Lab 21 demonstrated how sanitisation on one code path leaves other paths vulnerable, and how second-order injection exploits the gap between insert and retrieval. Lab 22 chains multiple vulnerabilities together for the highest-impact attack sequence in the course.
❓ Frequently Asked Questions — DVWA SQL Injection High 2026
What makes DVWA SQL injection high security different?
What is second-order SQL injection?
How do you bypass mysql_real_escape_string()?
What is the DVWA High SQL injection bypass?
How does time-based blind SQL injection work?
What properly fixes SQL injection?
Lab 20: DVWA CSRF Advanced
Lab 22: DVWA Vulnerability Chaining
📚 Further Reading
- DVWA SQL Injection Lab (Low/Medium) — The foundational UNION-based and error-based SQL injection techniques that Lab 21 builds on — complete this before attempting High security.
- Lab 22: DVWA Vulnerability Chaining — Lab 22 chains SQLi, XSS, and file upload vulnerabilities for the highest-impact combined attack in the course series.
- DVWA Lab Series Hub — Full 30-lab course overview — Lab 21 is the second to last security-escalation challenge before the final chaining lab.
- PortSwigger — SQL Injection Complete Guide — PortSwigger’s comprehensive SQL injection reference including blind injection, second-order, and out-of-band techniques with guided labs.

