Vibe Coding Security Series
- What Is Vibe Coding Security? A Field Guide for 2026
- The OWASP Top 10 for Vibe-Coded Applications (you are here)
- Anatomy of a Vibe Coding Breach: Lessons from 2026’s Worst Incidents
- The Dependency Trap: Supply Chain Risks in AI-Generated Code
- Authentication & Secrets: What AI Gets Wrong Every Time
- [Scanning Vibe-Coded Apps: Why Traditional SAST/DAST Falls Short] (https://simonroses.com/2026/05/scanning-vibe-coded-apps-why-traditional-sast-dast-falls-short-part-6/)
- Prompt Engineering for Secure Code (coming soon)
- The Founder’s Security Checklist (coming soon)
- Securing the AI Coding Pipeline (coming soon)
- The Future of Vibe Coding Security (coming soon)
Read Time: 15 minutes
TL;DR
The OWASP Top 10 got a major update in 2025 — the first since 2021 — and it maps surprisingly well to the vulnerabilities I keep finding in vibe-coded applications. But here’s the thing: when AI writes the code, these classic vulnerability categories don’t just show up. They show up differently. Injection isn’t the same when nobody wrote the query. Broken access control isn’t the same when the AI puts auth checks in the browser. Security misconfiguration isn’t the same when the developer can’t tell you what the AI configured.
This post walks through all ten categories and shows how each one manifests in AI-generated code, with concrete examples from real-world cases and data from Veracode, Apiiro, Escape.tech, and Wiz. If you read the Field Guide (Part 1 in this series), you know the attack surface. This post maps it to the framework every security team already uses.
Why This Mapping Matters
At VULNEX, when we do penetration testing for clients, we report findings against OWASP. It’s the shared language of web application security. Every security team knows it. Every compliance framework references it. So when I started consistently seeing vibe-coded apps in our pipeline — MVPs, internal tools, startup products built with Cursor, Bolt, Lovable — the question wasn’t whether they’d have OWASP issues. It was which issues, and how the AI’s involvement changed the nature of the findings.
After dozens of these assessments, I can tell you: the categories are the same, but the root causes are fundamentally different. When a human developer ships a SQL injection, it’s usually because they made a shortcut under deadline pressure. They know it’s wrong. When an AI ships a SQL injection, it’s because string-concatenated queries appear millions of times in the training data and the model has no concept that there’s anything wrong with them.
That distinction matters for remediation. You can’t just point a vibe coder at the OWASP testing guide and tell them to fix their code. They didn’t write it. In many cases, they can’t read it.
OWASP published the 2025 edition in November — the first refresh since 2021. Two new categories (Supply Chain Failures and Mishandling of Exceptional Conditions), SSRF merged into Broken Access Control, and updated data across the board. Here’s how each category plays out when the AI wrote the code.
A01:2025 — Broken Access Control
The classic: Users access resources or perform actions beyond their intended permissions.
The vibe-coded version: The AI puts the access controls in the wrong place.
This is the number-one finding in the OWASP 2025 update, with 100% prevalence across tested applications. And in vibe-coded apps, I see it in nearly every engagement. The pattern is always the same: the AI generates a beautiful frontend with role-based UI elements — admin buttons hidden for regular users, premium features visually gated — and puts zero enforcement on the server side.
I wrote about Enrichlead in the Field Guide. That’s the textbook case: a Cursor-built SaaS where every access control was client-side JavaScript. Users bypassed the entire subscription by changing a value in the browser console. But I’ve seen this pattern dozens of times since. It’s not a Cursor problem. It’s an AI code generation problem.
Here’s what the AI typically generates for a “protected” admin route:
// Frontend route guard — what the AI generates
const AdminPage = () => {
const { user } = useAuth();
if (user.role !== 'admin') return <Navigate to="/" />;
return <AdminDashboard />;
};
Looks secure. The admin page redirects non-admins. But hit the API directly — GET /api/admin/users — and there’s no middleware checking roles. The API returns everything to anyone. The AI built the appearance of access control without the reality of it.
Apiiro’s research across Fortune 50 enterprises found that AI-generated code creates 322% more privilege escalation paths than human-written code. Not 22%. Three hundred and twenty-two percent. The AI is excellent at building the UI. It’s terrible at building the enforcement layer.
Wiz Research confirmed this pattern at scale: 20% of vibe-coded apps they analyzed had serious vulnerabilities, with missing authentication and misconfigured database security (specifically, absent or permissive Row-Level Security policies) among the top findings.
A02:2025 — Security Misconfiguration
The classic: Default credentials, unnecessary features enabled, missing security headers, verbose error messages.
The vibe-coded version: Nobody knows what the AI configured.
This one drives me crazy during assessments. With a traditional app, you can sit down with the dev team and walk through their configuration decisions. With a vibe-coded app, the developer literally cannot tell you why the AI chose a particular framework configuration, what defaults it left in place, or what security headers it did or didn’t set.
In my C1b3rWall demo — the QuickNote app I built deliberately insecure for the talk — the AI happily shipped with DEBUG=True, stack traces exposed to the browser, CORS set to *, and no rate limiting on any endpoint. Every single one of those is a security misconfiguration. And every single one came from the AI’s default behavior, not from a conscious decision by a developer.
Escape.tech’s audit of 5,600 vibe-coded apps found that 65% had security issues and 58% contained at least one critical vulnerability. Exposed Supabase tokens retrievable from frontend bundles. Misconfigured APIs. Missing RLS policies. These aren’t sophisticated bugs. They’re misconfigurations that the AI left in place because nobody told it to change them — and nobody knew to check.
The AI’s training data is overwhelmingly tutorial code. Tutorials optimize for clarity, not security. They leave debug mode on. They disable CORS restrictions. They skip rate limiting. When the AI generates a production application based on those patterns, you get a production application with tutorial-grade configuration.
A03:2025 — Software Supply Chain Failures
The classic: Compromised dependencies, lack of integrity verification, insecure CI/CD pipelines.
The vibe-coded version: The AI picks your dependencies, and some of them don’t exist.
This is a brand-new OWASP category for 2025 — and it’s one of the most relevant for vibe-coded apps. I covered the dependency problem in the Field Guide, but it’s worth drilling into the OWASP context.
The AI doesn’t just write logic. It imports packages. When you prompt “build me a user registration form with email validation,” the model reaches into its training data and pulls whatever packages were popular when it was trained. Those versions may be six months or a year old. They may have known CVEs that were patched weeks after the model’s training cutoff.
But the supply chain risk goes deeper than outdated versions. LLMs sometimes generate import statements for packages that don’t exist — hallucinated packages. Researchers have documented this phenomenon repeatedly: attackers monitor AI-generated code for hallucinated package names, register those names on npm or PyPI, and upload malware. Someone runs npm install on their AI-generated package.json and pulls a package the AI invented, except now an attacker owns the name.
This is the same supply chain class I covered in the Skill Poisoning article, but applied to package registries rather than agent skills. The attack surface is structurally identical: an ecosystem where names are trusted and registration is easy, combined with an automated system that generates plausible-sounding names.
At VULNEX, we now run SCA scans as the first step on every vibe-coded app engagement. In at least a third of cases, we find dependencies with known vulnerabilities that the AI pulled from its training data.
A04:2025 — Cryptographic Failures
The classic: Weak algorithms, missing encryption, improperly managed keys.
The vibe-coded version: The AI defaults to whatever crypto pattern has the most Stack Overflow upvotes.
This is one of those areas where the headline stat — Veracode’s 86% pass rate for CWE-327 (cryptographic algorithm selection) — actually masks the real problem. Models are decent at picking AES over DES when you explicitly ask for encryption. Where they consistently fail is in the surrounding crypto decisions: how keys are managed, how passwords are hashed, how tokens are stored. Their Spring 2026 update showed that despite newer models, overall security pass rates remain flat at around 55% — models have gotten much better at writing code that compiles, but not code that’s secure.
Here’s what I consistently see in vibe-coded applications:
// What the AI generates for password hashing
const crypto = require('crypto');
const hash = crypto.createHash('md5').update(password).digest('hex');
MD5. No salt. In 2026. The model generates this because MD5 hashing examples dominate its training data. It should be using bcrypt, scrypt, or Argon2 — but those appear less frequently in tutorials and Stack Overflow answers, so they lose the statistical vote.
JWT handling is another consistent failure. The AI generates a perfectly functional JWT verification function that checks the signature correctly but hardcodes the secret (const JWT_SECRET = 'mysecretkey123'), stores tokens in localStorage (accessible to XSS), and skips issuer or audience validation. Each individual component works. The aggregate is cryptographically broken.
In the QuickNote demo I showed at C1b3rWall, the AI stored passwords with plain MD5 and put the JWT signing secret directly in the source code. That’s two CWEs (CWE-327: Use of a Broken or Risky Cryptographic Algorithm, CWE-798: Use of Hard-coded Credentials) from a single prompt.
A05:2025 — Injection
The classic: SQL injection, XSS, command injection, LDAP injection — untrusted data sent to an interpreter as part of a command or query.
The vibe-coded version: The AI reproduces vulnerable patterns because they’re the most common patterns in the training data.
Injection dropped from #3 in OWASP 2021 to #5 in 2025 — a sign that traditional development practices (parameterized queries, ORMs, auto-escaping template engines) are working. But AI-generated code is dragging the numbers back up.
Veracode’s testing found that AI models fail to prevent Cross-Site Scripting 86% of the time and produce Log Injection vulnerabilities 88% of the time. SQL injection had the best pass rate at 80% — still meaning one in five AI-generated database queries is injectable.
The reason is straightforward. When the most-upvoted Stack Overflow answer for “how to query a database in Node.js” uses string concatenation:
// What the AI learns from training data
const query = `SELECT * FROM users WHERE id = ${req.params.id}`;
db.query(query);
…the model reproduces that pattern. It has no concept that ${req.params.id} is untrusted input. It doesn’t know that parameterized queries exist because they prevent injection. It just generates the statistically most probable code.
For XSS, the pattern is similar. The AI renders user input directly into HTML because that’s what most code examples do:
// AI-generated React component with XSS vulnerability
const Comment = ({ text }) => (
<div dangerouslySetInnerHTML={{ __html: text }} />
);
React normally escapes output by default — which is great. But the moment the AI needs to render rich text, it reaches for dangerouslySetInnerHTML because that’s the pattern in the training data. The function name literally has “dangerously” in it, and the model doesn’t care.
A06:2025 — Insecure Design
The classic: Missing or flawed security architecture. Threat models that were never built.
The vibe-coded version: There is no design. There is no architecture. There is only the prompt.
This is the OWASP category that resonates most deeply with vibe coding. Traditional insecure design means someone designed something insecurely. With vibe coding, there’s often no design at all. The entire architecture is an emergent property of whatever the AI decided to generate based on the prompt.
In the Field Guide, I called this the invisible decision surface — the AI made hundreds of architectural decisions (framework, auth strategy, data model, validation approach, error handling, logging) and nobody knows what they were.
Apiiro’s research found a 153% increase in design-level security flaws in AI-generated code, including authentication bypass and improper session management patterns. These aren’t implementation bugs — they’re architectural failures. The AI built the wrong thing, correctly.
I’ll give you a real example from a VULNEX engagement (anonymized, obviously). A startup built their entire multi-tenant SaaS with a vibe coding tool. The AI generated a clean schema, a functional API, a polished frontend. Beautiful product. One problem: there was no tenant isolation at the database level. Every API query returned data across all tenants. The AI had built a working multi-tenant UI on top of a single-tenant database. That’s not a bug. That’s an architectural flaw that no amount of patching can fix — it requires a redesign.
A07:2025 — Authentication Failures
The classic: Broken authentication, credential stuffing, missing MFA, insecure session management.
The vibe-coded version: The AI builds authentication that looks complete but has fundamental gaps.
Authentication is where the gap between “it works” and “it’s secure” is widest. The AI can generate a complete login flow — registration, login, password reset, session management — that functions correctly for the happy path. The problem is that security lives in the edge cases, and the AI doesn’t test edge cases.
Common failures I see in assessments:
No rate limiting on login endpoints. The AI generates a clean /api/auth/login route. It checks credentials. It returns a token. It never limits attempts. An attacker can brute-force credentials at machine speed.
Password reset tokens that don’t expire. The AI generates a “forgot password” flow with a reset token sent via email. The token works indefinitely. Once intercepted, it’s a permanent backdoor.
Session tokens in URL parameters. I’ve actually seen this. The AI put the session token as a query parameter in redirects, making it visible in server logs, browser history, and referrer headers.
These aren’t exotic vulnerabilities. They’re the basics of authentication security. But the AI doesn’t distinguish between “authentication that works” and “authentication that’s secure,” and most vibe coders don’t know the difference either.
A08:2025 — Software and Data Integrity Failures
The classic: Failure to verify integrity of software updates, critical data, CI/CD pipelines.
The vibe-coded version: The AI generates code that trusts everything.
This category covers a broad class of trust failures, and AI-generated code is particularly vulnerable because LLMs generate code that assumes trust by default. The model doesn’t add integrity checks unless you explicitly ask for them.
Deserialization is a good example. If you prompt the AI to “accept JSON data from the webhook,” it generates code that parses and processes whatever comes in — no signature verification, no schema validation, no source authentication. It trusts the webhook caller because the training data examples trust the webhook caller.
The same pattern applies to file uploads (no file type verification), API integrations (no response validation), and configuration loading (no integrity checking). The AI generates the functional path — receive data, process data, return result — and skips every trust verification step because those steps don’t appear in most training examples.
The Moltbook breach I wrote about previously is a case study in data integrity failure: a platform where autonomous agents published content consumed by other agents, with no content provenance, no cryptographic signing, and no verification at any hop in the trust chain.
A09:2025 — Logging and Alerting Failures
The classic: Insufficient logging, missing alerting, inability to detect breaches.
The vibe-coded version: The AI either logs nothing useful or logs everything including secrets.
This one is almost invisible in a pentest — you don’t discover logging failures by testing from the outside. But when I do architecture reviews on vibe-coded apps, it’s consistently one of the worst areas.
The AI generates functional code with console.log statements scattered for debugging, but there’s no structured logging framework, no audit trail for authentication events, no alerting on failed login attempts, and no log rotation or retention policy. The application runs in production with development-grade logging.
Worse, when the AI does log things, it often logs too much. I’ve seen AI-generated error handlers that dump full request objects — including authorization headers, session tokens, and request bodies containing passwords — straight into plaintext log files. That’s CWE-532 (Insertion of Sensitive Information into Log File) and CWE-117 (Improper Output Neutralization for Logs) in one shot.
Veracode’s testing found that AI models produce Log Injection vulnerabilities 88% of the time — the worst failure rate across all four vulnerability types they tested. The AI simply doesn’t understand that log output is a security-sensitive channel.
A10:2025 — Mishandling of Exceptional Conditions
The classic: Unhandled exceptions, improper error handling, exposed stack traces, denial-of-service through error conditions.
The vibe-coded version: The AI optimizes for the happy path and barely considers what happens when things go wrong.
This is a brand-new OWASP category for 2025, and it describes vibe-coded apps almost perfectly. AI code generation is fundamentally happy-path oriented. The model generates code that handles the expected input and the expected flow. Edge cases, error conditions, resource exhaustion, malformed input, concurrent access patterns — these are afterthoughts at best.
In practice, this means:
Unhandled exceptions that crash the app. The AI generates an API endpoint that parses user input, queries the database, and returns results. If the database connection drops, the app crashes with an unhandled promise rejection. No graceful degradation. No retry logic. No meaningful error response.
Stack traces in production. When an unhandled exception does occur, the default behavior in most frameworks is to return the full stack trace — including file paths, package versions, and sometimes environment variables. The AI never configures production error handling because the training data is overwhelmingly development-mode examples.
Missing input boundary checks. The AI generates a file upload handler that accepts any file of any size. A 10GB upload exhausts memory and crashes the server. That’s denial-of-service through a missing exceptional condition handler.
This connects directly to the design problem (A06). The AI doesn’t plan for failure because it was never given a failure scenario. It generates code that works when everything goes right. Security is about what happens when things go wrong.
The Numbers: OWASP Meets AI
| OWASP Category | AI-Specific Data Point | Source |
|---|---|---|
| A01: Broken Access Control | 322% more privilege escalation paths in AI code | Apiiro (2025) |
| A02: Security Misconfiguration | 65% of vibe-coded apps had security issues | Escape.tech (2025) |
| A03: Supply Chain Failures | 40% increase in secrets exposure in AI projects | Apiiro (2025) |
| A04: Cryptographic Failures | 86% pass on algo selection, but consistent failures in key/password management | Veracode (2025) |
| A05: Injection | 86% XSS failure rate, 88% Log Injection failure rate | Veracode (2025) |
| A06: Insecure Design | 153% increase in design-level security flaws | Apiiro (2025) |
| A07: Authentication Failures | 20% of vibe-coded apps had serious vulns incl. missing auth | Wiz Research (2026) |
| A08: Integrity Failures | 45% of AI-generated code contains security flaws | Veracode (2025) |
| A09: Logging Failures | 88% of AI code produces log injection vulnerabilities | Veracode (2025) |
| A10: Exceptional Conditions | Security pass rate flat at ~55% despite model improvements | Veracode Spring 2026 |
What You Can Do About It
If you’re building with AI coding tools, here’s the minimum:
Before you prompt, define your architecture. Auth strategy. Data model. Which framework, which ORM, which security middleware. Specify all of this in your prompt or, better, in a rules file (.cursorrules, CLAUDE.md). Don’t let the AI make these decisions for you — it will make them based on tutorial patterns, not security requirements.
After every generation, review the OWASP-relevant areas first. Access controls: are they server-side? Crypto: what algorithm, where are the keys? Injection: parameterized queries or string concatenation? Configuration: debug mode, CORS, error handling? Dependencies: known versions, no hallucinated packages? You don’t have to read every line. But you have to check these five areas.
Run automated scanning tuned for AI patterns. Standard SAST rule sets were built for human-written code. They’ll catch some of this, but not all. Tools like Semgrep let you write custom rules targeting the specific patterns AI generates — client-side auth checks, hardcoded secrets in common locations, insecure crypto defaults. I’ll cover the specific tooling landscape in a later post in this series.
If you’re a security professional assessing vibe-coded apps, update your methodology. The OWASP categories still apply, but your checklist needs AI-specific items: check for client-side-only access controls, check for hallucinated dependencies, check for training-data-default configurations. At VULNEX, we’ve added these to our standard web application assessment template.
What Comes Next
This post maps the what. The rest of the series goes deeper into the how and the fix:
- Part 3: Anatomy of a Vibe Coding Breach — real-world case studies showing these OWASP categories in action
- Part 4: The Dependency Trap — deep dive into A03 (Supply Chain Failures) for AI-generated code
- Part 5: Authentication & Secrets — deep dive into A04 and A07, the most dangerous combination
- Part 6: Scanning Vibe-Coded Apps — practical tooling to catch these issues automatically
The OWASP Top 10 has been the industry standard for web application security for two decades. It still applies to vibe-coded apps. But the root causes have shifted from human error to statistical reproduction, and the remediation path has shifted from “educate the developer” to “constrain the AI and verify the output.”
The framework is the same. The game has changed.
As always: trust nothing, verify everything.
- X (Twitter): @SimonRoses
Further Reading
- What Is Vibe Coding Security? A Field Guide for 2026 — Part 1 of this series
- Moltbook: When AI Agents Build Their Own Social Network — Data integrity failures in a vibe-coded agent platform
- AI Agent Skill Poisoning: The Supply Chain Attack You Haven’t Heard Of — Supply chain attack patterns relevant to A03
- The Shadow Twin Threats: When AI and Vibe Coding Go Rogue — Enterprise governance and the invisible decision surface
References
- OWASP Foundation (2025). OWASP Top 10:2025.
- Veracode (2025). GenAI Code Security Report.
- Veracode (2026). Spring 2026 GenAI Code Security Update.
- Apiiro (2025). 4x Velocity, 10x Vulnerabilities: AI Coding Assistants Are Shipping More Risks.
- Escape.tech (2025). The State of Security of Vibe Coded Apps.
- Wiz Research (2026). Common Security Risks in Vibe-Coded Apps.
- Embrace The Red (2025). GitHub Copilot: Remote Code Execution via Prompt Injection (CVE-2025-53773).
- CodeRabbit (2025). State of AI vs. Human Code Generation Report.


