
13 Vulnerabilities in Vibe coding every builders need to look out for
Vibe coding has made building software faster than it has ever been. A non-technical founder can go from idea to deployed product in an afternoon. A developer can ship features in hours that would have taken days. The barrier between having an idea and having something real has never been lower.
But speed without awareness is how you build something that looks finished and falls apart the moment a real user, or a real attacker, shows up.
The code that AI platforms generate is not inherently bad. Most of it works. Most of the time. The problem is that AI models are optimized to produce code that runs, not code that is secure, maintainable, or architected for what your product becomes six months from now. Those are different goals, and the gap between them is where most vibe-coded products get into serious trouble.
Here are 13 vulnerabilities that show up consistently in AI-generated code, what they actually mean in plain language, and what to do about each one before they become your problem.
1. Hardcoded API Keys and Secrets in the Codebase
This is the most common and most immediately dangerous vulnerability in vibe-coded projects. When you ask an AI to connect your app to an external service, it will often generate code with placeholder API keys or, worse, prompt you to paste your real key directly into the code. Some builders do exactly that, then push the code to a public GitHub repository and wonder why their AWS bill suddenly has five figures on it.
API keys in code get scraped by bots that monitor public repositories in real time. GitHub has automated scanning for certain key patterns, but it does not catch everything, and private repositories can become public accidentally.
What to do: Store every API key, database password, and secret token in environment variables, never in the code itself. Use a .env file locally, add it to your .gitignore immediately, and use your hosting platform's environment variable management for production. This takes five minutes to set up and eliminates one of the most avoidable categories of security breach.
2. SQL Injection Through Unsanitized User Input
SQL injection is one of the oldest attack vectors in software and it still shows up in AI-generated code regularly. It happens when user input is taken directly and inserted into a database query without being sanitized first. An attacker who spots this can manipulate the query to return data they should not have access to, delete records, or in some configurations, execute commands on the underlying server.
AI models generate direct string interpolation in database queries more often than they should, particularly when you ask them to build something quickly without specifying security requirements.
What to do: Never construct database queries by concatenating user input into a string. Use parameterized queries or prepared statements, which your database library almost certainly supports. If you are using an ORM like Prisma or Drizzle, it handles this for you by default, but verify that you are not bypassing it with raw query methods anywhere in the codebase.
3. Missing Authentication on API Endpoints
This one is surprisingly easy to miss in a vibe-coded app. You build a frontend that looks protected behind a login screen, but the API endpoints that the frontend calls to fetch or modify data have no authentication checks on them. Anyone who inspects your network traffic, opens browser developer tools, or reads your API documentation can call those endpoints directly without logging in.
AI platforms often generate authentication for the frontend flow and forget to apply it consistently to every backend route, especially routes added later in the build process.
What to do: Audit every API endpoint in your application and verify that each one requires valid authentication before returning any data. Use middleware that applies authentication checks at the router level rather than adding individual checks to each endpoint manually. Tools like Postman or Insomnia make it easy to test your endpoints as an unauthenticated user to see what comes back.
4. Broken Access Control Between Users
Authentication confirms who you are. Authorization controls what you are allowed to do. Vibe-coded apps frequently handle authentication reasonably well and handle authorization poorly.
The classic failure here is a user who can access another user's data by simply changing an ID in the URL or request body. Your app confirms they are logged in but does not check whether the resource they are requesting belongs to them.
What to do: Every database query that fetches user-specific data should include a check that ties the record to the authenticated user's ID. Never trust client-supplied IDs without verifying ownership on the server side. This is called object-level authorization and it needs to be applied consistently across every endpoint that touches user data.
5. No Rate Limiting on Sensitive Endpoints
Without rate limiting, any endpoint in your application can be hammered with unlimited requests. This creates two distinct problems. First, it makes brute force attacks against login forms trivially easy: an attacker can attempt thousands of password combinations per minute until one works. Second, it makes your application vulnerable to denial of service: enough requests from enough sources can bring your server down entirely.
AI-generated code almost never includes rate limiting by default because it is not required for the app to function during development.
What to do: Apply rate limiting to at minimum your login endpoint, your registration endpoint, your password reset flow, and any endpoint that sends emails or SMS messages. Libraries like express-rate-limit for Node.js make this a few lines of code. Platforms like Cloudflare can apply rate limiting at the network level before requests ever reach your server.
Here another article we think you would love:
15 Best New Vibe Coding Platforms Right Now for Vibe Coders FREE/PAID
6. Exposed Error Messages That Reveal System Details
When something goes wrong in a vibe-coded app, the error handling is often minimal. The raw error from the database, the file system, or the external API gets passed directly to the client. That error message might contain your database schema, your file paths, your server configuration, or the specific version of software you are running.
Each piece of that information is useful to an attacker mapping out your system before attempting something more serious.
What to do: Implement a global error handler that catches unhandled errors and returns a generic message to the client while logging the full error detail server-side where only you can see it. "Something went wrong. Please try again." is the right user-facing message. The stack trace belongs in your logs, not in the browser.
7. Insecure File Upload Handling
If your application allows users to upload files, the AI-generated code for handling that upload is probably checking the file extension to determine whether it is safe. File extension checks are trivially bypassed. An attacker can rename a malicious executable to have a .jpg extension and your extension check will happily accept it.
What to do: Validate file type by checking the actual file signature (the magic bytes at the start of the file), not the extension. Set strict file size limits. Store uploaded files outside your web root so they cannot be executed directly by the server. Scan uploaded files with an antivirus library if your use case requires it. Never execute or include user-uploaded files in your application logic.
8. Cross-Site Scripting (XSS) Through Unescaped Output
Cross-site scripting happens when user-supplied content is rendered directly in the browser without being escaped first. An attacker who can inject a script tag into a field that gets displayed to other users can steal session cookies, redirect users to phishing pages, or perform actions on behalf of other users without their knowledge.
Modern frontend frameworks like React escape output by default, which is why this vulnerability shows up more often in apps that bypass that default through dangerouslySetInnerHTML or equivalent patterns, which AI models sometimes generate when you ask for rich text rendering.
What to do: Avoid dangerouslySetInnerHTML unless you are certain the content being rendered has been sanitized. If you need to render user-provided HTML, run it through a dedicated sanitization library like DOMPurify first. Audit every place in your codebase where user input is rendered to the DOM.
9. Weak or Missing CSRF Protection
Cross-Site Request Forgery is an attack where a malicious website tricks a user's browser into making a request to your application while the user is logged in. Because the browser automatically sends the user's session cookie with the request, your server thinks it is a legitimate action from the authenticated user.
Vibe-coded apps that use cookie-based sessions and do not implement CSRF tokens are vulnerable to this attack on any state-changing endpoint.
What to do: Use CSRF tokens for any application that relies on cookie-based authentication. Most web frameworks have CSRF protection middleware that handles this for you. Alternatively, switching to token-based authentication where the token is sent in a request header rather than automatically by the browser eliminates this attack vector entirely.
10. Dependencies With Known Security Vulnerabilities
Every npm install, pip install, or equivalent command that an AI platform runs when setting up your project pulls in a chain of dependencies. Some of those dependencies have known security vulnerabilities. Some have been abandoned by their maintainers and will never be patched. Some have been compromised through supply chain attacks where malicious code was injected into a legitimate package.
You did not choose most of these packages individually. The AI scaffolded your project and selected them for you.
What to do: Run npm audit or pip-audit regularly to check your dependency tree for known vulnerabilities. Use a tool like Snyk or Dependabot to automate this monitoring and alert you when new vulnerabilities are discovered in packages you are using. Keep dependencies updated, but test updates before deploying them to production.
11. Sensitive Data Stored or Transmitted Without Encryption
User passwords stored as plain text in a database. Personally identifiable information sent over HTTP rather than HTTPS. Sensitive data stored in browser localStorage where any JavaScript on the page can read it. These are not edge cases. They appear in AI-generated code more often than they should.
What to do: Passwords must be hashed with a slow, purpose-built algorithm like bcrypt, scrypt, or Argon2 before being stored. Never use MD5 or SHA-1 for password hashing. Enforce HTTPS for all traffic. Do not store sensitive data in localStorage. Use secure, httpOnly cookies for session tokens so they cannot be accessed by JavaScript.
12. Lack of Input Validation on the Server Side
Frontend validation, the kind that tells a user "this field is required" or "please enter a valid email address," is a user experience feature. It is not a security feature. Any request to your server can be crafted manually, bypassing your frontend entirely. If your server does not independently validate every piece of incoming data, an attacker can send anything they want directly to your API.
AI platforms often generate client-side validation diligently and server-side validation inconsistently.
What to do: Treat every incoming request as potentially hostile and validate all input on the server before processing it. Define schemas for your API requests using a library like Zod or Joi and reject requests that do not conform to those schemas with a 400 status code before they touch your business logic or your database.
13. Overly Permissive CORS Configuration
Cross-Origin Resource Sharing controls which domains are allowed to make requests to your API from a browser. AI-generated code frequently sets CORS to allow all origins, meaning any website in the world can make requests to your API with a user's credentials if that user visits the malicious site while logged into your application.
Wildcard CORS configurations are generated as a quick fix when CORS errors show up during development and often never get tightened before production.
What to do: Configure CORS to allow only the specific domains that legitimately need to access your API. In production, that means your own frontend domain and nothing else unless you are intentionally building a public API. Review your CORS configuration before every production deployment and treat a wildcard origin setting as a failed check.
The Pattern Behind All of These
Read through this list and one pattern becomes clear. Almost none of these vulnerabilities are present because the AI made a sophisticated error in judgment. They are present because the AI generated code that works and left security as something to figure out later.
Later, in most vibe-coded projects, never comes. The MVP ships, users show up, and the security debt sits quietly in the codebase until it does not.
The practical response is not to stop using AI platforms. They are genuinely useful tools and most of what they generate is fine. The response is to build a habit of asking one additional question after you get code you are satisfied with: what did this not handle that a real user or a real attacker might care about?
Vibe coding is fast. Security is not optional. The founders who understand both of those things simultaneously are the ones who build products that survive contact with the real world.


