DEV Community

Cover image for Lab14: DVWA Security Levels Explained 2026 — Low, Medium, High & Impossible Complete Guide
Mr Elite
Mr Elite

Posted on • Originally published at securityelites.com

Lab14: DVWA Security Levels Explained 2026 — Low, Medium, High & Impossible Complete Guide

Lab14: DVWA Security Levels Explained 2026 — Low, Medium, High & Impossible Complete Guide

🧪 DVWA LAB SERIES FREE Part of the DVWA Lab Series — 30 Labs Lab 14 of 30 · 46.7% complete DVWA security levels explained 2026 — after completing 13 DVWA labs you have seen the attack techniques. Lab 14 is different: instead of exploiting a vulnerability, you are reading the PHP source code at each security level to understand exactly what changes between Low and Impossible, and why those changes close the vulnerabilities you have been exploiting. This is the lab that transforms you from someone who can run attacks into someone who can explain to developers precisely what code changes would have prevented them. That is the difference between a script-kiddie and a professional penetration tester. 🎯 What You'll Learn in Lab 14 Understand exactly what each DVWA security level changes in the PHP source code Use View Source effectively to analyse vulnerability root causes and fixes Compare Low vs Impossible implementations of SQL injection, XSS, and CSRF defences Identify which defences are bypassable (Medium) and which are genuinely secure (Impossible) Write technical recommendations based on source code analysis ⏱️ 40 min · 3 source code analysis exercises ✅ Prerequisites DVWA Labs 1–13 completed (or working knowledge of each vulnerability type) DVWA running locally with PHP source accessible via View Source Basic PHP reading ability (you do not need to write PHP — just read logic) 📋 Lab 14 Contents — DVWA Security Levels Explained What Each Security Level Actually Changes SQL Injection — Low vs Impossible Source Comparison XSS — How Each Level Tries (and Sometimes Fails) to Filter Output CSRF and Brute Force — Token and Lockout Implementation Impossible Security Patterns — The Code Standards Worth Memorising In Lab 13 you saw a logic flaw in CAPTCHA implementation. Lab 14 zooms out to view the entire DVWA security framework — understanding how defences are layered, why some fail, and what genuine security looks like in code. This knowledge is directly applicable to the remaining 16 DVWA labs and to writing remediation recommendations in real penetration test reports. What Each Security Level Actually Changes securityelites.com DVWA Security Level Comparison — What Changes LOW No input validation · No prepared statements · Raw string concatenation in SQL · No output encoding · No CSRF tokens · No lockout · No logging MEDIUM mysql_real_escape_string() (bypassable with techniques like UNION) · Basic strip_tags() · Some input length limits · Partial blacklist filtering (easily bypassed) · Still vulnerable to most attacks with minor modifications HIGH PDO prepared statements (no SQL injection) · htmlspecialchars() on output (prevents XSS) · CSRF tokens (prevents CSRF) · Server-side reCAPTCHA verification · Stricter input validation · Still some academic bypasses in edge cases IMPOSSIBLE PDO + parameterised queries · htmlspecialchars ENT_QUOTES · Anti-CSRF token + session binding · Rate limiting + account lockout + logging · Minimum password length enforcement · All user input treated as untrusted 📸 DVWA security level comparison — Low removes all defences to demonstrate pure vulnerability; Medium adds partial (bypassable) defences; High implements strong defences; Impossible implements security best practices. SQL Injection — Low vs Impossible Source Comparison ⚡ EXERCISE 1 — DVWA SOURCE CODE ANALYSIS (15 MIN) Compare SQL Injection Source Code Across All Four Security Levels ⏱️ Time: 15 minutes · DVWA running · navigate to SQL Injection module SQL INJECTION SOURCE CODE — LEVEL COMPARISONCopy ═══ LOW SECURITY — Pure vulnerability ═══ $id = $GET[ 'id' ]; $query = "SELECT first_name, last_name FROM users WHERE user_id = '$id';"; // $id goes directly into the query — any SQL injected immediately executes ═══ MEDIUM SECURITY — Partial defence ═══ $id = $_POST[ 'id' ]; $id = mysqli_real_escape_string($GLOBALS["__mysqli_ston"], $id); $query = "SELECT first_name, last_name FROM users WHERE user_id = $id;"; // Note: integer ID not quoted — UNION injection still works without quotes ═══ HIGH SECURITY — Strong defence ═══ $id = $_SESSION['id']; $query = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;"; // LIMIT 1 prevents some multi-row UNION attacks; id from session not GET/POST ═══ IMPOSSIBLE SECURITY — Best practice ═══ $data = $db->prepare('SELECT first_name, last_name FROM users WHERE user_id = (:id) LIMIT 1;'); $data->bindParam(':id', $id, PDO::PARAM_INT); $data->execute(); // PDO prepared statement — $id is NEVER part of the SQL string itself // Even if $id = "1' OR '1'='1", it is treated as a literal value, not SQL ✅ What you just learned: The progression from raw string concatenation (Low) to parameterised queries (Impossible) illustrates the only reliable SQL injection defence. Medium's mysql_real_escape_string is often cited as a mitigation but it is context-dependent and can be bypassed with integer injection when the field is unquoted. High's LIMIT 1 helps but the id is still from user-session which in some configurations is user-controlled. Only Impossible's PDO prepared statement with PARAM_INT type binding provides a complete


Originally published on SecurityElites

Top comments (0)