## https://sploitus.com/exploit?id=5F692418-3A90-5C6F-8243-9795881C7D1D
[](https://github.com/amin-ale/vibe-playground/actions/workflows/ci.yml)
# vibe-playground
> ## Intentionally vulnerable app for security training. Never expose this publicly.
> This app ships with **12 deliberately planted security holes**. It exists to be
> broken: for training, demos, and interview-free proof of what "vibe-coded"
> apps get wrong. Run it only on a machine you control, bound to `localhost`,
> behind isolation. Do **not** deploy it to the internet, a shared network, or
> any host that reaches real data. Only run it, and any exploit against it, on
> infrastructure you own or have written authorization to test.
`QuickNotes` is a small FastAPI + SQLite + vanilla-JS note app in the shape that
AI code assistants generate: it runs, it looks fine, and it contains twelve real
vulnerabilities I have repeatedly found in production code that started in a
generator. The holes are documented, and each one is pinned by a test that
asserts it **exists**, so the target can't be accidentally "fixed" out from under
the exercise.
Try it blind first, then check your work against
[`docs/find-the-12-holes.md`](docs/find-the-12-holes.md): the full answer key
with exploit and fix for every hole.
## The 12 planted holes
BOLA/IDOR 路 mass assignment 路 secret shipped to client 路 missing rate limit on
auth 路 raw SQL injection 路 open redirect 路 weak/predictable session 路 debug
endpoint enabled 路 permissive CORS 路 unvalidated webhook 路 path traversal in
file serving 路 missing authz on admin route.
## Architecture
```mermaid
flowchart LR
Browser["Browserstatic/index.html + app.js"] -->|fetch JSON| API
subgraph API["FastAPI app (app/main.py)"]
Auth["/api/login 路 /api/registermd5 session tokens"]
Notes["/api/notes 路 /api/search"]
Users["/api/users/me 路 /api/admin/users"]
Misc["/api/redirect 路 /api/files/api/webhooks/payment 路 /api/debug"]
end
API --> DB[("SQLiteusers 路 notes")]
Notes -.->|planted holes| DB
Users -.->|planted holes| DB
```
## Quickstart
Requires Python 3.11+ and [uv](https://docs.astral.sh/uv/).
```bash
uv venv --python 3.12
uv pip install -e .
# bind to localhost only, never 0.0.0.0
uv run uvicorn app.main:app --host 127.0.0.1 --port 8000
```
Open http://127.0.0.1:8000. The database seeds itself on first run with two
users (`alice` / `alice-password`, `root` / `super-secret-admin-pw`) and a
sample note.
Isolating the process (a container with no network, a throwaway VM, or firewall
rules that keep it on loopback) is a human TODO. This repo does not sandbox
itself.
## Running the tests
The suite is the proof the holes are planted, not accidental: every test asserts
a vulnerability is present. All twelve should be green, offline, in under a
second.
```bash
uv pip install -e ".[dev]"
uv run pytest
```
```
tests/test_holes.py ............ [100%]
12 passed
```
## Layout
```
app/
main.py FastAPI app: all 12 holes live here (and in static/, db.py, config.py)
db.py SQLite schema + seed data
config.py secrets/paths (deliberately weak defaults)
static/ index.html + app.js (front end; one hole here)
tests/test_holes.py one test per hole, each asserting it EXISTS
docs/find-the-12-holes.md the answer key: exploit + fix for each hole
```
## Hire me
I harden apps exactly like this one, turning generated-and-shipped code into
something that survives a real attacker. If your Lovable/Bolt/Cursor app needs a
security pass before it touches customer data, get in touch:
[portfolio site](https://amin-ale.github.io/portfolio-site) 路 [amin.ale.business@gmail.com](mailto:amin.ale.business@gmail.com) 路 Amin Ale.