Imagine you built an app over the weekend with Cursor or Bolt. The login page looks great. Users can sign up, save data, make payments. You're ready to share it with the world. But buried in the JavaScript that gets sent to every visitor's browser is your Stripe secret key, your database password, and your Firebase admin credentials. Anyone who hits F12 and opens developer tools can see all of it.

That's not a hypothetical. It's the default behavior of AI coding tools. A 2025 Veracode study tested AI-generated code across 100+ large language models and found security vulnerabilities in 45% of coding tasks. Not edge cases. Nearly half of everything the AI produced had holes in it.

This article walks through the five most common security problems in vibe-coded apps, gives you three checks you can run on your own code right now, and explains what a professional security cleanup looks like if you find issues.

Why AI tools generate insecure code

When you tell an AI "connect to the Stripe API" or "build me a login page," it does exactly that. It connects to Stripe by putting the API key directly in the code, because that's the fastest path to a working demo. It builds a login page with a nice form and a token, but it doesn't add the server-side check that actually verifies the token on protected routes.

The AI isn't doing anything malicious. It's being literal. You asked it to make something that works, and it did. You didn't ask it to make something secure, so it took the shortest path and skipped the safety steps. Environment variables, server-side proxies, authentication middleware, input validation: these all add code that doesn't change what the app looks like or how it feels to click around. And since the AI optimizes for "does it work," the invisible security layer never gets built.

The five most common security risks in AI-generated code

1. Hardcoded credentials in frontend code

This is the big one, and it's everywhere. AI tools routinely put API keys, database connection strings, and payment processor secrets directly into JavaScript files that get shipped to the browser. Your Stripe secret key, your Firebase admin credentials, your database password, all sitting in source code that any visitor can read in about 30 seconds if they know where to look.

The AI does this because it's the simplest way to make an API call work. Setting up environment variables and server-side routes adds complexity that doesn't change the visible result, so the AI skips it.

The fix: Move all credentials to environment variables on the server. Create server-side API routes that make the sensitive calls and return only the data the frontend needs. Never reference secret keys in client-side code.

2. Backend routes with no authentication

Here's a pattern that catches a lot of people off guard. Your app has a login screen that looks legit. The user signs in, gets a token, and the frontend sends that token with every request. Looks secure, right? But the backend endpoint that returns user data never actually checks for that token. It responds to anyone who sends a request, logged in or not. The login page is a locked front door. The API is an open window around back.

This happens because authentication middleware is extra code that doesn't change how the page looks. The AI generates what you can see, and auth verification is invisible.

The fix: Add authentication middleware to every route that returns or modifies user data. Verify the token server-side on every request. Return a 401 error for unauthenticated requests instead of silently serving data.

3. No input validation

Whatever someone types into a form on your app goes straight to the database or straight onto the page. No checking, no cleaning, no escaping. This opens the door to two of the oldest and most common attacks on the internet: SQL injection, where an attacker runs database commands through your form fields, and cross-site scripting (XSS), where an attacker injects code that runs in other users' browsers.

OWASP has listed these in their top 10 web vulnerabilities for over a decade. AI tools ignore them because the form works perfectly fine with normal input. It's only when someone types something unexpected that the problem shows up, and by then it's too late.

The fix: Validate all input on the server side. Use parameterized queries for every database operation. Never render user-provided content without sanitizing it first. Escape HTML output.

4. Insecure data storage

AI tools love localStorage. It's simple to use, it persists across page loads, and the code to read and write to it is clean and short. It's also completely exposed. Any JavaScript running on your page can read it, including malicious scripts injected through the XSS vulnerability described above.

In AI-generated apps, auth tokens, user profiles, and sometimes even payment information end up in localStorage. This data should live in httpOnly cookies that JavaScript can't access, or in server-side sessions that never touch the browser at all.

The fix: Move sensitive data to httpOnly cookies with the Secure and SameSite flags set. Use server-side sessions for anything you don't want exposed to client-side scripts. Save localStorage for non-sensitive stuff like theme preferences.

5. No rate limiting

Your login endpoint accepts unlimited requests. An attacker can run a script that tries thousands of passwords per minute without any pushback. Your password reset endpoint sends unlimited emails, so someone can flood a user's inbox or rack up your email service bill. Your payment endpoint can be hit over and over without throttling.

Rate limiting has zero visible effect on how an app looks or feels during normal use, which is exactly why AI tools never add it. But it's one of the most basic protections against automated attacks.

The fix: Add rate limiting to authentication endpoints, password reset flows, and anything that sends emails or costs money per call. Most frameworks have middleware for this, and it's usually less than 10 lines of code to implement.

What a security breach actually costs

The IBM 2025 Cost of a Data Breach Report puts the global average at $4.44 million. Your startup probably wouldn't hit that number, but even a small incident triggers notification requirements, potential legal exposure, and the kind of customer trust damage that's hard to put a dollar figure on. A proactive security cleanup costs a fraction of what a single incident costs to recover from.

How to check your own app right now

You don't need to hire anyone to find the most obvious problems. These three checks take about fifteen minutes and will tell you if your app has the most common vulnerabilities.

Check 1: Look for exposed credentials. Open your app in the browser, press F12 to open developer tools, and go to the Sources tab. Search the JavaScript files for strings that look like API keys: long alphanumeric strings, anything starting with "sk_", "pk_", "AKIA", or "Bearer". If you find credentials in client-side code, that's a critical issue.

Check 2: Test your authentication. Log out of your app. Then go to the Network tab in developer tools, find an API call that should require you to be logged in, copy the URL, and open it in a new tab (or replay it with a tool like Postman). If the endpoint returns real data without a valid login token, your authentication isn't actually protecting anything.

Check 3: Try injecting code. Pick any text input on your app and type <script>alert('xss')</script>, then submit it. If you see a popup appear, your app has a cross-site scripting vulnerability. You can also try typing ' OR 1=1 -- in a search field. If you get unexpected results, you may have SQL injection.

If any of these checks turns up a problem, get a professional security review before putting the app in front of real users or real data.

How different AI tools compare on security

They're all bad at security by default, but some are worse than others.

Bolt and Lovable tend to be the worst offenders because they prioritize speed and visual polish above everything else. Developer forums are full of reports about Bolt-generated apps shipping with database credentials sitting in client-side JavaScript. Security is almost entirely absent from their output.

Cursor and Claude Code are better because they work inside your existing codebase and can follow patterns you've already established. If your project already has authentication middleware set up, they'll usually use it. But if it doesn't exist yet, they won't add it on their own.

GitHub Copilot lands somewhere in the middle. It autocompletes based on the code around it, so it inherits whatever security patterns (or lack of patterns) already exist in the file you're working in.

The takeaway isn't that one tool is safe. None of them are. The difference is how much cleanup you'll need afterward.

What a security cleanup looks like

When we do a vibe code cleanup, security is always the first thing we tackle. The typical timeline for a small to mid-size app looks like this:

On day one, someone goes through every file in the codebase looking for the problems described above. Exposed credentials, unprotected routes, missing input validation, insecure storage, outdated dependencies with known vulnerabilities. Everything gets cataloged into a prioritized list: critical issues that need to be fixed immediately, and lower-priority items that can wait.

Over the next two to three days, the critical fixes go in. Credentials get moved to environment variables. Authentication middleware gets added to every protected route. Input validation and parameterized queries replace the raw database calls. XSS vectors get closed.

Days four and five are about hardening: rate limiting, security headers like Content-Security-Policy and HSTS, HTTPS enforcement, proper session management, and a full dependency audit to catch any packages with known vulnerabilities.

By day six, the same checks run again to verify everything's been addressed, and the whole process gets documented so there's a record of what was found and what was fixed.

After that week, the app is secure enough to put in front of real users and real data. Architecture cleanup and test coverage come next in the broader cleanup process, but security is always the non-negotiable first step. According to ScienceSoft's published rates, a secure code review for a small application starts around $8,000. For complex apps, $10,000 to $18,000.

Frequently asked questions

Is vibe coding a security risk?

Yes. A 2025 Veracode study found AI-generated code introduced security vulnerabilities in 45% of coding tasks tested. The common patterns are hardcoded API keys in frontend JavaScript, missing authentication on backend routes, no input validation, and insecure data storage in the browser.

What are the most common security vulnerabilities in AI-generated code?

The five most common based on industry research: API keys and database credentials hardcoded in frontend code, backend endpoints with no authentication checks, no input validation (leaving the app open to SQL injection and XSS), sensitive data stored in localStorage, and no rate limiting on auth endpoints.

How do I check if my vibe-coded app is secure?

Start with three checks you can do yourself: search your frontend code for anything that looks like an API key or password, check your backend routes for authentication middleware, and try submitting a script tag through your input forms. If any of these reveal issues, get a professional audit before going to production.

Can AI-generated code pass a security audit?

Not in its raw form. But after a professional cleanup that addresses authentication, input validation, credential management, and access controls, the code absolutely can pass. The cleanup typically takes one to two weeks for a small to mid-size application.

Not sure if your vibe-coded app is secure? Send us the repo. We'll run a security audit and give you a prioritized list of exactly what needs to be fixed. No pitch, no pressure. Reach out here or call (507) 388-4748.