Replit app security checklist (from a security engineer)
By Pritesh Ghodge, Senior Solutions Engineer (cybersecurity) · Last updated 11 November 2026
Scan your app free — check what your published Replit app serves to a stranger.
Abbi Labs looks at your live site from the outside: secret keys in the JavaScript, Supabase tables readable with your public key, exposed .env and .git files, source maps, and security headers. No sign-up for the quick check.
No sign-up. Read-only public-resource and protocol metadata checks. No model prompts or tool execution. Scan only sites you own or are allowed to test.
Run on every deploy or use from Cursor / Claude Code via MCP →
Weekly AI-app security checklist
One short email a week: a practical check for apps built with Supabase, Next.js and AI tools (RLS, leaked keys, headers and more). Unsubscribe anytime.
Replit Agent can build a full-stack app (often a React/Vite frontend with an Express or Python backend, a database, and auth) and publish it to a .replit.app address in one session. Replit handles a lot for you: Secrets, a pre-publish security scan, private dev previews. What it can't know is which data belongs to which user, or whether an API route the Agent added should be public. Here's the checklist I'd run on a Replit-built app before sending the link to real users.
1. Check the published URL, not the editor
The preview inside the workspace is not what strangers get. After you publish (and after every republish), open the .replit.app URL or your custom domain in a private window and run the checks below against that. Also check the access setting you chose when publishing (Public, Password protected, Workspace only or Invite only). If the app isn't meant for the public yet, a private option is the simplest fix of all.
2. Secrets stay on the server
Replit's Secrets tool encrypts values and gives them to your app as environment variables, and syncs them to the published app. That only protects a key while server code is the only thing that reads it. Watch for the ways it leaks anyway:
- Agent pastes a key straight into a React component or a config file "to get it working".
- A key is put in a
VITE_variable. Vite inlines everyVITE_variable into the JavaScript every visitor downloads. - A backend route returns the key (or a whole config object) to the browser.
Keys that must never reach the browser: OpenAI/Anthropic/Gemini, Stripe secret keys and webhook secrets, the Supabase service_role or sb_secret_ key, Resend and other email keys, and database connection strings. Quick check: open your published site, DevTools → Sources (or search the loaded JS) for sk_live, sk-, sb_secret_, service_role and postgres://. If a key was ever shipped, rotate it at the provider. Removing it from code doesn't un-leak it. More: NEXT_PUBLIC_ and VITE_ variables are shipped to every visitor and AI API key exposed in your frontend.
3. Every API route checks who is calling
Moving an AI or payment call to the backend hides the key, not the endpoint. Anyone can call https://your-app.replit.app/api/... with curl. For each route Agent created, ask:
- Does it require a signed-in user and verify the session on the server, or is it deliberately public?
- Does it check the user owns the record whose ID came from the browser (not just that they're signed in)?
- Does it work out prices and plan limits on the server instead of trusting values sent by the browser?
- For Stripe or other webhooks: does it verify the signature before doing anything?
- If each call costs you money (AI, email, SMS), is there a per-user limit?
A prompt you can paste into Replit Agent:
List every backend API route in this app as a table: method, path,
whether it requires a signed-in user, whether it checks the user owns
the record it reads or changes, and whether it calls a paid API.
Flag any route that reads or writes user data without both checks.
Show me the fixes before applying them.4. Know which database you're on
Replit's built-in database, used only from your server: the browser can't reach it directly, so your API routes (step 3) are the whole security boundary. Make sure the connection string is only in Secrets and never logged or returned.
Supabase from the browser: the publishable/anon key in your frontend is meant to be public, so Row Level Security is the boundary. Every table needs RLS on, and user-owned tables need policies tied to auth.uid(), not using (true) or with check (true). The 60-second test (your project URL and the public key from your app):
curl -s "https://YOUR-PROJECT.supabase.co/rest/v1/profiles?select=*&limit=1" \
-H "apikey: YOUR_PUBLIC_KEY" \
-H "Authorization: Bearer YOUR_PUBLIC_KEY"[] or a permission error is what you want for private tables. Walkthrough: how to check if your Supabase tables are readable by anyone. For write-side holes an outside scan can't test, paste one read-only query into the free Supabase RLS policy checker.
5. Keep dev URLs private
Per Replit's docs, development URLs on replit.dev are private by default. If you turned off Private preview (in Networking) to show someone a work in progress or test a webhook, anyone with that URL can use the running app, often against your dev data. Turn it back on, and use Replit's external access tokens for webhook testing instead.
6. Nothing extra is published
From a browser, try /.env, /.git/HEAD and a .map next to one of your JS files on the published URL. You want a 404 or your app's normal page, not a file. An Express app that serves the project folder as static files (instead of just the build output) is the usual way this happens. Vite only ships source maps if build.sourcemap is on. See exposed .env, .git and source maps.
7. Security headers
On Replit your own server usually sends the response headers, so they're your job. Check with curl -sI https://your-app.replit.app and look for Content-Security-Policy, Strict-Transport-Security and clickjacking protection (X-Frame-Options or CSP frame-ancestors). In Express, a middleware such as helmet sets sensible defaults. Examples: security headers for vibe-coded apps.
8. The two-account test
Sign up as user A and create some data. In a private window, sign up as user B and try to open A's pages by changing IDs in the URL, and watch the network tab for responses that contain A's data. Then sign out and call the same API routes with curl. Only test apps you own.
9. Re-check after every republish
Each Agent session can add a route, a variable or a policy. A clean scan last week says nothing about today's build. Re-run the outside check after you republish, or let Monitor re-scan for you.
What an outside scan adds, and what it can't do
Replit's pre-publish scan reads your code. An outside scan checks what the published site serves to a stranger: the built JavaScript, files on the host, the headers, and what your public Supabase key can read. It can't see your server code, your business rules, or test as a signed-in user, so it doesn't replace steps 3 and 8.
Abbi Labs' free quick check covers leaked keys in JS, Supabase tables anyone can read with the public key (limit=1), exposed .env/.git, and security headers. Full scans on a verified domain also cover public storage buckets and source maps.
Keep it that way
Abbi Labs scans your live app for leaked keys, Supabase tables readable with your public key, exposed .env/.git files and security headers. Monitor re-scans weekly and after deploys, and emails you only when something new appears.
FAQ
Does Replit check my app's security before I publish?
Replit runs a security scan of your project before publishing (its docs describe static analysis plus an AI review in the Project Security Center), and you can choose to block publishing on critical findings. That looks at your code. It's still worth checking what the published URL actually serves to a stranger: the built JavaScript, files on the host, headers, and what your public database key can read. The two views catch different mistakes.
Are Replit Secrets safe?
Replit Secrets are encrypted and exposed to your app as environment variables on the server, and they sync to your published app when you publish. They stay private as long as only server code reads them. If Agent copies a secret into frontend code, a VITE_ variable or an API response, it is shipped to every visitor, and the Secrets tool can't protect it anymore.
My Replit app uses the built-in database. Do I need RLS?
If only your server talks to the database (through DATABASE_URL), the database is not reachable from the browser, so your API routes are the security boundary. Every route that reads or changes data must check who is signed in and whether that user owns the record. If your app uses Supabase from the browser instead, RLS policies are the boundary and the Supabase checks in this guide apply.
Is my Replit development URL public?
Replit's docs say development URLs (on replit.dev) are private by default and require sign-in. Turning off Private preview in Networking makes the dev URL public to anyone who has it. Use the published .replit.app URL (or your custom domain) for sharing, and turn Private preview back on after testing.
Does Abbi Labs work with Replit apps?
Yes. Paste your published .replit.app or custom-domain URL. The free quick check needs no sign-up and looks at your home page headers, its JavaScript for secret keys, /.env and /.git, and whether Supabase tables your code queries (plus common names) return rows with your public key. Full scans on a domain you've verified you own add storage buckets and source maps. It can't log in as your users or see your server code, so it doesn't replace the two-account test.
Related guides
- Stripe webhook signature verification for AI-built apps
- Cursor-built app security checklist (from a security engineer)
- Is my Bolt.new app secure? A security checklist before you publish
- Lovable app security checklist (from a security engineer)
- v0 app security checklist (from a security engineer)
- OpenAI, Claude or Gemini API key exposed in your frontend? What to do now
- How to check if your Supabase tables are readable by anyone
- 3 files your production site shouldn't be serving: .env, .git and source maps
- Security headers for Lovable, Bolt, v0 and Cursor apps
- Free tool: Supabase RLS policy checker