A dockerized, deliberately-vulnerable Next.js banking app that teaches SQL injection and broken-access-control through five graded, hands-on challenges.

Most AppSec training is either toy "spot the bug" snippets or sprawling labs nobody can stand up locally. SecureBank CTF lands in between: a believable Next.js / React banking app on a SQLite backend with no ORM, so every query path is hand-written and every vulnerability is deliberate, not accidental.
The engineering is in making the flaws solvable but non-trivial. The login route strips SQL metacharacters with a regex, then URL-decodes the input twice, so a double-encoded payload slips past the filter and injects. The feedback endpoint routes its INSERT through SQLite's multi-statement exec instead of a prepared statement, turning a comment box into stacked-query privilege escalation, while the DELETE path stays parameterized. Two access-control backdoors round it out: an x-dev-mode header that drops the per-user WHERE clause, and a maintenance route that runs raw SQL only under a debug flag on a specific weekday.
Each challenge ships an objective and full writeup, and the whole lab runs from one multi-stage Docker image with a seed-snapshot database that persists progress across restarts. SecureBank was a five-person university project: I authored the privilege-escalation challenge and was the largest contributor to the application and its Docker packaging, while four teammates each built a graded challenge of their own.
x-dev-mode header and a weekday-gated debug route running raw SQLFive-person team at Ontario Tech