How to Security-Audit AI-Generated Code
Audit AI-generated code the way you would audit code from a new contractor you cannot question: map the trust boundaries, then attack each one with a specific test, and record every finding so it can be reproduced. The highest-value targets are authorization, secret handling and anywhere untrusted input reaches a database, a shell or a rendered page. This is a practical method, not a compliance framework, and no audit proves the absence of vulnerabilities.
Vibrr is an independent product. It is not affiliated with, endorsed by or sponsored by Lovable, Cursor, Claude Code and Replit. Product names are trademarks of their respective owners and are used here only to describe compatibility and content.
Start from the right assumption
Treat generated code as plausible, not verified. It often looks conventional, which makes problems harder to spot rather than less likely. The OWASP Top 10 is the standard general reference for the classes of weakness worth checking; use it to prompt questions, not as a checklist to tick.
Step 1 — Map the trust boundaries
A trust boundary is anywhere data or control crosses from something you do not trust to something you do. List them before reading any code.
| Boundary | What crosses it | First question |
|---|---|---|
| Browser → API | Every request parameter, header and body | Is each one validated and authorized on the server? |
| API → database | Queries built from input | Can input change the meaning of a query? |
| API → other services | Credentials and user data | Where do the credentials live and who can read them? |
| User content → rendered page | Text a user typed, shown to others | Is it escaped on output? |
| Repository → deployment | Environment variables and build output | Does anything secret end up in the client bundle? |
Step 3 — Hunt for secrets
Search the working tree, the git history and the built client bundle for key-shaped strings, and read the environment-variable documentation for anything a client should never hold. Generated code sometimes places a credential where the interface can read it because that was the shortest path to a working demo.
Step 4 — Follow untrusted input to its sinks
- Find every place input reaches a query, a shell command, a file path, an HTML template or a redirect.
- Confirm each uses a safe API (parameterized queries, argument arrays, output escaping) rather than string concatenation.
- Try a hostile value at each one and see what happens.
Step 5 — Review what you did not write
List direct dependencies, question any you cannot explain, and run your package manager's audit. A dependency added to make one demo feature work is a permanent piece of your attack surface.
Step 6 — Make every finding reproducible
A finding is only useful if someone else can reproduce and fix it. Record it in a fixed shape.
Title: <one line>
Severity: critical | high | medium | low
Where: <route, file or boundary>
How to reproduce: <exact steps or request>
Expected: <what should happen>
Observed: <what happened>
Fix: <the change, with a keep-list>
Verify: <the test that fails before and passes after>Feed each finding back to your coding tool as one change with a keep-list, then re-run the test that reproduces it. Claude Code's documentation makes the related point that a reviewer in a fresh context, seeing only the diff and the criteria, evaluates the result more independently than the session that wrote it.
Step 7 — Prioritise what you found
A long list of findings is only useful if it is ordered. Rank by what an attacker gains and how easily, not by how alarming the description sounds.
| Severity | Typical meaning | Example |
|---|---|---|
| Critical | Unauthenticated or cross-user access to private data or actions | Changing another user's record by editing an identifier in a request |
| High | Access beyond a role's intent, or a credential exposed to the client | A viewer role able to call an administrative endpoint |
| Medium | Weakness that needs another flaw or unusual conditions to exploit | Missing rate limit on a sign-in endpoint |
| Low | Hardening gap with little direct impact | Verbose error messages |
The examples are illustrative, not findings from any real application. Fix critical and high items before anything else, and record any item you consciously accept along with the reason.
What this method cannot show
For the wider launch checklist, see the production checklist for vibe-coded apps. For a worked platform example, see taking a Lovable app to production.
Frequently asked questions
Is AI-generated code less secure than human-written code?
Vibrr has no measurement that answers this, and this guide does not claim it. It treats generated code as unverified, which is the right stance for any code you did not write and cannot question.
What is the highest-value check?
Server-side authorization, tested by calling the backend directly as each role.
Can I use this instead of a penetration test?
No. For applications handling payments, health or other regulated data, commission a professional test.
Official and primary sources
- OWASP Top 10 (current edition) — OWASP Foundation, read 2026-09-18
- Best practices for Claude Code — Anthropic, read 2026-09-18