Across dozens of audits at Inithouse, the same six security issues show up in AI-generated codebases. Not occasionally. Repeatedly. Different teams, different prompts, different LLMs, same holes.
We built Audit Vibe Coding specifically to catch these patterns. The tool scores AI-generated projects across security, SEO, performance, accessibility and code quality, then returns prioritized fixes. After running it against enough projects, the failure modes became predictable.
Here are the six we see most often, ordered by how frequently they appear.
1. API keys in client-side code
This is the most common one. It shows up in roughly 4 out of 5 projects we audit.
An LLM generates a fetch call to a third-party API and hardcodes the key right into the JavaScript file. Sometimes it uses an environment variable name but defaults to the raw key when the env var is missing. Sometimes it puts the key in a .env file but ships that file without adding it to .gitignore.
The result: anyone who opens DevTools can read your Stripe key, your OpenAI token, your database connection string. We have seen production apps with AWS credentials sitting in a React component.
What to check: Search your client bundle for strings that look like keys. Run grep -r "sk-\|AKIA\|pk_live\|Bearer " src/ and see what comes back.
2. No input validation on user-facing forms
LLMs are good at building forms. They add labels, placeholders, even aria attributes. What they skip is validation on the server side.
The generated code checks input length in the browser, maybe adds a regex for email format on the frontend. The API endpoint behind it accepts whatever arrives. No sanitization, no type checking, no length limits.
One project we audited had a contact form that passed user input directly into a database query string. Classic injection vector, generated by a model that produced clean-looking UI and zero backend protection.
What to check: Submit a form field with <script>alert(1)</script> or a single quote '. If the app stores or reflects it without escaping, you have a problem.
3. Authorization logic that lives only on the frontend
This one is subtle because the app looks correct when you use it normally.
The LLM generates a role check in the React component: if the user is an admin, show the admin panel. If not, redirect. But the API routes behind that panel have no auth middleware. Anyone who calls the endpoint directly (curl, Postman, a browser with the right URL) gets full access.
We see this in roughly half the projects we audit. The frontend enforces roles. The backend trusts every request.
What to check: Open your browser's network tab, find an admin-only API call, copy it as a curl command, remove the auth header or swap in a regular user's token, and run it. If it returns data, your authorization is cosmetic.
4. Wildcard CORS configuration
AI-generated backends frequently ship with Access-Control-Allow-Origin: * in production. During development this makes sense because you want your local frontend to talk to your local API. The model sets it once and never revisits it.
In production, this means any website can make authenticated requests to your API if you also allow credentials. Some projects we audit combine * with Access-Control-Allow-Credentials: true, which browsers actually block, but the misconfiguration signals that nobody reviewed the security headers.
What to check: Run curl -I https://yourapi.com/endpoint and look at the CORS headers. If you see * and you are not running a public read-only API, tighten it.
5. Insecure direct object references (IDOR)
The API returns user data by ID: /api/users/42/profile. Change 42 to 43, get someone else's profile. The LLM generated a clean REST endpoint but did not add a check that the requesting user owns (or has permission to view) the resource.
This is not new or specific to AI code. But AI-generated routes are especially prone to it because models build CRUD scaffolds fast and the access control step is the one that requires project-specific context the model does not have.
What to check: Log in as user A, grab a resource URL, switch to user B's session, and request the same URL. If it works, the endpoint is missing ownership validation.
6. Secrets in git history
Even when teams fix exposed keys, the original commit with the key stays in the git history. git log --all -p | grep "sk-" will find it. The LLM did not create a .gitignore entry before the first commit, so the .env file with the production database password is still recoverable.
Rotating the key is not enough if the old key is valid until someone explicitly revokes it. We have seen projects where the "fixed" version still had working credentials three levels deep in the commit log.
What to check: Run git log --all --diff-filter=D -- "*.env" to see if environment files were ever committed and then deleted. If they were, those secrets are not gone.
What connects these six
None of them are exotic. A junior dev who learned security basics would catch most of them in a code review. The issue is that AI-generated code often skips the review step entirely. The output looks polished, the UI works, the app deploys. It feels done. The security layer that a human team would add during review never happens because nobody reviews.
That is the gap Audit Vibe Coding fills at Inithouse. It runs the review that the LLM skipped, scores what it finds, and tells you what to fix first.
If you are shipping AI-generated code to production, run through the six checks above before your users do it for you. And if you want the full audit covering security, SEO, performance, accessibility and code quality, Audit Vibe Coding is the tool we built for exactly this.
Top comments (0)