L3 — Security Essentials
Track 2: Vibe-Coder Level-Up · B.U.I.L.D. letter: L (Lock It Down)
The AI's code runs. That doesn't mean it's safe. This is the lesson that separates "I made an app" from "I made an app I'd trust with real people's data."
⚠️ The vibe trap
AI assistants optimize for working, not secure. They'll happily hardcode your API key, trust whatever the user types, and leave your database wide open — because all of that works in the demo. The bill comes later, when a real stranger pokes at it. Most vibe-coded breaches aren't clever hacks; they're doors left unlocked.
This lesson is the five locks every builder must check.
🔑 Lock 1 — Keep secrets secret
Your API keys and passwords are like house keys. Hardcoding them in your code is taping the key to the front door.
- Put them in environment variables (a
.envfile), and add.envto.gitignore. - Anything sent to the browser is public. Secret keys belong on the backend only.
- Already committed a key? Assume it's compromised — rotate it (generate a new one) and remove it from history.
🧹 Lock 2 — Never trust user input
Every input box is a place a stranger can type anything — including things designed to break you.
- Validate and sanitize on the server, not just in the browser (browser checks are trivially bypassed).
- Use parameterized queries so input can't become a database command (that's how SQL injection happens).
- Escape user content before showing it on the page (that's how XSS — malicious scripts — gets in).
🚪 Lock 3 — Check permissions on the backend
The frontend hiding a button does not stop anyone. Real enforcement happens server-side.
- For every protected action, the server must ask: "Is this specific user allowed to do this?"
- Test for IDOR: log in as yourself, change an ID in the URL, and see if you can read someone else's data. If you can, so can anyone.
🗄️ Lock 4 — Lock down your database (the #1 leak)
The single most common vibe-coder disaster: a Firebase/Supabase/database left in "anyone can read/write" test mode and shipped to production.
- Open your database rules/permissions and actually read them.
- Default to deny; grant only what each user genuinely needs.
📦 Lock 5 — Audit your dependencies
Your app is built on other people's code, and some of it has known holes.
- Run
npm audit(or your stack's equivalent) and fix the criticals. - Keep packages reasonably current; drop abandoned ones.
🛠️ Your mission
Find three vulnerabilities in this snippet, then fix them:
const API_KEY = "sk_live_92h4f8..."; // (1)
app.get('/user', (req, res) => {
const id = req.query.id;
db.query("SELECT * FROM users WHERE id = " + id); // (2)
res.send(user); // returns the full row, including password_hash // (3)
});
(Answers: (1) secret hardcoded → env var; (2) string-concatenated SQL → parameterized query; (3) over-exposed data → return only safe fields. Post your fixed version in the comments!)
✅ You're done when…
Run the 🔒 Security Audit Checklist (pinned in Featured). At minimum:
- No secrets in your code or Git history
- All input validated server-side; queries parameterized
- Auth/permission checks enforced on the backend
- Database rules locked down
-
npm auditrun and criticals fixed
➡️ Next: L4 — Testing & Quality (prove it works, on purpose). Build It Right, Or Don't Build It At All. 🏛️