Cindy Zhu.
Free guides
Building & apps Claude Code

Close the 3 security holes in every vibe-coded website

Hey, it's Cindy ๐ŸŒฑ If you vibe-coded a website, three security holes are probably already live, and one can run up your bill overnight. Below are three Claude Code prompts, one per hole.
btw the waitlist for AI System Club is now open! If you're keen on using AI to automate your content, video editing, job search, business or build AI agents, feel free to sign up (only if you want to hehe). Ps. the waitlist gets first dibs:)
Run these in Claude Code, pointed at your repo. Not a normal chat. Claude Code is what lets it spin up sub-agents and actually read and edit your files. Open your project in Claude Code first, then paste the prompts one at a time and review each diff before you accept it.
the numbers

Why this is worth 10 minutes

This is not a hypothetical. The research on AI-built apps is genuinely alarming.

400+ leaked secrets One scan of 1,400 vibe-coded apps found over 400 leaked secrets and 175 PII exposures. (Escape.tech)
~1 in 5 leaks a key RedHunt Labs scanned ~130,000 AI-built sites and found roughly 1 in 5 leaked a key readable in client-side code. (RedHunt Labs)
$13 to $8,000 With no rate limiting, OWASP documents a bill jumping from $13 to $8k from unrestricted resource consumption. (OWASP API4:2023)
~45% ship a flaw Veracode found ~45% of AI-generated code introduces a known security flaw. (Veracode 2026)

hole one

Exposed secrets

Most vibe-coded apps accidentally ship API keys inside the front end (your OpenAI key, database URL, Stripe keys), which means anyone can open DevTools, copy them, and use your backend on your dime. This prompt finds them, moves the real ones server-side, and tells you which to rotate.

๐Ÿ”‘ find and move leaked secrets
Spin up 3 sub-agents to audit this repo for exposed secrets and fix them.
Sub-agent 1: scan everything that ships to the browser (src/, components/, pages/, public/, and any VITE_* or NEXT_PUBLIC_* variables) for hardcoded API keys, database URLs, Stripe keys, and auth tokens. Report every hit as file + line number.
Sub-agent 2: scan the full git history (git log -p) and any committed .env files, because deleted keys stay live in old commits.
Sub-agent 3: sort each finding into "true secret" (OpenAI/Stripe secret key, Supabase service_role, DB connection string, must move server-side) vs "publishable/anon key" (only safe if Row Level Security is on).
Then give me one table (file, line, key type, risk). For each true secret: move it into a server-side .env file, add .env to .gitignore, and replace the client call with a backend API route / serverless function / Supabase Edge Function that reads the key from process.env so it never reaches the browser. Finish with a checklist of exactly which live keys I must ROTATE now, because deleting them from code does not revoke them. Never print the actual key values.
Rotate, do not just delete. Deleting a key from your code does not revoke it. A key that was ever committed is compromised, so generate a new one and retire the old one in the provider's dashboard. (OWASP Secrets Management; on the anon vs service_role rule, Supabase API keys.)
hole two

No rate limiting

With no limits, anyone can spam your backend with unlimited requests, crash your API, or quietly drain your account on the endpoints that cost money per call. This prompt finds those endpoints and adds real throttling.

๐Ÿšฆ add real rate limiting
Spin up 3 sub-agents to add rate limiting to this app.
Sub-agent 1: list every API route / endpoint / serverless function, and flag the ones that cost money per call (they hit a paid API like OpenAI, an email/SMS provider, or my database) or have no auth. Those are the "denial of wallet" targets.
Sub-agent 2: check what protection already exists (any per-IP or per-user throttle, any HTTP 429 handling) and report what is missing.
Sub-agent 3: detect my stack and write the limiter. Use express-rate-limit if this is Express, or @upstash/ratelimit with a sliding window if this is Next.js / serverless / edge. Limit by IP AND by logged-in user, return HTTP 429 with a Retry-After header, and set a tighter limit on the expensive AI routes than on the cheap ones.
Then apply it to every endpoint sub-agent 1 flagged, show me the diff, and give me one line per endpoint explaining the limit you chose.
The tools here are all standard: express-rate-limit, @upstash/ratelimit, and OWASP calls this class of risk "denial of wallet" (LLM10:2025).
hole three

No input validation (the scary one)

If your app blindly trusts user input, someone can inject bad data, break your database, or run malicious queries, and AI-generated apps skip this step most of the time. This prompt adds server-side validation and locks the database itself.

๐Ÿ›ก๏ธ add input validation + lock the database
Spin up 3 sub-agents to fix input validation across this app.
Sub-agent 1: find every place user input enters (form handlers, API route bodies, URL/query params, webhooks) and list each with file + line.
Sub-agent 2: check whether each one is validated on the SERVER before use (browser-only validation does not count, it is bypassable), and flag any raw SQL that concatenates user input instead of using parameterized queries.
Sub-agent 3: if this is a Supabase/Postgres app, list every table and whether Row Level Security is on, because the public anon key can read any table with RLS off.
Then: add a Zod schema for each input and reject bad data server-side with .safeParse(), convert concatenated SQL to parameterized queries (or the Supabase client / Prisma), and write the missing RLS policies so the database itself enforces who can read and write each row. Show me the before and after for every fix.
The building blocks: Zod for schemas, Supabase Row Level Security, and OWASP's rule that validation must happen server-side (Input Validation, SQL Injection Prevention).

after you run them

Finish clean

  1. ๐Ÿ‘€ Review every diff. These prompts edit real files. Read what each one changed before you accept it, so you understand your own app.
  2. ๐Ÿ”„ Rotate the flagged keys. Go into each provider (OpenAI, Stripe, Supabase, your DB) and issue new keys for anything that was ever exposed. This is the step people skip.
  3. ๐Ÿš€ Re-deploy and re-check. Ship the fixes, then open DevTools on the live site and confirm no secrets sit in the shipped bundle. Green means done.
the waitlist is now open

AI System Club is launching soon

Build AI systems with me through recorded lessons you can follow at your own pace. Join the waitlist for first access and the founding price.

btw this list gets first dibs
the moment doors open :)