Setting up a personal security testing lab gives you a safe, legal environment to practice web application penetration testing, benchmark SAST and DAST scanners, and develop the skills needed for real-world application security work. This guide walks through everything you need: what to run, how to run it, how to keep it isolated, and how to structure your practice.
Why You Need a Dedicated Security Testing Lab
Testing attack techniques against live, unauthorized systems is illegal. Testing against your own production application risks real data, user disruption, and security incident alerts. A local security testing lab solves both problems: deliberately vulnerable applications designed to be attacked, running entirely on your own machine or private network.
A properly configured lab gives you:
- Legal targets — applications built to be exploited
- Full control — reset to clean state instantly, run any tool you want
- Isolated environment — vulnerable apps never exposed to the internet
- Multiple tech stacks — PHP, Java, Node.js, Python apps to match real-world diversity
- SAST/DAST benchmarking — validate your security tools before pointing them at production
Lab Requirements
A capable security testing lab runs comfortably on a modern laptop:
Minimum hardware:
- 8 GB RAM (16 GB recommended for running multiple apps simultaneously)
- 20 GB free disk space
- A modern CPU (any 4-core machine from 2018 onward)
Required software:
- Docker Desktop (macOS, Windows, Linux)
- A modern browser with DevTools (Chrome or Firefox)
- A terminal / shell
Optional but useful:
- A REST API client (Bruno, Postman, or Insomnia)
- Burp Suite Community Edition (free) for traffic interception
- Python 3 (for scripting and tool installation)
Core Vulnerable Applications to Include
A complete lab covers multiple technology stacks and vulnerability patterns:
| Application | Tech Stack | Best For | Setup Time |
|---|---|---|---|
| OWASP Juice Shop | Node.js + Angular | DAST benchmarking, CTF, modern SPAs | < 1 minute |
| DVWA | PHP + MySQL | OWASP Top 10 fundamentals, PHP SAST | < 2 minutes |
| WebGoat | Java + Spring | Java security, structured learning | < 2 minutes |
| bWAPP | PHP | Breadth (100+ vulnerability types) | < 2 minutes |
| NodeGoat | Node.js + Express | Node.js/MongoDB SAST | 5 minutes |
Start with Juice Shop and DVWA — they cover the fundamentals across modern and legacy architectures. Add WebGoat when you need Java-specific practice, and NodeGoat when you want Node.js patterns.
Step 1: Install Docker Desktop
Docker is the fastest way to run vulnerable applications — no dependency conflicts, instant reset, and clean teardown.
macOS:
# Install Docker Desktop from https://www.docker.com/products/docker-desktop/
# Or with Homebrew:
brew install --cask docker
open /Applications/Docker.app
Windows: Download and install Docker Desktop from docker.com. Enable WSL 2 integration when prompted.
Linux (Ubuntu/Debian):
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER
# Log out and back in for group changes to take effect
Verify Docker is running:
docker run hello-world
# Should print: Hello from Docker!
Step 2: Set Up Network Isolation
Critical: Vulnerable applications must never be reachable from outside your machine. Run them on localhost only, or on a host-only Docker network that is not bridged to the internet.
Docker’s default bridge network (bridge) allows inter-container communication but not inbound internet traffic as long as you bind to 127.0.0.1. Use the -p 127.0.0.1:HOST_PORT:CONTAINER_PORT binding instead of -p HOST_PORT:CONTAINER_PORT to restrict access to localhost only:
# SECURE — binds to localhost only
docker run -d -p 127.0.0.1:3000:3000 --name juice-shop bkimminich/juice-shop
# LESS SECURE — binds to all interfaces (0.0.0.0) — accessible from network
docker run -d -p 3000:3000 bkimminich/juice-shop
For a team lab or a VM-based lab where you want machines to reach each other but not the internet:
# Create an isolated Docker network for your lab
docker network create --driver bridge --internal security-lab
# Run apps on the isolated network
docker run -d --network security-lab --name juice-shop bkimminich/juice-shop
docker run -d --network security-lab --name dvwa vulnerables/web-dvwa
With --internal, the Docker network cannot route to the internet — containers can only talk to each other.
Step 3: Deploy OWASP Juice Shop
Juice Shop is the best single target for DAST benchmarking and modern web application practice:
# Start Juice Shop
docker run -d \
-p 127.0.0.1:3000:3000 \
--name juice-shop \
bkimminich/juice-shop
# Verify it's running
curl -s -o /dev/null -w "%{http_code}" http://localhost:3000/
# Should return: 200
Open http://localhost:3000/ in your browser, then navigate to the scoreboard at http://localhost:3000/#/score-board.
Manage your Juice Shop container:
# Stop (preserves your challenge progress)
docker stop juice-shop
# Restart and resume progress
docker start juice-shop
# Reset to clean state (clears all progress)
docker stop juice-shop && docker rm juice-shop
docker run -d -p 127.0.0.1:3000:3000 --name juice-shop bkimminich/juice-shop
Step 4: Deploy DVWA
DVWA (Damn Vulnerable Web Application) provides structured OWASP Top 10 coverage with a built-in code viewer — ideal for understanding why each vulnerability exists:
docker run -d \
-p 127.0.0.1:8080:80 \
--name dvwa \
vulnerables/web-dvwa
# Access at http://localhost:8080/
# Default login: admin / password
# Click "Create / Reset Database" on first access
DVWA has three difficulty levels per vulnerability — Low, Medium, and High. Always start at Low (fully unobfuscated vulnerabilities), then progress to Medium and High to understand evasion-resistant patterns.
DVWA SQL Injection at Low difficulty:
URL: http://localhost:8080/vulnerabilities/sqli/
Input the User ID field: ' OR '1'='1
This simple payload returns all users from the database, demonstrating the core SQL injection mechanism before any defenses are applied.
Step 5: Deploy WebGoat (Java)
WebGoat covers Java-specific vulnerabilities and has a structured lesson format ideal for developer training:
docker run -d \
-p 127.0.0.1:9090:8080 \
-p 127.0.0.1:9091:9090 \
--name webgoat \
webgoat/webgoat
# Access at http://localhost:9090/WebGoat
# Register a new account on first access
WebGoat lessons require you to successfully exploit the vulnerability before marking it complete — effective for building real exploitation skills, not just reading about them.
Step 6: Deploy bWAPP (Optional — Broad Coverage)
bWAPP covers 100+ vulnerability types, including unusual classes not found in Juice Shop or DVWA:
docker run -d \
-p 127.0.0.1:8888:80 \
--name bwapp \
raesene/bwapp
# First access: http://localhost:8888/bWAPP/install.php
# Then login: http://localhost:8888/bWAPP/login.php
# Default credentials: bee / bug
Use bWAPP when you want to explore vulnerability classes beyond the standard OWASP Top 10 — LDAP injection, XML injection, HTML5 security issues, server-side request forgery variants, and more.
Step 7: Run Everything with Docker Compose
For a one-command lab startup, use Docker Compose:
# docker-compose.yml — complete security testing lab
version: '3.8'
services:
juice-shop:
image: bkimminich/juice-shop
ports:
- "127.0.0.1:3000:3000"
container_name: juice-shop
restart: unless-stopped
dvwa:
image: vulnerables/web-dvwa
ports:
- "127.0.0.1:8080:80"
container_name: dvwa
restart: unless-stopped
webgoat:
image: webgoat/webgoat
ports:
- "127.0.0.1:9090:8080"
- "127.0.0.1:9091:9090"
container_name: webgoat
restart: unless-stopped
bwapp:
image: raesene/bwapp
ports:
- "127.0.0.1:8888:80"
container_name: bwapp
restart: unless-stopped
# Start the entire lab
docker compose up -d
# Stop everything
docker compose down
# Check status
docker compose ps
Your complete lab is now available:
- Juice Shop:
http://localhost:3000/ - DVWA:
http://localhost:8080/ - WebGoat:
http://localhost:9090/WebGoat - bWAPP:
http://localhost:8888/bWAPP/login.php
Step 8: Configure Traffic Interception with Burp Suite
Burp Suite Community Edition (free) intercepts and modifies HTTP/HTTPS traffic between your browser and the vulnerable applications, enabling:
- Manual request modification for injection testing
- Repeating requests with modified parameters
- Active scanning with Burp Scanner (Pro only, but manual testing is free)
Setup:
- Download Burp Suite Community Edition — free
- Start Burp → Proxy → Intercept → “Open Browser” (launches a pre-configured browser)
- Navigate to
http://localhost:3000/(Juice Shop) — all traffic appears in Burp’s HTTP history - Right-click any request → “Send to Repeater” to modify and replay
For testing injection points, use Repeater to modify parameters without writing scripts.
Step 9: Configure a DAST Scanner Against Your Lab
For DAST scanner benchmarking — testing whether your scanner can detect known vulnerabilities before you point it at production — configure it against Juice Shop:
Setting Up Authenticated Scanning
Most interesting vulnerabilities in Juice Shop are behind authentication. Configure your scanner to log in first:
- Register a test account at
http://localhost:3000/#/register(e.g.,[email protected]/LabTest123!) - In your DAST scanner, configure the authentication flow:
- Login URL:
http://localhost:3000/rest/user/login - Method: POST
- Body:
{"email":"[email protected]","password":"LabTest123!"} - Token extraction: from the JWT in the response body
- Login URL:
Minimum Findings Your Scanner Should Report
Run your DAST scanner against a locally authenticated Juice Shop instance and verify it finds these known vulnerabilities:
| Vulnerability | Location | Severity |
|---|---|---|
| SQL injection | Login form (/rest/user/login) | Critical |
| Reflected XSS | Search bar (/rest/products/search?q=) | High |
| Missing Content-Security-Policy | All pages | Medium |
| Missing X-Content-Type-Options | All pages | Low |
| Directory listing | /ftp/ endpoint | Medium |
| Sensitive file accessible | /ftp/acquisitions.md | High |
A production-ready DAST scanner must find the unobfuscated SQL injection in the login form — the most basic SQL injection test case. If it misses this, it will miss similar patterns in your production application.
Practice Roadmap: Getting the Most from Your Lab
Structure your practice for progressive skill development:
Week 1–2: Injection Fundamentals (DVWA Low Difficulty)
- SQL injection in User ID field — manual payload testing
- Command injection in the ping utility — OS command execution
- File inclusion (LFI) — reading server-side files via path manipulation
- Understand the source code via DVWA’s “View Source” button for each vulnerability
Week 3–4: Juice Shop One- and Two-Star Challenges
- Find the scoreboard (teaches: security through obscurity fails)
- DOM-based XSS via the search bar
- SQL injection in the login form (bypass authentication)
- IDOR via the basket API (access other users’ baskets)
- Use browser DevTools → Network tab to observe all API calls
Month 2: Authentication and Access Control
- JWT algorithm confusion in Juice Shop (forge admin tokens)
- Password reset flow weaknesses
- CORS misconfiguration detection
- Horizontal privilege escalation (IDOR across user resources)
- WebGoat’s Access Control and Authentication lessons
Month 3: Advanced Techniques
- Juice Shop three- and four-star challenges
- XXE injection in XML-accepting endpoints
- SSRF via URL parameters
- Second-order SQL injection patterns
- Run a DAST scanner (Offensive360, Burp Pro, or OWASP ZAP) against your lab and compare automated findings vs. manual results
Ongoing: DAST Benchmarking
Each time you evaluate a new security tool, verify it against your lab:
- Point it at Juice Shop with authentication configured
- Compare what it finds against the known vulnerability list
- Test your SAST tools against DVWA and WebGoat source code (clone from GitHub)
Keeping Your Lab Secure
A local lab with intentionally vulnerable applications is safe when properly isolated:
Do:
- Bind all ports to
127.0.0.1(localhost only) - Use Docker’s
--internalnetwork flag when you need inter-container communication - Stop containers when not in use (
docker compose down) - Keep Docker Desktop updated
Don’t:
- Expose lab ports on a public or shared network interface
- Run lab containers on a production server or VPS without firewall rules
- Leave containers running unattended on a laptop used in public places
If you’re running a team lab (multiple users sharing a single server), use VLANs or firewall rules to restrict who can reach the lab network.
Adding Your Own Applications
Once you’re comfortable with standard vulnerable apps, extend your lab with your own code:
# Run any local application alongside your vulnerable app lab
docker run -d \
-p 127.0.0.1:5000:5000 \
-v $(pwd)/my-app:/app \
--name my-app \
python:3.11-slim \
bash -c "pip install -r /app/requirements.txt && python /app/app.py"
Then point your SAST scanner at the source code and your DAST scanner at http://localhost:5000/ — exactly as you’d do for a production application, but safely on your local machine.
This workflow — SAST scan of source + DAST scan of running app — mirrors professional application security assessment methodology.
Frequently Asked Questions
How much disk space does the full lab require?
Docker images for all four applications (Juice Shop, DVWA, WebGoat, bWAPP) total approximately 3–4 GB of disk space. Running all simultaneously uses about 2–3 GB of RAM, which is well within range for a machine with 8 GB.
Can I run the lab on a virtual machine?
Yes — and this is often preferable for isolation. Running your lab in a VirtualBox or VMware VM with a host-only network adapter gives you a second layer of isolation beyond Docker’s network controls.
Is it safe to run vulnerable applications on a home network?
When properly configured (localhost binding or Docker internal network), vulnerable applications are not reachable from other devices on your network. However, as an extra precaution, always use 127.0.0.1 port binding and close the lab when not in use.
Do I need the paid version of Burp Suite?
No. Burp Suite Community Edition is free and sufficient for manual traffic interception, request modification, and repeater-based injection testing. Burp Suite Pro adds an automated scanner, which is useful for DAST benchmarking but not required for manual skill development.
Can I use the lab to prepare for certifications?
Yes — OWASP Juice Shop, DVWA, and WebGoat are widely used for preparation for:
- OSCP (web exploitation modules)
- CEH (practical exam web security sections)
- eWPT (Web Application Penetration Tester)
- GWAPT (GIAC Web Application Penetration Tester)
- PortSwigger Web Security Academy courses (free, browser-based)
Summary: Your Complete Lab in One Command
# Save this as docker-compose.yml and run:
docker compose up -d
# Your lab is ready at:
# Juice Shop: http://localhost:3000/
# DVWA: http://localhost:8080/ (admin/password)
# WebGoat: http://localhost:9090/WebGoat
# bWAPP: http://localhost:8888/bWAPP/login.php (bee/bug)
Start with Juice Shop’s one-star challenges and DVWA at Low difficulty. Use browser DevTools to watch every API call. Move to Burp Suite when you want to modify requests. Add a DAST scanner when you’re ready to compare automated detection against your manual findings.
A security testing lab is the highest-return investment you can make in application security skills — legal, realistic, and available for practice at any hour.
Offensive360 DAST is benchmarked against OWASP Juice Shop on every release. Book a demo to see authenticated DAST scanning in action — or to verify scanner performance against your own codebase before committing to a production deployment.