reference from: Claude Code for Beginners

The Vibe Coding Security Checklist (20 Points)

by J Cook · 8 min read·

Summary:

  1. AI code tools write functional code, not secure code. Five vulnerability types appear in nearly every vibe-coded project.
  2. Full 20-point security checklist organized by category: Authentication, Input Validation, Data Access, Infrastructure.
  3. Copy-paste grep commands that find hardcoded secrets in 30 seconds.
  4. The XSS test you can run right now to see if your app is vulnerable.

A Reddit post titled “Why the majority of vibe coded projects fail” hit 7,600 upvotes and 690 comments on r/ClaudeAI. The top-voted responses weren’t about bugs or UX. They were about security. One commenter put it bluntly: “A vibe coded product using sensitive info like bank details is asking for a security breach that will get your ass sued.”

That post didn’t go viral because security is abstract. It went viral because 7,600 people recognized themselves. They’d shipped AI-generated code without checking it. They’d seen the gaps after the fact.

This checklist exists so you check before shipping. It’s practical security hygiene, not enterprise security engineering. Ten minutes, twenty checks, and you’ll know exactly where the gaps are.

Where does AI-generated code actually leak data?

Five places. The same five, every single project. AI code tools optimize for “does it work?” They do not optimize for “is it safe?” That gap creates the same vulnerabilities on repeat.

1. Authentication that looks right but isn’t. Sessions work. Logins work. But session tokens might be in regular cookies instead of httpOnly cookies (JavaScript can steal them). The auth secret might be a placeholder value. There’s no rate limiting on login, so an attacker can try a thousand passwords per second.

2. Input validation that doesn’t exist. The form accepts whatever the user types. The database stores it. The page renders it. No sanitization, no length limits, no server-side checks.

3. Database queries that trust user input. Insecure Direct Object References (IDOR) are the most common variant. If your API fetches a record by ID without checking ownership, anyone who guesses the ID can read someone else’s data. Raw SQL without parameterized inputs is the other variant.

4. Environment variables that aren’t environment variables. API keys, database URLs, auth secrets sitting in source code instead of .env files. Or worse, .env files that were committed to git history.

5. Dependencies with known vulnerabilities. Your node_modules has hundreds of packages. Some have published CVEs. npm audit checks all of them against a vulnerability database in five seconds.

How do you test for XSS right now?

Open your app. Find any text input field. Type this as the value:

<script>alert('hacked')</script>

Submit the form. If you see an alert box pop up, your app has a cross-site scripting vulnerability. Anyone can inject JavaScript through your input fields.

If the text renders as plain text on the page (you see the literal <script> tag as characters, not as executed code), your inputs are sanitized. You pass this check.

This takes ten seconds. It catches the single most common vulnerability in AI-generated frontend code. If your app fails this test, every other input field is suspect too.

What’s the full 20-point checklist?

Run this on every project before real users touch it. Each item gets a PASS, FAIL, or N/A.

Authentication (5 points)

#CheckWhat to look for
1Passwords hashedbcrypt or argon2, never plain text storage
2Session tokens in httpOnly cookiesNot accessible by client-side JavaScript
3Auth secret is realRandom value, not a placeholder like “secret123”
4Login rate limitingMax 5 attempts per minute per IP
5Password reset tokens expireWithin 1 hour of issuance

Input Validation (5 points)

#CheckWhat to look for
6Server-side validation on all inputsClient-side alone is not security
7HTML sanitized from text inputsPrevents XSS (run the script tag test)
8Input lengths limitedPrevents memory exhaustion attacks
9File uploads validatedType and size checked, if applicable
10Unexpected API parameters rejectedEndpoints don’t silently accept extra fields

Data Access (5 points)

#CheckWhat to look for
11Every query includes userId checkNo fetching records by ID alone
12No raw SQL, or parameterized inputsPrisma/ORM queries preferred
13API responses don’t leak sensitive dataNo password hashes in JSON responses
14Admin endpoints require role verificationIf applicable
15Deleted data is actually deletedNot just hidden with a soft-delete flag

Infrastructure (5 points)

#CheckWhat to look for
16.env in .gitignoreNever committed to git
17No hardcoded secrets in sourceUse the grep commands below
18npm audit shows zero high/criticalRun weekly
19HTTPS enforcedVercel/Netlify handle this automatically
20CORS configuredAllow only your domain, block all other origins

Score: 20/20 is a solid baseline to ship with confidence. Anything less means fix the failures before real users touch it.

How do you find hardcoded secrets in 30 seconds?

Three commands. Copy them, run them, read the output.

# Find hardcoded secrets in source files
grep -r "sk_\|pk_\|password=\|secret=" src/ --include="*.ts" --include="*.tsx"

# Check if .env was ever committed to git history
git log --all -- .env .env.local .env.production

# Find API keys or tokens in any file
grep -rn "Bearer \|apiKey\|API_KEY" src/

If any of those return results, you have secrets in your source code. Here’s the full cycle: I ran the first grep on a project and found password="admin123" in a seed file and sk_test_abc123 in a Stripe integration file. Both were placeholders Claude created during setup that never got moved to .env. Fix: moved both values to .env.local, replaced the hardcoded strings with process.env.DB_SEED_PASSWORD and process.env.STRIPE_SECRET_KEY, and added .env* to .gitignore. Two minutes. Two critical vulnerabilities closed.

The git log command is the one people miss. Your .env file might be in .gitignore now, but if it was ever committed, the secrets are in your git history. Anyone who clones the repo can see them. If you pushed to a public repo with secrets in history, those secrets are compromised. Generate new ones.

How does AI code security compare to manual code security?

The vulnerabilities are the same. The difference is frequency.

VulnerabilityHand-written codeAI-generated codeWhy the gap
Missing input validationCommonNearly universalAI skips validation unless prompted
Hardcoded secretsOccasionalFrequentAI uses placeholder values during setup
IDOR (broken access control)CommonVery commonAI fetches by ID without ownership checks
Outdated dependenciesVariesSameBoth depend on npm audit discipline
XSSDeclining (frameworks help)CommonAI sometimes bypasses framework protections
SQL injectionRare (ORMs help)RareBoth benefit from parameterized queries
Missing rate limitingCommonNearly universalAI never adds rate limiting unprompted
Weak session handlingOccasionalFrequentAI defaults to basic cookie settings

The pattern is clear: same vulnerability types, higher frequency. A human developer might forget rate limiting. An AI tool will never add it unless you ask. That one difference turns “common” into “nearly universal” across three of the eight categories.

How do you fix the five most common failures?

Each fix is a single prompt to your AI code tool.

Missing input validation (checklist items 6-10):

Add server-side input validation to all API endpoints and server
actions. Sanitize HTML from all text inputs. Limit titles to 200
characters, descriptions to 2000 characters. Return clear error
messages for invalid input. Validate on the server, not just
the client.

Broken access control (checklist item 11):

Verify that every database query that fetches user data also
checks that the record belongs to the authenticated user. If
any query fetches by ID alone without a userId check, add the
check. Show me every query you changed.

Hardcoded secrets (checklist items 16-17):

Search the entire codebase for hardcoded API keys, database
URLs, auth secrets, and tokens. Move all of them to environment
variables. Ensure .env is in .gitignore. Show me what you found
and where you moved it.

Missing rate limiting (checklist item 4):

Add rate limiting to all API endpoints and server actions.
Max 5 attempts per minute per IP for login. Max 30 requests
per minute per user for write operations. Max 60 per minute
for reads.

Dependency vulnerabilities (checklist item 18):

npm audit
# Then tell your AI tool:
# "Run npm audit and fix any vulnerabilities. For vulnerabilities
# that can't be auto-fixed, tell me what they are and the risk level."

How should you test AI-generated code?

Start with integration tests, not unit tests. AI generates complete features, not individual functions. Your most valuable test verifies the whole path: create a record, confirm it appears, change its status, confirm the update.

Use a real test database, not mocks. Mocked tests confirm your code calls the right functions. Integration tests with a real database confirm data actually saves and retrieves correctly. I’ve seen AI-generated code pass all mocked tests and fail with a real database because the migration was wrong.

How many tests: 20-25 total for a standard CRUD app.

  • 3-4 per CRUD operation (create, read, update, delete)
  • 1-2 per auth scenario (login success, login failure, unauthenticated access)
  • 1 per input validation rule (max length, required fields, sanitization)

The test suite should run in under 10 seconds. You don’t need 100% coverage. You need 100% confidence that the critical paths work.

What should you actually do?

  • If you haven’t run ANY security check: start with the three grep commands and the XSS test. Five minutes, and you’ll know whether you have urgent problems.
  • If you’re about to deploy: run the full 20-point checklist. Copy the prompts above to fix every FAIL. The audit takes ten minutes. The fixes take another ten.
  • If you’re already live with users: run npm audit first (dependency vulnerabilities are the fastest to exploit remotely), then the grep commands (hardcoded secrets are the most damaging), then the full checklist.
  • If you want ongoing protection: run npm audit weekly. Re-run the 20-point checklist after every major feature. Add integration tests that double as security tests (a test for “unauthenticated user gets 401” is also an auth security test).

bottom_line

  • AI code tools write code that works. They do not write code that’s secure. Five vulnerability types appear in nearly every vibe-coded project: missing validation, broken access control, hardcoded secrets, no rate limiting, and weak session handling.
  • The 20-point checklist catches all five. Run it before any real user touches your app. Aim for 20/20 as your shipping baseline.
  • Three grep commands find hardcoded secrets in 30 seconds. One XSS test in any input field tells you if validation exists. These two checks alone catch the majority of critical vulnerabilities in AI-generated code.

Frequently Asked Questions

Is AI-generated code safe to deploy without a security review?+

No. AI code tools optimize for 'does it work,' not 'is it safe.' They skip input validation, hardcode secrets, and leave auth gaps unless you explicitly ask. A 20-point audit catches the five most common vulnerability types.

How long does a vibe coding security audit take?+

About ten minutes per project. Run the grep commands to find hardcoded secrets, test XSS with a script tag in any input field, and walk through the 20-point checklist. Most fixes are one-line changes.

What's the most common security flaw in vibe-coded apps?+

Missing input validation. AI tools rarely add server-side validation unless you ask for it. Forms accept anything, databases store anything, pages render anything. One XSS test exposes the gap in seconds.