The 10-minute security checklist for AI-generated code
45% of AI-generated code contains security flaws. Before you ship your vibe-coded app, run through this practical checklist. No security expertise required.
Your AI wrote vulnerable code
This is not a scare tactic. A 2025 Veracode study found that 45% of AI-generated code contains security vulnerabilities. A CodeRabbit analysis showed AI-assisted pull requests have 2.74 times more security issues than human-written code.
The problem is not that AI is bad at coding. The problem is that AI optimizes for "works correctly" and not "works securely." It will build a login system that authenticates users but forget to hash passwords. It will create an API endpoint that returns data but skip authorization checks.
You do not need to become a security expert. You need a checklist.
Before you start: the mindset shift
Security is not something you add at the end. But if you already have a working app, the next best time to check is right now. This checklist is designed to catch the most common and most dangerous flaws in AI-generated code.
Go through each section. Check the relevant parts. Fix what you find. The whole thing should take about 10 minutes for a small project.
1. Authentication
Authentication is who you are. This is where AI makes the most dangerous mistakes.
Check these:
- Passwords are hashed before storage (look for
bcrypt,argon2, orscryptin your code) - If you see passwords stored as plain text or with
md5/sha256, fix this immediately - Login forms have rate limiting (5-10 attempts, then a cooldown)
- Session tokens are random and long (at least 32 characters)
- Sessions expire after a reasonable time (hours, not years)
- Logout actually destroys the session on the server, not just the client
Common AI mistake: Generating a session token with Math.random() or storing it in localStorage. Both are insecure. Use your auth library's built-in session management.
If you used a proper auth library (Better Auth, NextAuth, Clerk, Lucia), most of these are handled for you. Check that you are using it correctly rather than building auth from scratch.
2. Authorization
Authorization is what you are allowed to do. This is the flaw AI misses most often.
Check these:
- Every API endpoint checks if the logged-in user owns the resource they are requesting
- A user cannot view, edit, or delete another user's data by changing an ID in the URL
- Admin-only routes verify admin status on the server, not just in the frontend
- Deleting or modifying data requires the same permission check as viewing it
Test it yourself: Log in as User A. Copy the URL of one of User A's resources. Log in as User B. Paste that URL. If User B can see User A's data, you have a broken authorization check.
Common AI mistake: Checking permissions in the frontend but not on the API route. Frontend checks are cosmetic. Anyone can call your API directly with a tool like curl or Postman.
3. Input validation
Never trust data that comes from a user, a form, a URL parameter, or an API request.
Check these:
- All form inputs are validated on the server (not just client-side)
- SQL queries use parameterized queries or an ORM (never string concatenation)
- User input is sanitized before displaying it in HTML (prevents XSS)
- File uploads check file type and size on the server
- URL parameters and query strings are validated before use
Test it yourself: Try entering <script>alert('xss')</script> in a text field. If an alert pops up anywhere on the site, you have an XSS vulnerability.
Common AI mistake: Building SQL queries with template literals:
// DANGEROUS - AI generates this often
const user = db.query(`SELECT * FROM users WHERE id = '${userId}'`)
// SAFE - use parameterized queries
const user = db.query('SELECT * FROM users WHERE id = ?', [userId])4. API keys and secrets
AI-generated code loves to put secrets in the wrong place.
Check these:
- No API keys, passwords, or tokens in your source code files
- All secrets are in environment variables (
.envfile locally, platform config in production) - Your
.gitignoreincludes.env(so secrets never get committed to Git) - Client-side code does not contain any secret keys (anything in the browser is public)
- If you use a third-party API, calls go through your server, not directly from the browser
Search your codebase:
# Look for common secret patterns
grep -r "sk_live" ./src
grep -r "sk-" ./src
grep -r "apiKey:" ./src
grep -r "PRIVATE" ./src
Common AI mistake: Putting a Stripe secret key or database password directly in a React component or a client-side file. Anything that starts with NEXT_PUBLIC_ in Next.js is visible to everyone.
5. Data exposure
Your API might be returning more data than your frontend displays.
Check these:
- API responses do not include password hashes, tokens, or internal IDs
- Error messages do not expose database structure, file paths, or stack traces
- List endpoints have pagination (returning 10,000 rows crashes your server and exposes data)
- Sensitive data is not logged to the console in production
Test it yourself: Open your browser's Network tab. Click through your app. Look at the API responses. If you see fields like passwordHash, internalNotes, or adminEmail in the response, your API is leaking data.
Common AI mistake: Returning the full database row from an API endpoint instead of selecting only the fields the frontend needs.
// LEAKY - returns everything including password hash
app.get('/api/user/:id', (req, res) => {
const user = db.getUser(req.params.id)
res.json(user)
})
// SAFE - return only what the frontend needs
app.get('/api/user/:id', (req, res) => {
const user = db.getUser(req.params.id)
res.json({ id: user.id, name: user.name, avatar: user.avatar })
})6. HTTPS and transport security
Data in transit can be intercepted if not encrypted.
Check these:
- Your site is served over HTTPS (not HTTP)
- All API calls use
https://URLs - Cookies have the
Secureflag set (so they are only sent over HTTPS) - Cookies have the
HttpOnlyflag set (so JavaScript cannot read them) - If you set cookies, the
SameSiteattribute is set toLaxorStrict
Most modern hosting platforms handle HTTPS automatically. But if your AI generated any hardcoded http:// URLs, those need to change.
7. Rate limiting
Without rate limiting, anyone can hammer your API with thousands of requests per second.
Check these:
- Login and signup endpoints have rate limits
- Password reset endpoints have rate limits
- Any endpoint that sends emails or SMS has strict rate limits
- Public API endpoints have reasonable request limits
If your framework does not have built-in rate limiting, add a middleware. For Express, express-rate-limit works. For Next.js, use a library like @upstash/ratelimit or implement rate limiting at the infrastructure level.
Common AI mistake: Not adding rate limiting at all. AI tends to generate the happy path and ignores abuse scenarios entirely.
8. Dependencies
Your app is only as secure as its weakest dependency.
Check these:
# Run a security audit
npm audit
# For a more thorough check
npx audit-ci --moderate
- Fix or replace packages with known vulnerabilities
- Remove packages you are not actually using (AI often installs packages and then does not use them)
- Check that you are not using abandoned packages (no updates in 2+ years)
The 60-second version
If you only have a minute, check these three things:
- Secrets in code: Search for API keys and passwords in your source files. Move them to environment variables.
- Authorization on APIs: Make sure every API endpoint checks that the logged-in user owns the data they are requesting.
- Input validation: Make sure user input is validated on the server, not just the client.
These three cover the majority of real-world exploits against vibe-coded apps.
Security is not optional
A startup founder recently shared a story about their vibe-coded SaaS: within days of launch, users bypassed the paywall, spam bots flooded the API, and the database filled with garbage. The app had no real auth, no rate limiting, and no input validation.
AI built all the features perfectly. It just skipped the locks on the doors.
You do not need to be a security expert. You just need to check the doors before you invite people in.
Building on noprod? Our workspace template includes authentication, input validation, and proper session handling out of the box. Start building securely.