A friend of mine shipped a side project in a single weekend. She never opened a terminal except to run one deploy command, described what she wanted in plain English, and watched a working app appear on a real domain by Sunday night. Two weeks later a stranger emailed her to say the admin dashboard had no login on it at all.

That story is not rare anymore. Vibe coding, where you describe the outcome and let an AI assistant assemble the implementation, has collapsed the distance between an idea and a running product. The code usually works. The trouble is that working and safe to expose to the internet are two different bars, and the second one rarely makes it into the prompt.

The fix is not to stop building this way. Speed is the whole point, and giving it up would be silly. The fix is to add a short, repeatable set of checks between the moment an app runs on your laptop and the moment it starts accepting traffic from strangers. What follows is that set, roughly in the order it matters.

Where the Risk Actually Lives

An AI assistant writes what you asked for, not what you forgot to ask for. That gap is the whole security story. Ask for a dashboard that shows customer orders and you will get one, complete with a clean table and a search box, and quite possibly a database query that any logged out visitor can reach. Nothing broke. The requirement simply was never stated.

The categories are not exotic, either. OWASP put broken access control at the top of its 2025 list of application security risks, with security misconfiguration right behind it, and those two describe the majority of what goes wrong in a generated app. Treat that pair as your baseline, and most of the scary headlines stop applying to you.

Get the Secrets Out of the Code First

Generated code loves a hardcoded value. An API key pasted into a config file runs perfectly in development, survives the first deploy, and then sits in your Git history forever. Move every credential into environment variables or a managed secrets store before you push anything public, and rotate the ones that were ever committed, because deleting a line does not delete the commit.

Automate the part you will forget. GitHub's secret scanning watches full branch history for exposed keys and tokens, and push protection can stop a credential from landing in the repository in the first place. It takes a few minutes to switch on and it will catch you on a tired Friday.

Put Real Authorization Behind Every Route

Authentication asks who you are. Authorization asks what you are allowed to touch, and vibe-coded apps tend to nail the first and skip the second. A login screen on the front end means nothing if the API behind it answers any request that arrives with a valid session, regardless of whose data is being requested.

Walk your routes one at a time. For each one, say out loud who should be able to call it, then try calling it as someone else. Change an ID in the URL and see what comes back. Five minutes of that will tell you more than any scanner, and the checks belong on the server, never in the interface layer where a curious user can route around them.

Tighten the Configuration Before You Point a Domain at It

Defaults are built for development, not for the open internet. Debug modes print stack traces to strangers, permissive CORS rules invite any origin to call your API, and a storage bucket set to public will happily serve every file in it. Go through the deployment settings by hand and turn the loose ones off.

NIST's Secure Software Development Framework is worth skimming here, because it organizes this work into four plain buckets: prepare, protect the software, produce well-secured software, and respond to vulnerabilities. You do not need the full document. The structure alone is enough to turn a vague worry into a short list, and platform guidance on how to deploy vibe-coded apps securely covers the same ground with a builder's vocabulary.

Plan for the Day Someone Comes Looking

Shipping is not the end of the job. Logging, rate limits, and a plan for abuse matter as much as the code itself, because availability is a security property too. Anyone who has run a public game server already knows this, and the same layered thinking that shows up in a practical DDoS prevention guide for hosts applies cleanly to a small app on a cheap VPS.

Cap requests per IP. Log authentication failures and watch them. Keep dependencies patched, since a generated project often pulls in packages nobody on your team has read. And write down, in advance, what you would do if a key leaked, because the middle of an incident is a terrible time to invent a process.

None of this asks you to write the code by hand. The assistant can do the typing, and it will often do it better than you would at eleven at night. What it cannot do is decide what your app is allowed to expose, because that judgment depends on your users, your data, and a risk tolerance nobody has told it about.

Run the same pass every time and it stops feeling like a chore. Secrets out of the code, authorization on every route, defaults tightened, monitoring on, incident plan written. That is twenty minutes of work on a small project, and it is the difference between a weekend build and something you can leave running.

My friend patched her dashboard in an afternoon. The app is still live, still built the fast way, and now it has a login that actually guards something. That is the whole ambition here, and it is well within reach on your next build.