Web Application Lab Setup
Set up vulnerable web applications locally using Docker for practicing XSS, SQL injection, authentication bypass, and other web security vulnerabilities.
Docker Required
Bind Vulnerable Apps Locally
Lab Runbook
Use this page as a controlled lab build, not a production hardening guide. Validate isolation before running exercises and write down the cleanup command before starting.
Plan
2-6 GB; 10-30 GB. Free. Isolation: Bind to localhost or isolated lab interface only.
Build
- - DVWA or Juice Shop running
- - Proxy configured
- - Reset path documented
Validate
- - Apps respond on expected localhost ports
- - Burp or ZAP intercepts browser traffic
- - No vulnerable container is bound to a public interface
Exercise
Run only the exercises tied to this lab and save screenshots, command output, logs, and timestamps outside disposable VMs.
Clean Up
- - docker compose down -v
- - docker container prune after exporting notes
- - Reset app databases between exercises
Quick Start with Docker
# Install Docker on Debian/Ubuntu
# Use the official Docker package instructions for your distro:
# https://docs.docker.com/engine/install/
docker --version
# Optional: add your user to docker group on a dedicated lab machine only
sudo usermod -aG docker $USER
newgrp docker
# Verify installation
docker --version
docker run hello-world# Install Docker on Debian/Ubuntu
# Use the official Docker package instructions for your distro:
# https://docs.docker.com/engine/install/
docker --version
# Optional: add your user to docker group on a dedicated lab machine only
sudo usermod -aG docker $USER
newgrp docker
# Verify installation
docker --version
docker run hello-worldVulnerable Applications
DVWA
BeginnerDamn Vulnerable Web App - Classic PHP vulnerabilities
vulnerables/web-dvwa OWASP Juice Shop
All LevelsModern JS/Node app with 100+ challenges
bkimminich/juice-shop WebGoat
BeginnerOWASP learning platform for web security
webgoat/webgoat bWAPP
IntermediateBuggy Web Application with 100+ bugs
raesene/bwapp crAPI
IntermediateOWASP Completely Ridiculous API - Modern API vulnerabilities
crapi/crapi vAPI
IntermediateVulnerable API with OWASP API Top 10 coverage
roottusk/vapi DVGA
IntermediateDamn Vulnerable GraphQL Application - GraphQL-specific attacks
dolevf/dvga NodeGoat
IntermediateOWASP Node.js vulnerable application
cider/owasp-nodegoat DVWA Setup
DVWA (Damn Vulnerable Web Application) is perfect for beginners. It includes multiple security levels (Low, Medium, High, Impossible) for each vulnerability type.
# Pull and run DVWA
docker run -d -p 127.0.0.1:8081:80 --name dvwa vulnerables/web-dvwa
# Access at http://localhost:8081
# Default credentials: admin / password
# After login, click "Create / Reset Database"
# Then go to DVWA Security and set level to "Low" to start# Pull and run DVWA
docker run -d -p 127.0.0.1:8081:80 --name dvwa vulnerables/web-dvwa
# Access at http://localhost:8081
# Default credentials: admin / password
# After login, click "Create / Reset Database"
# Then go to DVWA Security and set level to "Low" to startDVWA Vulnerabilities to Practice:
OWASP Juice Shop Setup
Juice Shop is a modern, feature-rich vulnerable application with a gamified experience. It has 100+ challenges across all skill levels and covers the OWASP Top 10.
# Pull and run Juice Shop
docker run -d -p 127.0.0.1:3000:3000 --name juice-shop bkimminich/juice-shop
# Access at http://localhost:3000
# Features:
# - Built-in score board (find it as a challenge!)
# - 100+ challenges with hints
# - Covers OWASP Top 10 and more
# - Modern JavaScript/Node.js architecture# Pull and run Juice Shop
docker run -d -p 127.0.0.1:3000:3000 --name juice-shop bkimminich/juice-shop
# Access at http://localhost:3000
# Features:
# - Built-in score board (find it as a challenge!)
# - 100+ challenges with hints
# - Covers OWASP Top 10 and more
# - Modern JavaScript/Node.js architectureJuice Shop Tips
OWASP WebGoat Setup
# Run WebGoat with WebWolf (companion app)
docker run -d -p 127.0.0.1:8080:8080 -p 127.0.0.1:9090:9090 --name webgoat webgoat/webgoat
# WebGoat: http://localhost:8080/WebGoat
# WebWolf: http://localhost:9090/WebWolf
# Register a new account to start
# Lessons are structured with explanations and exercises# Run WebGoat with WebWolf (companion app)
docker run -d -p 127.0.0.1:8080:8080 -p 127.0.0.1:9090:9090 --name webgoat webgoat/webgoat
# WebGoat: http://localhost:8080/WebGoat
# WebWolf: http://localhost:9090/WebWolf
# Register a new account to start
# Lessons are structured with explanations and exercisesDocker Compose: Multiple Apps
Run multiple vulnerable applications at once using Docker Compose.
services:
dvwa:
image: vulnerables/web-dvwa
ports:
- "127.0.0.1:8081:80"
container_name: dvwa
juice-shop:
image: bkimminich/juice-shop
ports:
- "127.0.0.1:3000:3000"
container_name: juice-shop
webgoat:
image: webgoat/webgoat
ports:
- "127.0.0.1:8080:8080"
- "127.0.0.1:9090:9090"
container_name: webgoat
bwapp:
image: raesene/bwapp
ports:
- "127.0.0.1:8082:80"
container_name: bwapp
crapi:
image: crapi/crapi
ports:
- "127.0.0.1:8888:8025"
- "127.0.0.1:8889:8443"
container_name: crapi
dvga:
image: dolevf/dvga
ports:
- "127.0.0.1:5013:5013"
container_name: dvga
environment:
- WEB_HOST=0.0.0.0 # Container bind; host exposure is restricted by 127.0.0.1 port mapping
# Run with: docker compose up -d
# Stop with: docker compose downservices:
dvwa:
image: vulnerables/web-dvwa
ports:
- "127.0.0.1:8081:80"
container_name: dvwa
juice-shop:
image: bkimminich/juice-shop
ports:
- "127.0.0.1:3000:3000"
container_name: juice-shop
webgoat:
image: webgoat/webgoat
ports:
- "127.0.0.1:8080:8080"
- "127.0.0.1:9090:9090"
container_name: webgoat
bwapp:
image: raesene/bwapp
ports:
- "127.0.0.1:8082:80"
container_name: bwapp
crapi:
image: crapi/crapi
ports:
- "127.0.0.1:8888:8025"
- "127.0.0.1:8889:8443"
container_name: crapi
dvga:
image: dolevf/dvga
ports:
- "127.0.0.1:5013:5013"
container_name: dvga
environment:
- WEB_HOST=0.0.0.0 # Container bind; host exposure is restricted by 127.0.0.1 port mapping
# Run with: docker compose up -d
# Stop with: docker compose down# Create docker-compose.yml with above content
# Then run:
docker compose up -d
# Check running containers
docker ps
# Access points:
# DVWA: http://localhost:8081
# Juice Shop: http://localhost:3000
# WebGoat: http://localhost:8080
# bWAPP: http://localhost:8082
# crAPI: http://localhost:8888 (mail) / https://localhost:8889 (app)
# DVGA: http://localhost:5013
# Stop all
docker compose down# Create docker-compose.yml with above content
# Then run:
docker compose up -d
# Check running containers
docker ps
# Access points:
# DVWA: http://localhost:8081
# Juice Shop: http://localhost:3000
# WebGoat: http://localhost:8080
# bWAPP: http://localhost:8082
# crAPI: http://localhost:8888 (mail) / https://localhost:8889 (app)
# DVGA: http://localhost:5013
# Stop all
docker compose downWeb Proxy Configuration
Configure a web proxy to intercept traffic to your local vulnerable apps. Burp Suite is the industry standard; Caido is a modern, lightweight alternative worth trying.
| Proxy | Cost | Scripting | Automation | Best For |
|---|---|---|---|---|
| Burp Suite Community | Free | Limited | Manual only | Learning, manual testing |
| Burp Suite Pro | $449/yr | BApp extensions | Scanner + Intruder | Professional pentesting |
| Caido | Free / $10+/mo | JavaScript plugins | Automate + Replay | Modern UI, fast, API-first |
| mitmproxy | Free (OSS) | Python scripting | Full Python API | Scripted testing, CI/CD |
| OWASP ZAP | Free (OSS) | Zest scripts | Active/Passive scanner | DAST, automation, CI/CD |
# 1. Start Burp Suite
# 2. Proxy > Options > Add listener on 127.0.0.1:8080
# Browser Configuration (Firefox recommended):
# Settings > Network Settings > Manual proxy
# HTTP Proxy: 127.0.0.1 Port: 8080
# Check "Also use for HTTPS"
# Install Burp CA Certificate:
# 1. Browse to http://burpsuite
# 2. Download CA Certificate
# 3. Import into browser's certificate store
# Target scope (add your apps):
# Target > Scope > Add:
# - http://localhost:3000 (Juice Shop)
# - http://localhost:8081 (DVWA)
# - http://localhost:8080 (WebGoat)
# - http://localhost:5013 (DVGA - GraphQL)
# - https://localhost:8889 (crAPI)# 1. Start Burp Suite
# 2. Proxy > Options > Add listener on 127.0.0.1:8080
# Browser Configuration (Firefox recommended):
# Settings > Network Settings > Manual proxy
# HTTP Proxy: 127.0.0.1 Port: 8080
# Check "Also use for HTTPS"
# Install Burp CA Certificate:
# 1. Browse to http://burpsuite
# 2. Download CA Certificate
# 3. Import into browser's certificate store
# Target scope (add your apps):
# Target > Scope > Add:
# - http://localhost:3000 (Juice Shop)
# - http://localhost:8081 (DVWA)
# - http://localhost:8080 (WebGoat)
# - http://localhost:5013 (DVGA - GraphQL)
# - https://localhost:8889 (crAPI)Practice Exercises
Exercise 1: SQL Injection (DVWA)
Set security to Low. Go to SQL Injection page. Extract all usernames and passwords from the database.
Exercise 2: XSS Cookie Stealing (DVWA)
Use Stored XSS against your local lab app and capture the request with a local listener or Burp Collaborator-equivalent inside your authorized lab scope.
Exercise 3: Find the Admin (Juice Shop)
Find the admin's email address, then log in as admin using SQL injection on the login form.
Exercise 4: JWT Manipulation (WebGoat)
Complete the JWT lessons - learn to decode, tamper, and exploit weak JWT implementations.
Exercise 5: GraphQL Introspection (DVGA)
Use introspection to map the GraphQL schema, then exploit IDOR and injection vulnerabilities in queries and mutations.
Exercise 6: API BOLA Attack (crAPI)
Exploit Broken Object Level Authorization to access other users' vehicle data through the crAPI REST API.
Cleanup Commands
# Stop specific container
docker stop dvwa juice-shop webgoat
# Remove containers
docker rm dvwa juice-shop webgoat crapi dvga
# Remove all stopped containers
docker container prune
# Remove images to free space
docker rmi vulnerables/web-dvwa bkimminich/juice-shop webgoat/webgoat crapi/crapi dolevf/dvga
# Nuclear option - remove everything
docker system prune -a# Stop specific container
docker stop dvwa juice-shop webgoat
# Remove containers
docker rm dvwa juice-shop webgoat crapi dvga
# Remove all stopped containers
docker container prune
# Remove images to free space
docker rmi vulnerables/web-dvwa bkimminich/juice-shop webgoat/webgoat crapi/crapi dolevf/dvga
# Nuclear option - remove everything
docker system prune -a💡 Pro Tip
Start with DVWA on "Low" security to understand each vulnerability type. Then increase difficulty and try Juice Shop for a more realistic modern web app experience. Document your findings as you would in a real pentest report.
Troubleshooting FAQ
Docker containers won't start (port conflict)
- Check what's using the port:
sudo lsof -i :8080ornetstat -tlnp | grep 8080 - Change the host port in docker run:
-p 9090:80instead of-p 80:80 - Stop conflicting containers:
docker psthendocker stop container_name - On Windows/Mac: check Docker Desktop is running
Burp Suite not intercepting HTTPS traffic
- Install CA cert: browse to
http://burpsuiteand download/import the certificate - Firefox: Settings > Privacy > View Certificates > Import (check "Trust for websites")
- Ensure proxy is set in browser (not just system proxy)
- Check Burp intercept is ON: Proxy > Intercept tab
DVWA shows "Access denied" or database error
- Default login:
admin / password - Click "Create / Reset Database" on the setup page first
- If container keeps crashing, recreate:
docker rm -f dvwa && docker run -d -p 127.0.0.1:8081:80 --name dvwa vulnerables/web-dvwa
Operational Safety Baseline
Apply these rules before running any lab command on this page.
- Work only on systems you own or have explicit authorization to test.
- Keep vulnerable services off your home LAN and off public interfaces.
- Take clean snapshots before every exercise and before every vulnerable configuration change.
- Use dedicated cloud accounts, subscriptions, and projects with billing alerts before deployment.
- Write down the teardown command before you run the setup command.
Validation Checkpoints
- -Apps respond on expected localhost ports
- -Burp or ZAP intercepts browser traffic
- -No vulnerable container is bound to a public interface
Cleanup And Rollback
- -docker compose down -v
- -docker container prune after exporting notes
- -Reset app databases between exercises