Security and Networking Precautions for Vibe-Coded Apps
AI agents generate code that works and quietly isn't safe — leaked secrets, trusting the client, open CORS, no rate limits. The security and networking checklist to run before you ship.
The short answer: AI agents generate code that runs and quietly isn't safe. The recurring failures are always the same handful — committed secrets, trusting the client, string-built SQL, wide-open CORS, no rate limiting, HTTP where HTTPS belongs. None are hard to prevent; all are invisible until exploited. The one rule that covers most of it: the client is controlled by the attacker, so every real check happens on the server. Everything below is that rule applied.
This is the scariest of the four vibe-coding areas because the demo looks identical whether it's secure or not. The login works either way. The difference only shows up when someone hostile arrives — and by then it's an incident, not a code review comment. Here's what to look for before that happens.
1. Never let a secret touch your repo or your bundle
The most common vibe-coding security bug, by a mile: a hardcoded API key. The agent helpfully inlines the key it saw in an example, and now it's in your git history forever (and git history is forever — removing it later means rotating the key anyway).
The discipline: secrets live in environment variables on the server, .env is in .gitignore, and you commit a .env.example that lists the variable names with no values. If a secret ever lands in a commit or a chat, treat it as compromised and rotate it — it's cheaper than assuming it's fine.
2. Trust nothing from the client
Frontend validation is a nicety for users. It is not security. Anyone can open dev tools or send a raw curl request that skips your beautiful React form entirely. So every check that matters happens server-side:
- Authentication — who is this? Verified on the server, every request.
- Authorization — are they allowed to do this specific thing to this specific resource? This is the one agents skip most. A classic hole: the endpoint checks you're logged in but not that the
order_idyou're editing is yours. - Input validation — never trust the shape, type, or size of anything the client sends. Validate against a schema on the server.
The mental model: assume every request is forged by someone who read your frontend code and is now attacking the API directly. Because some of them are.
3. Parameterize every query
String-built SQL is how injection happens, and it's exactly the shape an agent produces when it "just makes the query work."
Same principle for any interpolation of user input into a command, a file path, or a shell call. Use the parameterized / escaped API your library provides; never build the string yourself.
4. Lock down the network edges
A few networking defaults agents get wrong:
- CORS — the agent reaches for
Access-Control-Allow-Origin: *because it makes the error go away. That opens your API to every site on the internet. Allow-list the specific origins you actually serve. - HTTPS everywhere — redirect HTTP to HTTPS, and set
Strict-Transport-Securityso browsers refuse to downgrade. (On a static host this goes in your server config — the same place you'd handle canonical redirects.) - Security headers —
Content-Security-Policy,X-Content-Type-Options: nosniff,X-Frame-Options. Cheap to add, meaningfully reduce the blast radius of other bugs. - Don't leak internals in errors — a stack trace or SQL error returned to the client is a free map of your system. Log the detail server-side; return a generic message.
5. Rate-limit anything an attacker can hammer
An endpoint with no rate limit is a free brute-force target (login), a free way to run up your bill (anything calling a paid API), and a free denial-of-service vector. Agents never add rate limiting unless asked. Put a limit on auth endpoints, on anything expensive, and ideally a sane default across the board.
The one-pass checklist
Before a vibe-coded backend ships, run this:
- [ ] No secrets in source or frontend bundle;
.envgitignored; keys rotated if ever exposed - [ ] Auth and authorization checked server-side on every protected endpoint (including "is this resource yours")
- [ ] All input validated on the server against a schema
- [ ] Every query parameterized; no string-built SQL/commands
- [ ] CORS allow-listed to real origins; no
* - [ ] HTTPS forced; HSTS + core security headers set
- [ ] Rate limiting on auth and expensive endpoints
- [ ] Errors don't leak stack traces or internal detail to clients
- [ ] Dependencies pinned to exact versions; no obvious typosquats
Use agents and skills deliberately
This is the area where a security-and-hardening skill/agent earns its place more than anywhere else — point it at your generated input handlers, auth flow, and query layer specifically to find this exact list. A general-purpose agent produced the code; a security-focused one reviewing it is the single highest-value loop in vibe coding.
- A security-and-hardening skill to audit auth, authorization, input handling, and secret usage before you accept the code.
- An API / interface-design skill so your error contract is deliberate — consistent, non-leaky error responses instead of raw exceptions.
- A dependency/vulnerability scan in CI so a flagged package fails the build rather than reaching production.
Security in a vibe-coded app isn't about being paranoid — it's about remembering the one thing the agent forgets every time: the client is the attacker's playground, so the server is where safety lives. Run the checklist, point a hardening agent at the risky surfaces, and the invisible failures stop being invisible.
This is one of four vibe-coding deep-dives alongside architecture by user scale, choosing a backend, and the frontend — all gathered in the vibe-coding precautions overview.
The vibe-coding series
Things to keep in mind while building with AI agents — this post is one part of the full checklist.
- Start here: the precautions overview
- Architecture for your user count
- Choosing a backend
- Frontend precautions
- Spec & prompt discipline
- Reviewing AI-generated code
- Testing & verification
- Dependency safety
- Data & database precautions
- Error handling & observability
- Cost control
- Keeping it maintainable
- Deployment & platform choice
Frequently asked questions
What are the biggest security risks in AI-generated code?
The recurring ones: hardcoded secrets committed to the repo, trusting the client (validation and authorization done only in the browser), SQL injection from string-built queries, overly open CORS, and missing rate limiting. Each is easy to introduce by accident and invisible until it's exploited, so review for them explicitly.
Where should I store API keys and secrets?
Never in source code or the frontend bundle. Store them in environment variables (or a secrets manager) referenced by name on the server only, and keep the .env file out of git with .gitignore plus a committed .env.example that lists the names with no values. Anything shipped to the browser is public — treat it that way.
Do I need to validate input on the server if the frontend already validates?
Yes, always. Frontend validation is a UX convenience; it can be bypassed trivially with curl or dev tools. Every security and data-integrity check — authentication, authorization, input validation, rate limits — must be enforced on the server, because the client is fully under the attacker's control.