Lab: DVWA Walkthrough
This comprehensive lab walks through every vulnerability module in DVWA at all three security levels — Low, Medium, and High — to show how defenses evolve and how attackers adapt. You will see firsthand how adding input validation, CSRF tokens, and prepared statements changes the attack surface. Completing DVWA at all security levels is a rite of passage for web application security students.
Learning Objectives — Deep Dive
Each objective below is broken down into plain English so you know exactly what you are learning, why it matters, and what you will be able to do when you are done. Mark each one complete as you work through the lesson.
Set up DVWA
Ensure DVWA is running and accessible with the security level set to Low. Navigate to the SQL Injection module and familiarize yourself with the interface — it accepts a User ID and returns the corresponding user's first and last name from the database. Open Burp Suite and configure your browser to proxy through it so you can capture and replay requests. Also open a second browser tab with the DVWA source code viewer (click 'View Source' in the DVWA module) so you can compare your attack results against the actual PHP code.
Complete SQL Injection at Low security
With security set to Low, test the User ID field with a single quote to trigger a SQL error, then use '1 UNION SELECT user, password FROM users--' to extract credentials. Read the Low security source code and confirm that the query is built by direct string concatenation with no sanitization: '$query = "SELECT first_name, last_name FROM users WHERE user_id = $id";'. Understanding the vulnerable code pattern is as important as exploiting it — you need to recognize this pattern in real code reviews. Document the exact payload, the response, and the source code line that caused the vulnerability.
Read the Low security source code
Click 'View Source' in the DVWA SQL Injection module with security set to Low and study the PHP code carefully. Identify the exact line where user input is concatenated into the SQL query without any sanitization or parameterization. Compare this against the Medium and High security source code to understand the progression of defenses. The Low code is a textbook example of what never to do — it is the pattern you will look for in code reviews and source code analysis during real penetration tests. Understanding the root cause (string concatenation instead of parameterized queries) is essential for writing accurate remediation recommendations.
Complete SQL Injection at Medium security
Change the DVWA security level to Medium and return to the SQL Injection module. The Medium level uses mysql_real_escape_string() to escape special characters, and the input is now a dropdown instead of a free text field. Bypass the dropdown restriction by intercepting the POST request in Burp Suite and manually editing the id parameter to inject your payload. The mysql_real_escape_string() function escapes quotes, but a UNION-based injection using numeric values (1 UNION SELECT user,password FROM users) does not require quotes and will still work. This demonstrates that input validation at the UI layer is not a substitute for parameterized queries.
Complete SQL Injection at High security
Change the DVWA security level to High and test the SQL Injection module. The High level uses a separate session-based input mechanism and adds a LIMIT 1 clause to the query. Bypass the LIMIT clause by appending a comment (--) after your UNION payload to ignore the rest of the original query. The High level also randomizes the number of columns, requiring you to determine the correct column count before constructing your UNION payload. Successfully exploiting the High level demonstrates that even applications with multiple layers of partial defenses can be vulnerable when the fundamental fix (parameterized queries) is not applied.