If you need a vulnerable web application for security testing — whether you’re benchmarking a SAST or DAST scanner, learning how web vulnerabilities work, or preparing for a certification — this guide gets you up and running in under two minutes.
Every application in this guide is free, open-source, and designed to be attacked legally. You can reset each one to its original state by restarting the Docker container. None of them require paid licenses or cloud accounts.
Which Vulnerable Web Application Should You Use?
The right choice depends on what you need to test:
| Goal | Best Application | Setup Time |
|---|---|---|
| DAST scanner benchmarking | OWASP Juice Shop | < 60 seconds |
| PHP SAST benchmarking | DVWA | < 60 seconds |
| Java SAST benchmarking | WebGoat | < 60 seconds |
| Maximum vulnerability breadth | bWAPP | ~2 minutes |
| Node.js / Express SAST | NodeGoat | ~3 minutes |
| Learning OWASP Top 10 (all levels) | DVWA or Juice Shop | < 60 seconds |
| Enterprise application simulation | AltoroJ | ~5 minutes |
For most teams, the answer is OWASP Juice Shop for DAST testing and DVWA for PHP SAST benchmarking. Start with one of those.
OWASP Juice Shop — Best for DAST Testing
OWASP Juice Shop is the most realistic deliberately vulnerable web application available. It is a modern Node.js/Angular e-commerce application with over 100 security challenges covering every OWASP Top 10 category.
Why Juice Shop for DAST testing:
- Realistic SPA + REST API architecture matching how modern web apps are built
- Authenticated endpoints behind JWT — critical for testing authenticated scanning
- File upload, admin panel, user management — comprehensive attack surface
- Industry-standard benchmark used by enterprise DAST tool vendors
Setup (< 60 seconds)
docker run --rm -p 3000:3000 bkimminich/juice-shop
Open your browser at http://localhost:3000/. The application is fully operational — complete with product catalog, shopping cart, user registration, and a REST API.
Access the challenge scoreboard:
http://localhost:3000/#/score-board
The scoreboard lists all 100+ challenges organized by difficulty and category. Finding the scoreboard is itself the first challenge — it is not linked from the navigation.
Save progress between sessions:
# Detached mode — keeps running after you close the terminal
docker run -d -p 3000:3000 --name juice-shop bkimminich/juice-shop
# Stop when done
docker stop juice-shop
# Restart later (challenge progress preserved)
docker start juice-shop
# Full reset (wipes all progress)
docker stop juice-shop && docker rm juice-shop
docker run -d -p 3000:3000 --name juice-shop bkimminich/juice-shop
Configuring a DAST Scanner Against Juice Shop
For meaningful DAST scanner benchmarking, configure authenticated scanning. An unauthenticated scan only covers approximately 20% of Juice Shop’s attack surface — the public product pages and login form.
- Start Juice Shop and navigate to
http://localhost:3000/#/register - Create a test account (e.g.,
[email protected]/Scanner123!) - Configure your DAST scanner to authenticate with those credentials before scanning
- Target:
http://localhost:3000/
What a production-ready DAST scanner must find in Juice Shop:
| Vulnerability | Location | CVSS Category |
|---|---|---|
| SQL injection | Login form (/rest/user/login) | Critical |
| Reflected XSS | Product search bar | High |
| Missing Content-Security-Policy | All pages | Medium |
| Directory listing | /ftp/ | Medium |
| CORS misconfiguration | API endpoints | Medium |
| Sensitive file exposure | /ftp/acquisitions.md | High |
If your DAST scanner does not find the SQL injection in the login form — the most unambiguous SQL injection test case that exists — it is not ready for production deployment.
DVWA — Best for PHP SAST Benchmarking
DVWA (Damn Vulnerable Web Application) is a PHP/MySQL application built specifically for security testing practice. Every vulnerability page exposes the source code and provides three difficulty levels (Low, Medium, High), making it ideal for both learners and security tool developers.
Why DVWA for SAST benchmarking:
- PHP source code available directly in the application UI
- Three difficulty levels per vulnerability: unobfuscated → partially obfuscated → near-secure
- Clean separation between vulnerable and safe code patterns
- Standard benchmark for PHP SAST tool evaluation
Setup (< 60 seconds)
docker run --rm -it -p 80:80 vulnerables/web-dvwa
Open http://localhost/ in your browser. Before your first login, click “Create / Reset Database” on the setup page.
Default credentials: admin / password
After logging in, go to DVWA Security in the left menu and set the difficulty to Low to start with the completely unobfuscated versions of each vulnerability.
DVWA Vulnerability Categories
| Category | What It Tests |
|---|---|
| SQL Injection | $_GET parameter directly in SQL query |
| SQL Injection (Blind) | Boolean-based and time-based blind injection |
| Command Injection | User input in shell_exec() |
| XSS (Reflected) | User input echoed without encoding |
| XSS (Stored) | User input saved to DB and rendered for others |
| CSRF | State-changing form without anti-CSRF token |
| File Inclusion | LFI and RFI via unvalidated file path parameter |
| File Upload | Unrestricted file upload with no type validation |
| Brute Force | Login form with no rate limiting |
| Weak Session IDs | Predictable session token generation |
DVWA SAST Benchmarking Procedure
- Clone the DVWA source code:
git clone https://github.com/digininja/DVWA.git - Point your SAST scanner at the source directory
- Verify it flags the SQL injection in
vulnerabilities/sqli/source/low.php - Check Medium difficulty — the same vulnerability with basic obfuscation
- Verify it does NOT flag High difficulty (which uses parameterized queries) as a false positive
// low.php — completely unobfuscated SQL injection
$id = $_GET['id'];
$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id'";
A SAST tool that misses this is not suitable for security scanning of PHP production code.
WebGoat — Best for Java SAST Benchmarking
WebGoat is OWASP’s Java/Spring deliberately vulnerable application. Each vulnerability comes with a lesson format — explanation, attack, and a practical exercise that requires successful exploitation before advancing.
Why WebGoat for Java SAST:
- Spring MVC architecture matching typical Java web applications
- Java-specific vulnerability classes (insecure deserialization, JDBC template injection)
- Source code on GitHub for SAST benchmarking
- Structured lessons ideal for developer security training
Setup
docker run -it -p 8080:8080 -p 9090:9090 webgoat/webgoat
Open http://localhost:8080/WebGoat and register a new account.
Key vulnerability categories in WebGoat:
- SQL Injection (including second-order injection and order-by injection)
- Java insecure deserialization (
ObjectInputStream) - JWT attacks (algorithm confusion, key leakage)
- XML External Entities (XXE)
- SSRF
- Path traversal
- Access control violations (IDOR, forced browsing)
bWAPP — For Maximum Vulnerability Coverage
bWAPP (Buggy Web Application) covers 100+ vulnerability types — more than any other single deliberately vulnerable application. It extends well beyond the OWASP Top 10 to include LDAP injection, SMTP injection, SSRF, HTML5 WebSocket attacks, and simulated classic vulnerabilities (Heartbleed, Shellshock).
Setup
docker run -d -p 80:80 raesene/bwapp
First visit: http://localhost/bWAPP/install.php (one-time setup)
Then: http://localhost/bWAPP/login.php
Default credentials: bee / bug
Best use case: Verifying that your SAST or DAST scanner’s rule coverage extends beyond the standard OWASP headline categories. bWAPP’s breadth is unmatched for comprehensive scanner coverage testing.
NodeGoat — For Node.js / Express SAST Benchmarking
NodeGoat is OWASP’s deliberately vulnerable Node.js/Express application. It covers Node.js-specific vulnerability patterns that don’t exist in PHP or Java applications.
Setup
git clone https://github.com/OWASP/NodeGoat
cd NodeGoat
npm install
docker-compose up
Open http://localhost:4000/ — default credentials: admin / Admin_123
Node.js-specific vulnerabilities in NodeGoat:
- NoSQL injection (MongoDB
$whereand operator injection) - Server-side JavaScript injection (
eval()misuse) - Prototype pollution
- Insecure Express session configuration (
cookie.secure: false,httpOnly: false) - Missing HTTP security headers
- Vulnerable npm dependencies
AltoroJ — Enterprise Banking Application Simulation
AltoroJ (Altoro Mutual) is a vulnerable Java/JSP banking application maintained by IBM for security tool testing. Its banking context — account transfers, transaction history, user management — provides a more realistic business application simulation than tutorial-style apps.
Setup
git clone https://github.com/AppSecDev/AltoroMutual
cd AltoroMutual
mvn package
java -jar target/altoromutual.war
Open http://localhost:8080/ — default credentials: admin / admin
Best for: Enterprise DAST tool benchmarking, demonstrating authenticated workflow testing to stakeholders, and validating scanner effectiveness in a business application context.
Running Multiple Applications Simultaneously
For comprehensive scanner benchmarking, run multiple applications at the same time using different ports:
# Juice Shop for DAST benchmarking
docker run -d -p 3000:3000 --name juice-shop bkimminich/juice-shop
# DVWA for PHP SAST/DAST
docker run -d -p 3001:80 --name dvwa vulnerables/web-dvwa
# WebGoat for Java SAST/DAST
docker run -d -p 3002:8080 --name webgoat webgoat/webgoat
# bWAPP for breadth coverage
docker run -d -p 3003:80 --name bwapp raesene/bwapp
Each application runs independently at its own port. Your DAST scanner can target each one in turn and you can compare which vulnerability classes it detects across different technology stacks.
What to Verify Your Scanner Finds
Use this cross-application checklist to validate your SAST or DAST scanner before deploying it on production code:
DAST Verification Checklist (Juice Shop)
- SQL injection in login form (
/rest/user/login—' OR '1'='1'--) - Reflected XSS in product search
- Directory listing at
/ftp/ - Sensitive file exposure (
/ftp/acquisitions.mdaccessible without auth) - Missing
Content-Security-Policyheader on all pages - Missing
X-Content-Type-Optionsheader - CORS policy review (
Access-Control-Allow-Originscope) - After authenticated scan: IDOR on basket API (
/api/BasketItems/1) - After authenticated scan: Stored XSS in product reviews
SAST Verification Checklist (DVWA Source Code)
- SQL injection in
vulnerabilities/sqli/source/low.php(line 4:$_GET['id']concatenated) - Command injection in
vulnerabilities/exec/source/low.php - Reflected XSS in
vulnerabilities/xss_r/source/low.php - Stored XSS in
vulnerabilities/xss_s/source/low.php - No false positive on
vulnerabilities/sqli/source/high.php(uses parameterized query)
A scanner that fails any item on these checklists requires tuning or replacement before it can provide meaningful coverage of production applications.
Common Setup Issues and Fixes
Port Already in Use
# Check what is using the port
lsof -i :3000 # macOS/Linux
netstat -ano | findstr :3000 # Windows
# Use a different port
docker run --rm -p 3001:3000 bkimminich/juice-shop
# Then access at http://localhost:3001/
Docker Not Installed
If Docker is not available, most applications can run directly from source:
Juice Shop (Node.js required, v18+):
git clone https://github.com/juice-shop/juice-shop.git
cd juice-shop && npm install && npm start
WebGoat (Java 17+ required):
# Download the latest release JAR
java -jar webgoat-2023.8.jar --server.port=8080
Apple Silicon Mac (M1/M2/M3)
All applications listed here support ARM64. On Apple Silicon with Docker Desktop:
docker run --rm -p 3000:3000 bkimminich/juice-shop
# Works natively — no special flags needed
If an older image only supports AMD64, add --platform linux/amd64 (runs via Rosetta emulation):
docker run --rm --platform linux/amd64 -p 80:80 vulnerables/web-dvwa
Deliberately Vulnerable Apps vs. Real Application Testing
Vulnerable web applications are the right place to calibrate your tools and build skills. But they are not a substitute for testing your actual applications.
Every vulnerability class in DVWA and Juice Shop has direct equivalents in real production code:
- SQL injection in
low.php→ SQL injection in a legacy .NET or PHP application using string-concatenated queries - Reflected XSS in DVWA’s search → Unencoded user input in a CRM comment field or support ticket system
- IDOR in Juice Shop’s basket API → Missing authorization checks in a REST API endpoint
Once your scanner finds these issues in deliberately vulnerable applications, run it against your own codebase. The patterns are identical — only the surrounding code complexity differs.
Frequently Asked Questions
Is it legal to attack these applications?
Yes — provided you run them in your own isolated environment (a local Docker container or private VM on your own hardware). These applications exist specifically to be attacked. Never run them on a public server or shared network without proper isolation, and never point your security tools at applications you don’t have explicit authorization to test.
Which application is best for a complete beginner?
Start with DVWA at Low difficulty. The built-in source code viewer shows exactly what makes each page vulnerable, and the three difficulty levels provide a clear progression. Once you can identify and exploit all categories at Medium difficulty, move to Juice Shop for a more realistic challenge.
Can I use these applications for OSCP preparation?
Deliberately vulnerable web applications cover the web exploitation modules of OSCP well. OSCP’s primary focus is network exploitation, Active Directory attacks, and privilege escalation chains. For OSCP-specific machine practice, VulnHub and retired HackTheBox machines are more representative. Use DVWA and Juice Shop to solidify web exploitation fundamentals alongside your OSCP prep.
How do I reset the application to its original state?
For Docker-based applications, stopping and restarting the container resets all state:
# For Juice Shop — remove and recreate
docker stop juice-shop && docker rm juice-shop
docker run -d -p 3000:3000 --name juice-shop bkimminich/juice-shop
# For DVWA — restart and click "Create / Reset Database"
docker stop dvwa && docker rm dvwa
docker run -d -p 80:80 --name dvwa vulnerables/web-dvwa
Do these apps work offline / air-gapped?
Yes. Once the Docker image is pulled (docker pull bkimminich/juice-shop), the application runs completely offline with no internet connection required. This makes them suitable for air-gapped training environments and laptop-based offline practice.
Benchmark Your Scanner Today
Testing your SAST or DAST scanner against deliberately vulnerable applications before applying it to production code is standard practice in any professional security program. A scanner that misses SQL injection in DVWA’s low.php will miss the same pattern in your production application.
Offensive360 SAST and DAST are benchmarked against DVWA, Juice Shop, and WebGoat on every release:
- Book a demo — see Offensive360 SAST scan a real codebase and get a full vulnerability report
- Offensive360 DAST — authenticated dynamic scanning of your running web application
- See the full OWASP Juice Shop guide — complete challenge walkthrough, DAST benchmarking details, and CTF setup
- See all vulnerable web applications — full comparison with Docker setup for each option