A modern, deliberately vulnerable, API-first web application for hands-on web and API security training - and a measurable regression target for pentest and scanner pipelines.
WARNING: This application is intentionally vulnerable. It is for local, educational use only. Do NOT deploy it on the public internet, a shared network, or anywhere reachable by untrusted users. Every secret in this repo is fake.
Project Management DVWA is a deliberately vulnerable web application and vulnerable API - a realistic project-and-task management SaaS planted with intentional security bugs, built as a modern DVWA alternative. The classic teaching apps (DVWA, bWAPP, OWASP WebGoat, Mutillidae) are ~2013-era PHP/Java form apps. This project instead targets the OWASP API Security Top 10 (2023) alongside the OWASP Web Top 10 (2021) and current attack techniques, giving you a realistic API penetration testing lab and a web security training ground that reflects how software is actually built today - covering IDOR, BOLA, SSRF, JWT flaws and much more.
It ships as two distinct origins on purpose: a web origin (Next.js 14, App Router, TypeScript) on http://localhost:8082 that issues an httpOnly session cookie, and an api origin (FastAPI, Python) on http://localhost:8081 that authenticates with a Bearer JWT. The browser logs into web, then exchanges its session cookie for an api Bearer token - a cookie-to-Bearer bridge across two hosts, exactly the kind of surface a real IDOR, BOLA, SSRF, or JWT bug lives on.
The catalog is maintained against a machine-readable ground-truth manifest that also serves as a regression fixture for scanners and pentest automation, and is kept out of the public repo so it does not spoil the exercise.
The target covers the OWASP API Security Top 10 (2023) and Web Top 10 (2021) alongside current techniques - broken access control, SSRF, injection, authentication and JWT/OAuth weaknesses, business-logic and integration abuse, and client-side flaws - across a realistic multi-tenant surface. Locating, exploiting, and classifying them is the exercise; the specifics are intentionally left undocumented.
Python 3.11+, FastAPI, Next.js 14 (App Router, TypeScript), SQLite (deterministically seeded). Web on http://localhost:8082, API on http://localhost:8081.
Requires Python 3.11+ and Node.js 18.17+. One cross-platform command installs everything and runs both servers (on macOS/Linux use python3 if python is missing):
git clone https://github.com/dev-rahulmandal/Project-Management_DVWA.git
cd Project-Management_DVWA
python run.pyOn first run run.py installs the Python and web dependencies and seeds the local .env files, then starts:
- api (FastAPI) on http://localhost:8081
- web (Next.js) on http://localhost:8082
Open http://localhost:8082 and sign in with a seeded account below. Press Ctrl-C to stop both servers.
The launcher detects your host, runs preflight checks, installs what it safely can, and prints the exact per-host commands for anything it cannot (Node.js, system packages, folder permissions). It never runs sudo for you. Available modes:
| Command | What it does |
|---|---|
python run.py |
Start both servers (installs deps and seeds on first run). |
python run.py --reseed |
Delete the local database first, then start with fresh seed data. |
python run.py --check |
Run host detection and preflight checks only, then exit (handy for diagnosing a setup). |
python run.py --pentest |
Print the optional real-hostname (Burp-visible) setup steps for your host. |
No Python or Node on the host? Use Docker instead: docker compose up --build (see below).
Prefer containers? With Docker and the Compose v2 plugin, one command builds and runs the whole system - no Python or Node needed on the host:
git clone https://github.com/dev-rahulmandal/Project-Management_DVWA.git
cd Project-Management_DVWA
docker compose up --buildOpen http://localhost:8082, then press Ctrl-C to stop and run docker compose down to remove the containers. The SQLite database is seeded fresh inside the container on every run - it is intentionally ephemeral, so each up starts from a clean, deterministic seed. Ports publish to 127.0.0.1 only.
On Debian/Kali the
docker.ioengine ships without Compose. Ifdocker composereports an unknown command, install the plugin per Docker's install docs - the manual binary drop-in into/usr/local/lib/docker/cli-plugins/is the most reliable method.
Manual setup (without the launcher)
pip install -r api/requirements.txt
cd web && npm install && cd ..
cp api/.env.example api/.env
cp web/.env.example web/.env.local
python -m uvicorn api.main:app --port 8081 --reload # api -> http://localhost:8081
cd web && npm run dev # web -> http://localhost:8082Optional (realistic pentest setup): to let a proxy like Burp observe api traffic (browsers bypass the proxy for localhost), set
NEXT_PUBLIC_API_ORIGIN=http://api.prolane.test:8081inweb/.env.localand add127.0.0.1 prolane.test api.prolane.testto your hosts file.
Two tenants plus a super-admin enable cross-tenant and broken-access-control bugs. All passwords are Password1!.
| Tenant | Role | |
|---|---|---|
| alice@northwind.test | Northwind Systems | Owner |
| charlie@northwind.test | Northwind Systems | Member |
| bob@bluepeak.test | Bluepeak Labs | Owner |
| diana@bluepeak.test | Bluepeak Labs | Member |
| marcus.webb@northwind.test | Northwind Systems | Owner + Super-admin |
The vulnerabilities in this project are intentional - please do not report them as security issues. If you find a genuine bug in the app scaffolding, the launcher, or the docs (not one of the intended vulnerabilities), see SECURITY.md.
MIT - see LICENSE.