· Vibe coding ·Replit ·Security

Vibe coding with Replit Agent — 5 issues every build ships

Replit Agent ships the whole thing for you — code, database, deploy, domain. It also ships five specific problems every time, in the same order.

Replit Agent is the most “hands off” of the major vibe-coding tools. You describe what you want, it provisions the database, writes the code, deploys it, gives you a URL, and tells you you’re done. For first-time builders this is genuinely magic. For everyone who’s shipped software before, the magic is also the source of a specific failure mode: you never see the seams, so you never see what’s broken at the seams.

This post is the five problems we see in nearly every Replit-built app we scan, in the order Replit Agent introduces them.

Why Replit-built apps fail differently

The defining trait of Replit Agent is end-to-end autonomy. It writes the code and runs the deploy. The reason this matters for security:

  • You don’t pick the database. Replit picks. Often Postgres-compatible, often with default-open permissions for the agent’s convenience.
  • You don’t see the secrets. Replit Agent generates and stores them on your behalf. They’re “secure” inside Replit’s secrets store — but if the agent decides it needs them in the client bundle to make a feature work, they go there too.
  • There’s no review step. Replit’s “Approve and deploy” flow exists, but the agent is good enough that most people approve without reading. The result is shipping code you’ve never opened.

The five issues below all flow from this.

Issue 1: secrets the agent generated end up in the client

Replit Agent has a habit of generating API keys for services and storing them in your Replit Secrets. So far so good. The problem is that when it builds the feature that uses the secret, it sometimes routes it through the frontend “because the API expects it as a client-side parameter.”

We’ve seen this with Stripe (publishable key is fine, secret key in the bundle is not), with OpenAI (the entire org key, sometimes), and with internal admin tokens Replit Agent invented.

How to check:

  1. Open your deployed Replit app and open devtools.
  2. In Sources, find the main JS bundle.
  3. Search for sk_, eyJ, and the names of any services your app integrates with (stripe, openai, anthropic).
  4. If anything that shouldn’t be public is present, rotate it immediately and move the call server-side.

Issue 2: the database is wide open

If Replit Agent provisioned your database, there’s a decent chance it set up access without the usual “only authenticated users from your app can read” layer. The agent did this to make iteration fast — it could write code, run it, see the result, all without dealing with auth handshakes.

You can test this. Open an incognito window. Find any database-backed page in your app (a list of products, a user feed, anything). Open devtools Network tab and watch the request that loads the data. Copy the request URL. Paste it in a different browser, with no login. If you get data back, anyone gets data back.

The fix is non-trivial in Replit. It usually involves moving from “agent-mode-friendly direct access” to a proper API layer with auth. Replit Agent can do this if you ask it specifically: “Audit my database access layer. Add server-side authorization to every endpoint that reads user data. Test that an unauthenticated request returns 401, not data.”

Issue 3: the agent’s “improvements” undo your security work

Specific to Replit Agent because of how it iterates: you fix something (add auth, enable RLS, restrict CORS), then ask the agent for a new feature. The agent’s next iteration sometimes reverts the security work because it sees those checks as “the reason this new feature doesn’t work yet.”

We’ve watched the agent re-enable wildcard CORS, drop a “now blocking the request” auth middleware, and disable RLS on a table to make a new query succeed. Each individual move makes sense to the agent. The cumulative effect is silently undoing everything that kept the app safe.

How to prevent: add a replit.md (or equivalent project context) that lists your security invariants and tells the agent never to weaken them without asking. Same pattern as .cursorrules or CLAUDE.md. The version we use:

SECURITY INVARIANTS — do not weaken any of these to make a feature work.
Ask first.

- Every API route that returns user data checks authorization server-side.
- CORS Access-Control-Allow-Origin is never "*" on routes that handle auth or user data.
- Row-Level Security is never disabled on existing tables.
- Secrets (API keys, service role keys) are never moved from server-side storage to the client bundle.
- The login page is never bypassed "for testing."

When a feature you're building requires changing one of these, stop and ask me. Explain what you'd weaken and why, and wait for explicit approval.

Issue 4: the deployed URL leaks information

By default, Replit deploys your app to a *.replit.app subdomain. Two related issues:

  • Your replit.app URL is publicly indexed. Search engines find it, sometimes before your custom domain. People link to it. If you ever decide to take the app down, the URL persists in Google for a while.
  • The Replit project metadata can sometimes be inferred from the URL. The project name. The owner’s username. The fact that it’s a Replit project — which means certain attack patterns become more likely.

The fix: when you connect a custom domain, also set a <link rel="canonical"> tag pointing at the custom domain on every page, and add the Replit URL to your noindex if Replit’s defaults didn’t.

Issue 5: the agent commits things to git that shouldn’t be there

Replit Agent treats your repo as a working tree. It commits whenever it finishes a step. That’s good for traceability and bad when “what it finished” includes:

  • A .env file with real credentials.
  • A seed.sql with test users whose passwords are “password.”
  • A debug.html with comments like // TODO: remove this before launch, has admin token.

These commits land in your git history before you ever look at them. Public repo: anyone can read them. Private repo: still in history forever, and anyone you grant repo access to inherits the keys.

How to check: git log --all --diff-filter=A --name-only | grep -E "(env|secret|credential|test|debug|seed)". Read what comes back. Rotate anything questionable.

What ties them all together

All five issues come from the same source: Replit Agent optimises for “the demo works.” It does the work that gets you to a working demo as fast as possible, and treats security as a layer to be added later — if you ask. If you don’t ask, the demo is what ships.

This isn’t a defect, exactly. It’s the explicit trade-off Replit made to be the most autonomous tool in the category. You just have to know what to put back in.

Patchable is the layer that puts it back in. We scan your deployed Replit app from the outside — the same way an attacker would — and tell you which of these five (and seventy other) issues are actually present. Each finding ships with a paste-ready prompt for Replit Agent, Claude Code, Cursor, or whatever tool you build with. Free to scan. You only pay if there’s something to fix.

Replit Agent ships your app. Patchable tells you what your app is shipping. Run the scan.

Have us scan your app.

We're taking on a small number of scans right now and running each one personally. Drop your app below — we'll take a look and reach out if it's a fit, usually within a day.

Built by Ahmet & Leonardo in Tallinn. We answer every email to hi@patchable.dev.