AI Generated Code Security Vulnerabilities
You built your app with Cursor in two weeks. It works. Users are signing up. Your YC batch mates are impressed.
Then your first enterprise prospect asks for a SOC 2 report. Or your Series A lead sends over a security questionnaire. Or a researcher emails you that your API is leaking user data. Any of these is enough to stall a deal, a round, or your reputation.
This is not hypothetical. In our audit of 50 vibe coded apps, 100% had at least four critical security vulnerabilities. Not sophisticated zero-days. Basic, well-documented flaws that AI coding tools reproduce with remarkable consistency because they are trained on tutorial code that was never meant to face the internet.
Credit where it is due: AI tools write functional code
Cursor, Copilot, and Claude generate code that works. The authentication flow logs users in. The payment form charges cards. The API returns data. For prototyping, this is genuinely valuable, and we use these tools ourselves.
But "works" and "secure" are different requirements separated by years of hard-won engineering discipline. A door that opens is functional. A door that locks is secure. AI tools build doors that open.
The 8 vulnerabilities we find in every audit
These are ordered by OWASP Top 10 category. We are not cherry-picking rare edge cases — these appear in virtually every AI-generated codebase we examine.
1. SQL injection via string concatenation (OWASP A03: Injection)
AI tools frequently generate database queries by concatenating user input directly into query strings. Even when using an ORM, we find raw query escapes where the AI dropped down to raw SQL because the ORM could not express the query it wanted.
The pattern looks like this: the AI generates a search feature. The ORM does not have a clean full-text search API. The AI writes a raw query with the search term interpolated directly. No parameterization. No sanitization.
In one audit, we found a search endpoint where a single crafted input could dump the entire users table — emails, hashed passwords, and billing data. The app had 3,000 users. The fix was a one-line change to use a parameterized query. But nobody knew to look because the code "worked."
2. Cross-site scripting from unescaped user content (OWASP A03: Injection)
React protects against XSS by default — unless you bypass its escaping by using unsafe innerHTML patterns, which AI tools reach for the moment you ask for "rich text display" or "render markdown." We find it in blog previews, comment systems, user profile descriptions, and admin dashboards.
The AI uses unsafe HTML rendering without sanitization because the training data shows that pattern. The sanitization library (DOMPurify, sanitize-html) is never imported because the prompt did not mention security. A user submits a profile bio containing a script tag. Every visitor to that profile page now executes arbitrary JavaScript in their browser.
Stored XSS in a SaaS app means an attacker can steal session tokens from every user who views the compromised content. That is complete account takeover at scale.
3. Insecure direct object references — IDOR (OWASP A01: Broken Access Control)
This is the vulnerability that ends startups. Your API has an endpoint: GET /api/invoices/123. The AI generated it to fetch the invoice with ID 123 from the database and return it. It did not add an ownership check. Change the URL to /api/invoices/124 and you get someone else's invoice.
We find IDOR in every AI-generated CRUD application. The AI treats the URL parameter as trusted input because, during development, the only person making requests is the developer. Access control — verifying that the requesting user owns the requested resource — requires an explicit check that AI tools almost never add.
In 50 audits, 46 apps had at least one IDOR vulnerability. The median was 7 exploitable endpoints per app. These are not theoretical — they are one curl command away from a data breach.
4. Missing CSRF protection (OWASP A01: Broken Access Control)
Cross-site request forgery tokens prevent other websites from submitting forms on behalf of your logged-in users. Most AI-generated apps use cookie-based authentication but never implement CSRF protection.
The attack: a malicious website embeds a hidden form that POSTs to your app's "change email" endpoint. A logged-in user visits the malicious site. Their browser automatically includes the session cookie. The email is changed. The attacker now resets the password to their own email.
Modern frameworks have CSRF protection built in — but it must be configured. AI tools skip the configuration because the feature works without it in development where the only requests come from localhost.
5. Secrets exposed in client bundles (OWASP A02: Cryptographic Failures)
This one makes us wince every time. API keys, database URLs, and third-party secrets hardcoded in files that get bundled into client-side JavaScript. We have found Stripe secret keys, Supabase service role keys (which bypass row-level security), and OpenAI API keys sitting in browser-downloadable JavaScript bundles.
The AI puts the key where it needs to use it. If a client component needs to call an API, the AI imports the key into the client component. The NEXT_PUBLIC_ prefix convention (or equivalent in other frameworks) is a footgun that AI tools fire consistently.
In one case, an exposed Supabase service role key gave any visitor full read-write access to every table in the database. The app had been live for four months. We do not know if anyone found it before we did.
6. Overly permissive CORS (OWASP A05: Security Misconfiguration)
When the AI encounters a CORS error during development, it does what every frustrated developer does: sets Access-Control-Allow-Origin: *. All origins. All methods. All headers.
This means any website on the internet can make authenticated requests to your API on behalf of your logged-in users. Combined with the missing CSRF protection above, this is a complete bypass of the same-origin policy that browsers use to protect users.
The fix is specifying your actual frontend domain. It takes 30 seconds. But the AI's training data overwhelmingly shows the wildcard because that is what tutorials use to avoid CORS errors during development.
7. Broken authentication flows (OWASP A07: Identification and Authentication Failures)
AI-generated auth is functional but shallow. We consistently find: password reset tokens that never expire, email verification links that work after the email has already been changed, sessions that are not invalidated on password change, and JWT tokens stored in localStorage (accessible to any XSS attack).
The most common pattern: the AI implements login and registration correctly, but the "forgot password" flow uses a token that is just a simple random string. Predictable. Not cryptographically secure. And valid forever because no expiration was set.
These are not exotic attacks. Password reset token prediction is a standard penetration test finding. But AI tools treat auth as a feature to ship, not a security boundary to harden.
8. No rate limiting anywhere (OWASP A04: Insecure Design)
Your login endpoint accepts unlimited requests. Your registration endpoint accepts unlimited requests. Your password reset endpoint accepts unlimited requests. Your API endpoints accept unlimited requests.
Without rate limiting, an attacker can: brute-force passwords at thousands of attempts per second, create millions of fake accounts, trigger millions of password reset emails (burning your email provider budget), and scrape your entire database through your API endpoints.
Rate limiting is infrastructure, not application code. AI tools do not think about infrastructure. They write the endpoint logic and move on. The result is an API that will serve as many requests as anyone cares to send.
Why this happens: the training data problem
AI code generators are trained on open-source code, tutorials, and Stack Overflow answers. This training data has a systemic bias: it optimizes for "making it work" rather than "making it secure."
Tutorials strip away security to focus on teaching the core concept. Stack Overflow answers solve the immediate problem without defensive coding. Open-source example code includes TODOs for security that were never completed.
The AI faithfully reproduces these patterns. It is not negligent — it is doing exactly what its training data shows. The problem is that its training data was never intended to be deployed to production facing the open internet.
The business cost of security vulnerabilities
Series A due diligence. Investors increasingly require security audits before closing. One firm we work with rejected a term sheet after their security team found IDOR vulnerabilities in the candidate's app. The round died. The startup ran out of runway three months later.
Enterprise sales. If your AI-generated code fails a formal security audit, the deal is dead before it starts. Any customer with a security team will send you a questionnaire. "Do you have CSRF protection?" "How do you handle secrets management?" "What is your rate limiting policy?" If the honest answer is "the AI did not add any of that," you lose the deal.
Breach liability. GDPR fines for data breaches start at 2% of annual revenue. CCPA provides for $100-750 per consumer per incident. For a startup with 10,000 users and an IDOR vulnerability leaking personal data, the liability math is existential.
Reputation. A single security incident reported on Twitter ends the goodwill that took months to build. Users do not come back to products that leaked their data.
The fix is systematic, not piecemeal
You cannot secure a vibe coded app by asking the AI to "add security." Security is an architectural property, not a feature toggle. It requires a systematic audit of every endpoint, every data flow, every authentication boundary, and every secret.
This is what production engineering includes: a line-by-line security audit mapped to OWASP Top 10, followed by systematic remediation. Not "add CSRF tokens to this form" — every form, every endpoint, every data access pattern reviewed and hardened. For a detailed walkthrough of how this audit process works and what deliverables to expect, see our AI app security audit guide.
The same patterns that cause vibe coded apps to crash also cause them to leak data. No input validation means both crashes and injection. No boundary checks means both errors and IDOR. Production engineering fixes both simultaneously because the root cause is the same: code that was never designed to face adversarial conditions.
Frequently asked questions
How do I know if my app has been compromised already?
Without audit logging — which AI tools never add — you likely cannot tell. The absence of evidence is not evidence of absence. If your app has IDOR vulnerabilities and has been live for more than a month, you should assume data has been accessed by unauthorized parties and assess your disclosure obligations.
Can I use automated security scanners to find these issues?
Automated scanners (Snyk, SonarQube, Semgrep) catch some issues — particularly dependency vulnerabilities and some injection patterns. They miss business logic flaws like IDOR because those require understanding what each endpoint should authorize. In our experience, automated scanners find 30-40% of the vulnerabilities in a vibe coded app. The rest require human review.
Which AI coding tool produces the most secure code?
None of them produce secure code by default. Whether you used Cursor or Lovable, the security gap is fundamentally the same. Claude tends to add more input validation than Copilot. Cursor's codebase-aware context sometimes prevents secret leakage. But the gap between any AI tool's output and production-grade security is significant regardless of which tool you use.
My app uses Supabase Row Level Security. Am I safe?
RLS is a strong foundation — if configured correctly. We find RLS policies that are too permissive (allowing users to read all rows in a table), missing entirely on some tables, or bypassed by the service role key that is exposed in client code. RLS is only as secure as its weakest policy and the secrecy of the service role key.
How long does a security audit take?
For a typical early-stage SaaS, a comprehensive security audit takes 3-5 days. Remediation depends on the severity: critical issues (IDOR, exposed secrets) are fixed in days; structural issues (adding CSRF protection across all forms, implementing rate limiting) take 1-2 weeks. A full security hardening engagement runs 2-4 weeks.
Do I need to worry about this before I have significant users?
Yes. Vulnerabilities exist from day one. An attacker finding an exposed API key does not wait for you to reach product-market fit. More practically, fixing security issues is dramatically cheaper in a small codebase. Every month of feature development on top of insecure foundations increases the cost of remediation.
What certifications or compliance standards should I target?
For B2B SaaS selling to enterprises, SOC 2 Type II is the minimum. For healthcare, add HIPAA. For fintech, PCI DSS. All of these require the security controls that AI tools omit. Getting compliant is a separate engagement from the initial security hardening, but you cannot start compliance without the baseline in place.
Your code is live. Is it secure?
Every day your AI-generated app faces the internet without a security audit, you are betting your company on the assumption that nobody has looked for the vulnerabilities that exist in every vibe coded app we have examined.
Apply for a security-focused production audit. We will map every vulnerability, prioritize by exploitability and business impact, and fix the critical issues before they become incidents.
Your prototype shipped fast. Now make sure it does not ship your users' data.