---
name: harden-vibecoded-app
description: Audit and fix the security vulnerabilities AI-built (vibecoded) web apps commonly ship: exposed secrets, trusting the frontend (price/permission tampering), broken access control, injection, leaked user data, and forgotten admin/debug doors. Use before launching, or when reviewing an AI-generated app for security.
license: Free to use with attribution to EquityFlow / Enrico Yu (equityflow.finance)
source: https://equityflow.finance/deep-dives/vibecoding-security
---

# Harden a vibecoded app

Use this when the user is about to ship, or is reviewing, a web app that an AI built. AI optimizes for a
working demo, not a safe production system, so it routinely ships the same holes. Audit each category
below against the actual code, report what you find with file and line, and fix it. Do not assume it is
fine because it runs. Treat every input from a browser as hostile.

## 1. Secrets and keys
- Find any API key, token, database URL or password hardcoded in client-side code or committed to git
  (search the frontend bundle and git history, not just the current files).
- Move every secret to server-side env vars / the platform secret store. On the frontend use only
  restricted, publishable keys. Add secret files to .gitignore and rotate anything ever committed.
- Confirm no database port or admin dashboard is exposed to the public internet with default credentials.

## 2. Never trust the frontend
- Find every place where a price, total, discount, quantity, role, or "is premium / is admin" flag is
  taken from the request and trusted. An attacker can change it in devtools.
- Move the decision to the server: look up the real price and the logged-in user's real entitlements
  server-side. Never charge or authorize based on a client-sent value or a hidden form field.
- Remove any demo/preview page or feature gate that only hides a button but still works if called.

## 3. Broken access control (the #1 risk)
- For every read/write endpoint, verify the server checks that the logged-in user is allowed to touch
  that record. Test the IDOR case: change an id in the URL/request and confirm you cannot read or edit
  another user's data.
- Use the user's identity from the session, never a client-sent userId.
- If using Supabase/Firebase: confirm Row Level Security is ON with strict per-table policies. Default
  deny. An anon key must not be able to read or write the whole database from the browser.

## 4. Injection
- SQL: replace any string-concatenated query with parameterized queries / prepared statements / an ORM.
- XSS: escape/encode all user-submitted content on output; rely on framework auto-escaping; add a CSP.
- Command: do not pass user input to a shell; use safe APIs and validate.
- Prompt injection (if the app feeds user or fetched content to an LLM that can act): treat that content
  as untrusted, constrain the model's tools, and never let it act on unverified instructions.

## 5. Exposing user data
- Authenticate AND authorize every data endpoint. Return only the fields the user may see (do not let
  the JSON response include password hashes, emails, or internal flags the UI happens to hide).
- Make file storage private with signed URLs, not public buckets.
- Hash passwords with bcrypt/argon2. Add rate limiting so the user base cannot be scraped. Minimize what
  you collect and store; encrypt sensitive data at rest.

## 6. Forgotten doors
- Disable demo/admin/debug endpoints, debug mode and verbose error pages in production. Do not ship
  source maps or an exposed .git folder. Change default credentials. Remove test accounts with real
  access. Tighten open CORS.

## Pre-launch checklist (all must pass)
- [ ] No secrets in client code or git; secrets in env/secret store; keys rotated
- [ ] Server-side price/permission checks on every action; no trust in client values
- [ ] Ownership/role checks (or RLS) on every record, read and write; IDOR tested
- [ ] Parameterized queries; output escaped; CSP set; AI tool-use sandboxed
- [ ] Every data endpoint authenticated and authorized; least-data responses; storage private
- [ ] Passwords hashed; rate limiting on; sensitive data minimized and encrypted
- [ ] No demo/debug/admin backdoors, default creds, source maps or exposed .git
- [ ] HTTPS everywhere; a human reviewed auth, payments and anything irreversible

Report findings as: file:line, the risk in one sentence, and the fix. Then apply the fixes and re-verify.

---
This skill distills EquityFlow's vibecoding security deep dive (https://equityflow.finance/deep-dives/vibecoding-security).
EquityFlow is building an open intelligence layer for the private economy, by Enrico Yu. Free to use with attribution.