Originally published at kunalganglani.com — read it there for inline code, hero image, and live links.
Vibe coding is the practice of using AI tools like Cursor, Windsurf, or Claude Code to generate entire applications from natural-language prompts, often by developers with little or no security training. It's fast, it's democratizing, and it produces apps that work. The problem is that "works" and "secure" are completely different things. When Yael Grauer of The Verge published "Read this before you vibe-code another app" on June 22, 2026, the headline confirmed what security researchers have been screaming about for months: your dream vibe-coded app might be a security nightmare nobody warns you about.
I've spent 14+ years shipping production software, and I've reviewed enough AI-generated codebases in the last year to say this flatly: vibe-coded apps don't just have bugs. They systematically reproduce the exact vulnerability classes that the OWASP Top 10 was built to prevent. And no, switching models won't save you.
Why Vibe-Code Security Nightmares Are a Systemic Problem, Not a Model Problem
The first thing every vibe coder asks when they hear about security risks is: "Should I switch to a different model?"
No. Ofri Peretz, a security researcher at ofriperetz.dev, benchmarked 700 AI-generated functions against CWE-mapped ESLint security plugins and found that 63% shipped at least one security vulnerability when developers used a standard feature-only prompt. No "make it secure" instruction. Just the way people actually use these tools.
Peretz pitted Claude Sonnet 4.6 against Gemini 2.5 Flash across four security domains — JWT authentication, SQL injection, file handling, and rate limiting. The result: a statistical dead heat. One Gemini win, two ties, one split. Claude's auth middleware produced 6 ESLint security findings; Gemini produced 2. But both models missed the same core hardening steps. When Peretz re-ran the JWT round, both models landed on 5 findings again with identical failure modes.
"Which model writes more secure code" is the wrong question entirely. The vulnerability rate is 63% regardless. The problem isn't the model. It's the workflow. Vibe coding without security review is like building a house without inspecting the foundation.
If you're shipping AI-generated code without a security linting step, you're shipping vulnerabilities. Full stop. The model doesn't matter.
How Vibe-Coded Apps Reproduce OWASP's Top Vulnerabilities
The OWASP Top 10 has been the industry standard for web application security risks for over two decades. The 2025 edition maps almost perfectly to the failure modes I keep finding in AI-generated codebases. Here are the four worst offenders.
A01: Broken Access Control — The #1 Web App Vulnerability
Shubhra Pokhariya, a developer who published a detailed audit of their Next.js 16 app, found the textbook example. The app had protected routes, correct redirects, expiring JWTs, and role checks. Everything passed tests. Then Pokhariya discovered that any authenticated user could access any other user's invoice by simply knowing the numeric ID.
No error in the logs. No failed requests. The auth was "technically correct at every layer I had actually built." The problem? Only one layer existed. Authentication without authorization. The AI generated login flows perfectly but never created object-level access control — the check that says "yes, you're logged in, but is this your invoice?"
This is a classic Broken Object Level Authorization (BOLA/IDOR) flaw, and it maps directly to OWASP A01. Having built systems that handle sensitive user data, I can tell you: this is the vulnerability that keeps security engineers up at night. AI tools reproduce it constantly because the prompt says "add auth" and the model interprets that as "add login," not "add per-resource authorization." Those are wildly different things.
A02: Cryptographic Failures and Secret Leakage
Vibe-coded apps routinely hardcode API keys, use weak JWT signing algorithms, or store secrets in client-accessible configuration files. The AI doesn't know your deployment environment. When you prompt "connect to my database," the model reaches for the simplest path: a connection string with credentials inline. In my experience reviewing AI-generated code, I've seen production database passwords sitting in .env files that were committed to Git, JWT secrets defaulting to "secret", and API keys embedded in frontend bundles.
That last one still makes me wince. A frontend bundle. Served to every browser that loads the page.
A03: Injection — SQL, NoSQL, and Everything Else
When an LLM writes your database queries, it often reaches for string concatenation or template literals instead of parameterized queries. This is AI security 101, and yet Peretz's benchmark found it happening in the majority of AI-generated database code. The model produces something that works against your test data. It just also works for any attacker who knows how to add a '; DROP TABLE users;-- to a form field.
We solved parameterized queries decades ago. The fact that AI is reintroducing this class of bug in 2026 should genuinely alarm people.
A07: Identification and Authentication Failures
AI-generated auth middleware consistently skips the hardening steps that separate a working demo from a production system: rate limiting on login endpoints, account lockout after failed attempts, secure cookie flags, token rotation, and session invalidation. The code authenticates users. It just doesn't defend against anyone trying to break authentication.
Is Vibe-Coded AI-Generated Code Actually Insecure?
Yes, and the data is clear. Peretz's benchmark across 700 functions shows 63% vulnerability rates. But I want to be fair here: all code starts insecure. Human-written code has vulnerabilities too. The difference is that experienced engineers know to look for them.
When a senior engineer writes auth middleware, they're drawing on years of knowledge about OWASP categories, past breaches they've studied, security reviews they've survived. They don't just write the happy path. They think about the attack path. AI models, by contrast, optimize for the most statistically likely next token. Security hardening is rarely the most likely completion because most training data is feature code, not hardened production code.
The OWASP GenAI Security Project has grown to 600+ contributing experts from 18+ countries and nearly 8,000 active members. That kind of mobilization tells you something. This isn't hypothetical risk. It's active exploitation waiting to happen.
The gap between a working demo and a production-hardened app is exactly where OWASP's LLM Top 10 vulnerabilities live. And vibe coders, by definition, are people who stop at "it works."
Prompt Injection: OWASP's #1 LLM Vulnerability and Vibe Coding's Biggest Blind Spot
Prompt injection is ranked #1 in the OWASP LLM Top 10 for 2025, and for good reason. It occurs when user inputs alter an LLM's behavior in unintended ways — and the inputs don't even need to be human-readable.
Two sub-types. Direct prompt injection is when a user deliberately crafts input to manipulate the model. Indirect prompt injection is when the LLM ingests malicious content from external sources like websites, files, or databases — content that was planted there specifically to hijack the model's behavior.
Here's the thing nobody's saying about vibe-coded apps and prompt injection: most of them pass user input directly to LLM prompts with zero sanitization. The developer prompted Cursor to "build a chatbot that answers questions about my product," and the model built exactly that — a chatbot that takes raw user input, stuffs it into a prompt template, and sends it to the API. No input validation. No output sanitization. No guardrails. Just a pipe from the user's browser to your API key.
And before someone says "just use RAG" — the OWASP GenAI Security Project explicitly states that RAG and fine-tuning do NOT fully mitigate prompt injection vulnerabilities. So even "advanced" vibe-coded apps that use retrieval-augmented generation to ground their responses in real data are still exposed. RAG adds context. It doesn't add security.
After shipping several AI agent systems to production, I've learned the hard way that prompt injection defense requires layers: input validation, output sanitization, tool call verification, context isolation, and audit logging. Google's ADK framework, for instance, addresses this with five security layers. Most vibe-coded apps implement zero of them.
The LLM-as-Security-Judge Trap
One pattern I see constantly in vibe-coded agentic AI apps: using a second LLM as a security gate. The agent wants to do something. Before it acts, a second model evaluates whether the action is safe.
Sounds reasonable. It's not.
Brian Hall of the AARM (AI Agent Risk Management) community puts it bluntly: you've put "a second thing you can reason with in front of the first one." If an attacker can craft input that bends the agent, there's a real chance the same input bends the judge too. Under the hood it's the same kind of system responding to the same kind of pressure.
But the more practical problem is non-determinism. You can ask an LLM the same authorization question twice and get two different answers. That's not a bug — it's how sampling works. For most tasks, non-determinism is fine. But when the question is "should this agent be allowed to drop the production database," you need a yes-or-no gate that gives the same answer every time. Every. Single. Time.
Security controls must sit at the action layer, not the reasoning layer. That means deterministic code: allowlists, role-based access control, hard-coded permission boundaries. Not vibes. Not probability distributions. The irony of vibe coding is that the one place where deterministic, hand-written code is most critical — security enforcement — is the exact place where vibe coders are most likely to let the AI handle it.
Compositional Escape: The Attack Pattern That Breaks Every Per-Step Security Gate
This one keeps me up at night. A Self-Correcting Systems researcher documented what they call "compositional escape" — a trajectory of individually permitted actions that combines into a forbidden outcome.
Here's the example from their test harness, an invoice reconciliation agent:
- Reading vendor banking details — allowed
- Reading the vendor payment schedule — allowed
- Compiling a summary from both and sending it — produces a payment-redirect fraud kit
No single step triggers a security gate. Every action is within the agent's permitted scope. But the sequence is the attack. A per-step gate can't catch this because each operation, taken alone, is genuinely allowed. The violation is a property of the fold, not of any step.
Think about what this means for vibe-coded multi-step agent orchestration apps. If you've built an AI agent that can read data from multiple sources and take actions, you've potentially built an exfiltration tool. Not because any single capability is dangerous, but because the combination is. And the AI that wrote the code has no concept of this risk because each function it generated looked perfectly safe in isolation.
OWASP's LLM06 — Excessive Agency — covers exactly this pattern. LLM-based systems are often granted more permissions than necessary, and when AI-generated code auto-provisions its own access (creating admin service accounts, requesting broad API scopes), the attack surface compounds with every new capability.
MCP Servers: The Supply Chain Attack Surface Nobody's Vetting
Model Context Protocol (MCP) has become the default "plug anything in" layer for AI agents, and it's increasingly embedded in vibe coding tools like Cursor, Windsurf, and Claude Desktop. Ken Walger, a developer advocate, nails the analogy: "MCP standardized the connection. It didn't eliminate the need to think about what you're connecting."
The problem is that vibe coders add MCP servers the way people used to install npm packages — indiscriminately. Your agent stack has six MCP servers: one for your vector database, one wrapping your CRM, one your junior engineer spun up last Tuesday, one from a third-party vendor whose security posture you haven't audited. Your agent trusts all of them equally unless you've told it otherwise.
I've seen this firsthand. A team I was advising had eleven MCP connections in their agent setup. When I asked which ones had been vetted, the answer was a long silence followed by "the MongoDB one, probably."
A malicious MCP server can exfiltrate context from the agent, inject instructions into the agent's memory, or cause the AI to take destructive actions on connected systems. This is a direct supply chain attack vector, and it maps to both OWASP A08 (Software and Data Integrity Failures) and OWASP LLM03 (Supply Chain Vulnerabilities).
I've written before about MCP's role as AI's USB-C moment, and I stand by the protocol's potential. But potential without security review is just a fancy attack surface. If you're using MCP in production, you need containment boundaries: explicit definitions of what each server can touch, on whose behalf, and under what conditions.
The Vibe-Code Security Audit Checklist
After auditing enough vibe-coded applications to see the same failures repeat, I've distilled the minimum security checks every vibe-coded app needs before it touches production. This isn't comprehensive. It's the floor.
Run CWE-mapped security linters on every AI-generated function. Peretz's benchmark used ESLint security plugins for this. If 63% of output has a vulnerability, your review process needs automated scanning, not just eyeballing.
Check for object-level authorization, not just authentication. If your app has user-specific resources (invoices, profiles, documents), verify that the API checks ownership on every request. AI tools almost never generate this. I've reviewed dozens of vibe-coded apps and found exactly one that had it right out of the box.
Search for hardcoded secrets. Run
git secrets,trufflehog, orgitleaksagainst the entire repo. Check.envfiles, config objects, and frontend bundles. You will find something. I always do.Verify parameterized queries. Every database call should use parameter binding, not string concatenation. Search for template literals in SQL query strings.
Audit LLM input/output pipelines. If your app passes user input to an LLM, check for input validation, output sanitization, and prompt injection defenses. If it uses RAG, verify that retrieved documents can't inject instructions.
Review MCP server trust boundaries. List every MCP server connected to your agent. For each one, document what it can access and whether you've actually verified the source. "It was on npm" is not verification.
Test for excessive agency. List every action your agent can take. Ask: if an attacker controlled the prompt, which of these actions would be dangerous? Then the harder question: which combinations of allowed actions produce dangerous outcomes?
Check auth hardening. Rate limiting on login, account lockout, secure cookie flags, token rotation, CORS configuration. These are the hardening steps both Claude and Gemini skip by default.
If you haven't done all eight, your app isn't ready for users. It's a prototype with a login page.
What OWASP's LLM Top 10 Means for the Future of Vibe Coding
The OWASP LLM Top 10 for 2025 isn't just a list. It's the security community telling us they've mapped the failure modes of AI-generated applications and found them to be systematic, predictable, and exploitable. LLM security is no longer a niche concern. It's the central challenge of the vibe-coding era.
Here's my prediction: within 12 months, we'll see the first major breach directly attributed to a vibe-coded application. An app built by a non-engineer using AI tools, deployed to production without security review, exploited through one of the exact vulnerability classes I've outlined here. BOLA, prompt injection, or supply chain via MCP. The pattern is already set. The only question is which app, which attacker, and how many users get burned.
The vibe-coding movement isn't going away, and I don't think it should. AI coding tools are genuinely transformative for productivity. But the gap between "I built an app" and "I built a secure app" is the gap between a weekend project and a professional product. That gap has always existed. AI just made it invisible by generating code that looks production-ready while carrying the security posture of a first draft.
If you're building with AI, build with AI. But stop assuming the model knows what "secure" means. It doesn't. Run the linters. Check the auth. Audit the MCP servers. That's still your job, and it's going to stay your job for a long time.
Frequently Asked Questions
Is AI-generated code less secure than human-written code?
In benchmark testing, 63% of AI-generated functions contained at least one security vulnerability when no explicit security instruction was given. Human-written code also has vulnerabilities, but experienced engineers typically apply security hardening practices that AI models skip by default. The key difference is awareness: a senior engineer knows to look for OWASP-class risks; AI models optimize for the most likely code completion, not the most secure one.
Does switching AI models improve code security?
No, not meaningfully. A benchmark of Claude Sonnet 4.6 versus Gemini 2.5 Flash across four security domains produced a statistical dead heat. Both models missed the same core hardening steps. The vulnerability rate is approximately 63% regardless of which model you use, because the problem is in the workflow (no security review), not the model.
Can RAG or fine-tuning fix prompt injection in vibe-coded apps?
OWASP explicitly states that RAG and fine-tuning do not fully mitigate prompt injection vulnerabilities. RAG adds grounding context to model responses, but it doesn't prevent an attacker from manipulating the model through crafted inputs. Prompt injection defense requires layered controls: input validation, output sanitization, tool call verification, and context isolation.
What is compositional escape in AI agents?
Compositional escape is an attack pattern where every individual action an AI agent takes is within its permitted scope, but the sequence of actions produces a forbidden outcome. For example, reading vendor banking details (allowed) plus reading a payment schedule (allowed) plus compiling and sending a summary (produces a fraud kit). Per-step security gates can't catch this because each step is genuinely allowed — the violation only exists in the combination.
How do MCP servers create security risks for vibe-coded apps?
Model Context Protocol (MCP) servers act as plug-in connections for AI agents, letting them access external tools and data sources. A malicious or unvetted MCP server can exfiltrate agent context, inject instructions into the agent's memory, or trigger destructive actions on connected systems. Most vibe coders add MCP servers without any security vetting, creating a direct supply chain attack surface.
What is the minimum security checklist for vibe-coded apps?
At minimum, run CWE-mapped security linters on all generated code, verify object-level authorization (not just login), scan for hardcoded secrets, confirm parameterized database queries, audit LLM input/output pipelines for prompt injection, review MCP server trust boundaries, test for excessive agent permissions, and verify auth hardening like rate limiting and secure cookies.
Originally published on kunalganglani.com
![Vibe-Code Security Nightmares Nobody Warns About [2026]](https://media2.dev.to/dynamic/image/width=1200,height=627,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fswltargd52b3hertbqqa.png)












