← Back to blog
Findings Apr 2, 2026 · 3 min read

Top 5 security issues on Replit apps

Replit's quick-deploy is great. It also makes it really easy to ship your API keys to the internet.

Replit + Supabase or Replit + raw OpenAI/Anthropic calls is the other dominant vibe-coding combo. We scanned ~60 Replit-deployed apps across two batches — here's what broke.

1. Hardcoded AI provider keys in the JS bundle (real, observed)

We found a Replit app this week shipping a valid sk-ant-api03-* Anthropic key and an sk-proj-* OpenAI project key in its Vite-built client bundle. Plus two Google API keys. The bundle is served publicly. Anyone visiting the site — or just running curl — gets working credentials to burn through the account's Anthropic and OpenAI quota.

We reported the keys to Anthropic and OpenAI for revocation within the hour. But this is a recurring pattern: Replit's tutorials often show AI calls happening client-side because it's the fastest path to a working demo. People deploy the demo, forget to move the calls server-side, and the keys live in production.

Fix: Every call to an AI provider goes server-side. Put the key in a Replit Secret, read it with os.environ[...], and expose a /api/ai endpoint on your own backend. The client never sees the key.

2. No server-side auth on /api/* endpoints

A lot of Replit apps are "hackathon-weekend" projects that never added auth beyond a client-side check. The JS bundle contains a fetch to /api/orders that returns everyone's orders — there's just no check on the server. Open one in DevTools, change the ID, get someone else's data.

Fix: Before returning anything, verify a session/JWT and scope the query by the authenticated user. auth.uid() = user_id in Supabase, session middleware in Flask/Express.

3. Missing HSTS + header hygiene (every app)

Replit's default deploy doesn't set strict transport security. We see this across every app we scan. Most people never notice because the app works over HTTPS anyway — but the browser is willing to downgrade on a compromised network.

Fix: Set Strict-Transport-Security: max-age=31536000; includeSubDomains in your app's response headers. One line in FastAPI / Flask / Express.

4. TLS cert hygiene on custom domains

Replit handles TLS on their edge for the managed *.replit.app domain — those are fine. The risk surface is custom domains: if you point app.example.com at a Replit deploy, you're responsible for cert renewal and a missed renewal will quietly expire. The scanner flags certs within 30 days of expiry as a MEDIUM, anything self-signed as HIGH.

Fix: If you're on a custom domain, put Cloudflare in front (free tier handles TLS termination + auto-renews their edge cert). Or run Caddy / a Let's Encrypt cron, but Cloudflare is one click.

5. Debug + admin endpoints exposed

The scanner probes ~25 known-leaky paths — /actuator/env (Spring Boot), /_debugbar (Laravel), /server-status (Apache), /.git/config, /terraform.tfstate, /.env variants, /wp-config.php.bak, /_ignition/execute-solution (Laravel RCE), and others. None of the Replit cohort happened to be running the relevant frameworks in this batch, but the canonical pattern that does show up on Replit specifically is a /api/health or /api/debug endpoint that returns more than it should — and AI assistants love writing those.

Fix: /health should return {"status": "ok"} and nothing else. Any debug endpoint should be gated behind if (process.env.NODE_ENV !== 'production') OR removed entirely before deploy. If you're on Spring Boot, secure or disable the actuator endpoints (management.endpoints.web.exposure.include=health).

Why it keeps happening

Replit's deploy-in-one-click is its killer feature. It's also why the friction between "tutorial" and "production" is lower than it's ever been — and tutorials optimize for shortest-path-to-working, not safest-path-to-deployable.

A pre-deploy security lint, or a "your bundle contains a key that looks like sk-ant-*" warning, would cut most of this at the source. Until then, scan before you launch.

Run the same scan on your app

One free scan, no credit card. Works with any URL or IP — finds the issues from this post and more.

Start free