Your AI tool built the app. It looks right, the buttons work, the demo flows end to end, and you are days from launch. Then a quieter question arrives: is it safe to put real people and real data behind it? The prototype works, and the security work has not been done at all.
This guide is the ai app security pass we run on apps built with Bolt, Lovable, Cursor, v0 and Replit before they meet real users. It names the exact gaps an AI tool leaves open, shows you how to find each one yourself, and tells you how to fix it. It is written for a founder, not a security engineer, so every term is explained the first time it appears.
Why AI-built apps are insecure by default
AI coding tools are built to get a working app on screen quickly, which is genuinely useful for shaping an idea. But security is invisible, so it is the first thing a tool trades away. A missing authorization check looks identical to a working one until someone tests it.
There is a founder-level truth underneath this. AI writes code, but it does not give you strategy, and it does not own the risk. Code does not make a business safe on its own. The hard production work, which is security, validation, testing and the real backend, is the part these tools leave for a human. We go deeper on the general version in why AI built apps break in production; this post is only about the security half.
The gaps cluster in a handful of predictable places. Here is the map before we walk through each one.
The security gaps in an AI-built app, and how to fix each
There are seven gaps that show up again and again. For each one, the pattern is the same: why the AI tool leaves it open, how you can find it in your own build in a few minutes, and how to close it properly. You do not need to trust us on any of them, because every one is something you can check yourself today.
1. Secrets and API keys in the frontend
An exposed secret is the fastest way an AI build gets compromised. AI tools wire up a third-party service in the quickest way that runs, which often means dropping the API key straight into client code so the browser can call the service directly. The problem is that anything in the browser bundle is public. Open dev tools, look in the loaded scripts or the network tab, search for the key, and there it is.
How to find it: open your deployed app, open the browser developer tools, and search the loaded JavaScript for words like key, secret or token. If a real key appears, it is exposed to everyone.
How to fix it: secrets belong on the server, not in the browser. On Vercel, environment variables are stored server side and, in Vercel's words, "these values are encrypted at rest". The catch is the browser exposure rule. Vercel's framework documentation states that "frameworks typically use a prefix to expose environment variables to the browser", and that "many frontend frameworks require prefixes on environment variable names to make them available to the client, such as NEXT_PUBLIC_ for Next.js or PUBLIC_ for SvelteKit", per its framework environment variables docs and its environment variables guide. The lesson is direct: a secret key must never carry a public prefix, and must be read by server code only. And because an exposed key is already compromised, rotating it, which means replacing it with a new value, is part of the fix, not optional.
2. No real authentication or authorization
This is the gap that does the most damage, because the data is wide open even when the app looks locked. Two words matter here. Authentication proves who a user is, usually through a login. Authorization decides what that user is allowed to see and do. AI builds often add a login screen and stop there, so the app checks who you are but never checks what you are allowed to touch.
Worse, the checks that do exist often live only in the interface. A page is hidden from the menu, so it feels protected, but the data behind it answers anyone who asks. Hiding a button is not security. The request still works if you send it directly.
How to find it: log in as a normal user and try to open a record that belongs to someone else by changing an ID in the address bar. If you can see it, authorization is missing. Then try calling the data API without logging in at all.
How to fix it: every rule about who can do what has to be enforced on the server, on every request, not in the UI. This usually means a real trusted server layer, which many AI builds simply do not have yet. If yours is frontend-only, you are really looking at adding a backend and database to the app first, then enforcing authorization inside it.
3. Missing row-level security on the database
Many AI tools connect the frontend straight to a hosted database like Supabase, using a public key that ships in the browser. That key is designed to be public. What protects your data in that setup is row-level security, and AI builds frequently leave it off.
Row-level security, or RLS, is an authorization rule that runs inside the database. Supabase describes it as giving "you granular authorization rules that run inside the database". The important behaviour is what happens when it is on versus off. Supabase's documentation states that "once RLS is enabled, no data is accessible through the API when using a publishable key, until you create policies", and warns that "a table in an exposed schema without RLS is readable and writable by any role with a grant on it", with the clear instruction to "enable RLS on every table in an exposed schema", per the Supabase row level security docs. In plain terms: with RLS off, the public key can read and write your tables from anywhere. With RLS on, it can do nothing until you write a policy that says who may touch which rows.
How to find it: in your Supabase dashboard, check whether RLS is enabled on each table. A table in the public schema with RLS off is open.
How to fix it: enable supabase row level security on every exposed table, then write a policy per table that ties each row to the user who owns it. Test it by querying with the public key as an outsider and confirming you get nothing back.
4. No input validation
Input validation means checking that data coming into your app is the right shape and safe before you act on it. AI builds often trust whatever the frontend sends, which opens the door to injection, where crafted input is read as a command instead of data.
The authority here is OWASP, the open security body that maintains the standard references. OWASP states that "input validation must be implemented on the server-side before any data is processed by an application's functions, as any JavaScript-based input validation performed on the client-side can be circumvented by an attacker". It also notes that validation alone "should not be used as the primary method of preventing XSS, SQL Injection and other attacks", per the OWASP Input Validation Cheat Sheet. So validation is necessary but not the whole answer.
How to find it: type unusual characters, very long strings, or quote marks into a form field and see whether the app errors oddly or accepts them without complaint.
How to fix it: validate every input on the server, and pair it with parameterised queries, which means passing user values as separate parameters so the database never treats them as part of the command. That combination is what actually stops SQL injection, not validation by itself.
5. No rate limiting
Rate limiting caps how many times someone can call a part of your app in a given window. Without it, one script can hit a login form or an expensive endpoint thousands of times a minute. That enables password guessing, runs up your bills on paid services, and can knock the app over.
AI tools leave this out because a prototype never feels the load. One user clicking buttons never triggers it, so the gap stays invisible until a real actor finds it.
How to find it: replay a single request in a fast loop and watch whether the app keeps answering every time with no slowdown or block.
How to fix it: add limits per user and per IP address on sensitive endpoints, especially login, sign-up, password reset and anything that calls a paid service. Return a clear "too many requests" response once a caller crosses the line.
6. Permissive CORS
CORS, which stands for cross-origin resource sharing, controls which other websites a browser will let call your API. MDN defines it as "an HTTP-header based mechanism that allows a server to indicate any origins ... other than its own from which a browser should permit loading resources", in its CORS documentation. The header that carries the decision is Access-Control-Allow-Origin.
AI builds often set this to a wildcard, written as *, which tells browsers to allow any origin. MDN notes the wildcard "tells browsers to allow any origin to access the resource". For a public, read-only feed that can be acceptable. For an API that touches user data, it is too open.
How to find it: open the network tab, look at a response from your API, and read the Access-Control-Allow-Origin header. A * on a data API is a flag.
How to fix it: list only the origins you own, such as your own domain, and reject the rest. Keep the wildcard only for genuinely public resources that carry no private data.
7. Client-side-only checks
This thread runs through several gaps above, so it is worth stating on its own. A check that lives only in the browser is a convenience, not a security control, because the user controls the browser. MDN puts it plainly: "never trust data passed to your server from the client", and warns that "client-side validation should not be considered an exhaustive security measure", because "a malicious user can still alter the network request", in its client-side form validation guide.
How to fix it: treat every browser check as a UX nicety and enforce the real rule again on the server. If a price, a permission or a quantity matters, the server must decide it, because that is the one place the user cannot edit.
| Risk | How to check | How to fix |
|---|---|---|
| Exposed API keys | Open browser dev tools and search the bundle for the key | Move the key to a server environment variable, then rotate it |
| No authorization | Call the data API without logging in | Enforce authentication and roles on the server, not in the UI |
| Open database | Query a table with the public key from outside the app | Enable row-level security and write a policy for each table |
| Injection | Send unusual characters into a form or URL field | Validate input on the server and use parameterised queries |
| No rate limiting | Replay one request in a fast loop | Add per user and per IP request limits on each endpoint |
| Permissive CORS | Read the Access-Control-Allow-Origin header on the API | Allow only your own trusted origins, never a blanket wildcard |
Read that table as a to-do list you can run this afternoon. Every check is something you can do on your own live build, and every finding has a known fix.
How to secure a Bolt app, or any AI build, before launch
To secure an AI-built app before launch, run a single audit pass: list every secret and move it to the server, test authentication and authorization by calling the API directly, enable row-level security on every table, validate all input server side, add rate limiting, and restrict CORS to your own origins. Then retest each item against the live build. The order matters less than the completeness.
The reason to work from a checklist rather than instinct is that these gaps hide. A build can look finished and still fail every item. This is also why a demo passing is not the same as a build being safe, a point we make in is your AI built app production ready. The same audit applies whether your app came out of Bolt, Lovable, Cursor or v0, since they all optimise for the visible layer. If you want the platform-specific launch steps, the Bolt to production guide and the Lovable finish-and-deploy guide sit alongside this one.
Our own approach is where the AI-amplified process stops and human engineering takes over. We let AI compress the early work, the scoping, the UI and turning a design into frontend, because it is genuinely good at that. Architecture, integrations and security are not delegated to a tool. They are engineered and hardened by a person, because the cost of getting them wrong lands on real users and on you. That is the exact line this secure a bolt app work sits on.
Tell us what you have in mind. We turn AI prototypes and fresh ideas into shipped, scalable products, from India, for the US and UK.
When securing it is not worth it
Honesty first: not every AI build is worth hardening, and a few are better restarted. The deciding factor is whether there is anything safe to build on.
If your app is frontend-only, with no server layer, no real database setup and no auth, then "adding security" is not a patch. It means building the hidden half of the product that was never there. In that case you are choosing between a rebuild of the backend and a finish of a prototype, which we break down in the pillar guide on how to launch an AI-built app. The useful rule from building these: keep the client-approved frontend design if it is good, because that saves roughly 30 percent of the cost and time, and rebuild the architecture, backend and security, because that is where AI tools fall short.
There is also a budget reality. If your total budget to take the app forward is only $1,000 to $2,000, it is usually not worth acting on. That amount cannot buy a real security layer and a production backend, and a half-done job here is worse than none, because it looks safe and is not. For a sense of real numbers, appico MVP work starts from $10,000 including source code and deployment, while a focused security pass on a sound, well-built app sits well below that. You can shape a rough range for your own case with our cost calculator. Skip the work to save money now, and you pay later in breached data, emergency fixes and the reputation hit of a public incident.
Our take
An AI tool can get you a convincing app in days, and that is real progress. What it cannot do is make that app safe for strangers, because safety is invisible and a tool optimises for what it can see. The seven gaps here are not signs you did anything wrong. They are the standard shape of the work an AI build leaves for a human.
If you have the skills, work the checklist, fix each gap against the live build, and retest as if you were the attacker. If you would rather hand it over, closing exactly these gaps is what our AI app rescue work does: we audit the build, keep the frontend where it is good, and engineer the secure backend underneath. If you are not sure how exposed you are yet, a short review tells you, and you can get your AI-built app audited before a single real user touches it. The goal is simple. Launch something that is safe the day it goes live, not something you have to rescue after an incident.
Frequently asked questions
Are AI-built apps secure?
Not by default. Tools like Bolt, Lovable, Cursor and v0 are built to make a working prototype fast, so they focus on the visible app, not the hidden security work. A fresh AI build usually ships with API keys in the frontend, no real authorization, an open database and no input validation. The code runs, but it is not safe for real users until a person closes those gaps.
How do I secure a Bolt app before launch?
Treat the Bolt output as a prototype, then audit it. Move every secret out of the frontend into server environment variables and rotate the keys. Add authentication and check it on the server. Turn on row-level security on your database. Validate all input server side, add rate limits, and restrict CORS to your own domains. Test the API directly, not just the UI, before you go live.
Why are my API keys in the frontend code?
Because AI tools wire a service in the quickest way that works, which often means putting the key straight into client code so the browser can call the service. Anything in the browser bundle is readable by anyone who opens dev tools. A key meant for a server does not belong there. Move it to a server environment variable and rotate it, since the old value is already exposed.
What is Supabase row-level security?
Row-level security, or RLS, is an authorization rule that runs inside the database itself. With RLS on, a table returns no rows through the API until you write a policy that says who can read or change which rows. Supabase documents that once RLS is enabled, no data is accessible with a publishable key until you create policies. It is the main thing protecting a Supabase database that the frontend talks to directly.
Can someone steal data from an AI-built app?
Yes, if the gaps are open. The common path is simple: read an exposed key from the browser, or call the data API directly with the public key while the database has no row-level security. Neither needs special skill. If authorization lives only in the UI and the database answers any request, a curious user can read or change records that are not theirs.
Do I need a backend to make my AI app secure?
Usually yes. Secrets, real authorization and server-side validation need code that runs somewhere the user cannot see or edit. A frontend-only build has nowhere safe to keep a secret or enforce a rule. You do not always need a large backend, but you need a trusted server layer, which is often part of adding a proper backend and database to the app.
What is the difference between authentication and authorization?
Authentication proves who a user is, usually with a login. Authorization decides what that user is allowed to see and do. AI builds often add a login screen but skip authorization, so any logged-in user, or sometimes any visitor, can reach data that should be restricted. You need both, and both have to be checked on the server, not just hidden in the interface.
Is client-side validation enough to stop bad input?
No. Checks in the browser improve the user experience, but they are easy to bypass. MDN is blunt about it: never trust data passed to your server from the client, because a malicious user can alter the network request. Every rule that matters for safety or money has to be enforced again on the server, where the user cannot change it.
How much does it cost to secure an AI-built app?
It depends on how much is missing and whether the architecture can be kept. A focused hardening pass on a sound build is modest. A build with no backend, no auth and an open database is closer to a rebuild of the hidden half. As a rough guide, appico MVP work starts from $10,000 including source code and deployment, and a security-only fix on a small, sound app sits well below a full build.
Should I rebuild or just fix my AI-built app?
Keep the frontend if the client-approved design is good, since that can save around 30 percent of the cost and time. Rebuild the architecture, backend and security, because that is where AI tools fall short. If the whole build is frontend-only with no safe server layer, fixing security means building that layer anyway. If your total budget is only $1,000 to $2,000, it is usually not worth acting on.
“Disciplined, committed, over-delivers. Three years in, I would re-hire any day.”
“A factory of ideas.”
“A fantastic-looking and performing website.”
Talk to the team, we reply within 24 hours, and the first consultation is free.
Start a conversation →