Skip to content

Is your Replit app safe?

Is Replit safe to host a real app on? Building and publishing are one step there, which is convenient, and it is also what makes the checks worth doing.

Vlad Tkachenko4 min read
Reeve's security-check card for Replit apps, with the Replit logo on a white tile.

Logos are the property of their respective owners, shown to indicate compatibility.

In short

  • A Replit app is safe to host, but building and publishing are one motion, so there is no deploy step to catch a mistake in.
  • Replit Secrets keeps a key out of your files. It cannot keep it out of the browser if your browser code is what reads it.
  • If your data is in Supabase, the setting that decides who may read it is Row Level Security, and it is set per table.

Replit runs your app and publishes it from the same place you build it. That is most of its appeal, and it also means the gap between "I changed something" and "the internet can see it" is roughly zero. There is no separate deploy step to pause at and think.

Here is the part that guide after guide gets wrong: storing a key in a secrets manager does not make it private. The manager decides where the value sits at rest. Your code decides where it travels, and if your code takes it into a browser, that is where it ends up.

What a published Replit app hands to a visitor

The whole front of it, always.

Think of it as a shop. Your app's pages, forms and buttons are the shopfront, handed in full to every visitor who loads your site: a browser cannot render a page it was not sent. Your data lives in the stockroom, a separate building on the internet with its own address and its own lock.

The nuance people miss on Replit is where the boundary falls. Code that runs on the server and code that runs in the visitor's browser sit in the same project, often in adjacent files. A value read on the server stays on the server. The same value read by browser code is compiled into what you publish. Replit Secrets keeps a key out of your source files, which is genuinely useful, but it cannot decide which half of your app reads it.

Is it bad that my Replit app has a key in it?

Usually not. It depends on which key, and there are two that look nearly the same.

Both are called API keys. Only one of them was ever meant to be readable.

A publishable key identifies your project and nothing more. Supabase names it sb_publishable_… in new projects and anon in older ones, and it is built to sit in a browser. A secret key (sb_secret_…, or service_role before the rename) ignores every rule you have set and reads and writes every row in every table.

If a scanner tells you a key is exposed, this is the first thing to establish, because one of those is a normal Tuesday and the other is worth stopping for. The check takes about a minute.

And "nobody knows my URL" is not a defence. Automated crawlers read public sites looking for exactly these strings, continuously, with no idea who you are.

What decides whether strangers can read your data

The rules on your database, which are not part of your Replit project at all.

Your app and a stranger knock on the same door. The setting decides who gets in, not your app's screens.

If your data is in Supabase, the setting is Row Level Security: a per-table switch deciding row by row who may read what. Off, and your publishable key returns the entire table to anyone. On, with a policy written, it returns only what that policy allows.

Two things decide whether you have it, and neither is obvious from inside your app. Supabase enables Row Level Security by default for tables created in the dashboard's Table Editor, and not for tables created by running SQL, which is how a migration file, or an assistant writing your schema, creates them. And a table can carry the setting while its policy still lets everyone through, so the switch on its own restricts nobody.

Removing a page from your Replit app changes none of this. The stockroom does not know your shopfront exists.

How to check your own Replit app in about ten minutes

Work out which half reads each secret. For every key in your project, find the code that uses it and decide whether that code runs on the server or in the browser. Anything the browser reads is published, wherever it was stored.

Load your own published app and open DevTools. The Network tab shows exactly what a visitor receives. It is the same view an outsider gets, and it settles the question faster than reading files.

Open Authentication → Policies in Supabase. Anything showing Row Level Security as disabled is readable by anyone with your project address.

Then look from the outside properly. That is what our free scan is for. It reads your live site the way any visitor would and gives you a grade in about 20 seconds, with no account: scan your app.

What to do

  • On Replit, building and publishing are one motion. There is no deploy step to catch a mistake in.
  • A secrets manager guards a value at rest. Browser code publishes whatever it reads, wherever the value came from.
  • A publishable key in your app is correct. sb_secret_… and service_role are the ones to rotate today.
  • Tables created by running SQL start without Row Level Security, and turning it on still leaves every row readable until a policy says otherwise.
  • An unknown URL is not protection. Crawlers do not need to know who you are to find your site.

Pick the key your app uses most and trace which half of your project reads it: server or browser. That one answer tells you more than any amount of reading, and the 10-minute security checklist covers the rest of the surface once you have it.

What can actually go wrong with a Replit app

None of these mean you did anything wrong. They come with building quickly. Here's what's worth checking:

  • A secret key in your code instead of Replit Secrets

    Replit gives you a Secrets manager so keys stay out of your code. But it's tempting to paste a key straight into a file to get things working, and if that file runs in the browser, or your Repl is public, anyone can read it. Reeve finds the keys in your app's loaded code and tells you which are safe to expose and which need to move.

  • A public Repl exposing your source (and keys)

    On many plans, Repls are public by default, meaning your code, and anything hardcoded in it, can be read by anyone with the link. Reeve checks what your deployed app exposes from the outside, so you know if private details are visible.

  • Your database left open (RLS off)

    If your app stores data (in Replit's database, Supabase, or another Postgres), there's usually a rule for who can read or change each row. If it's off or misconfigured, your tables can be open to anyone who finds the address. It's the most common serious issue, and it hides until you check.

  • An exposed .env or config file

    Keys often live in a .env file that shouldn't ship. Sometimes it ends up reachable on the deployed site anyway, which is a shortcut to everything sensitive. Reeve checks whether yours is quietly accessible.

  • Source maps left on

    A "source map" reveals your app's original code to anyone who looks. Handy while building, but in production it gives strangers a readable copy of how your app works and makes other gaps easier to find. Reeve checks whether yours are exposed.

  • Missing safety headers & open endpoints

    Small settings that tell browsers how to protect your visitors, plus whether your data endpoints answer to anyone or any website. Each one is minor on its own, but together they widen the gap. Reeve flags what's missing.

What Reeve is, and what it isn't

Reeve is a free, read-only check from the outside, like an inspector trying the doors without going in. It catches the common, high-impact mistakes fast. It is not a full security audit, and a clean grade isn't a guarantee; it means the obvious doors are shut.

Replit gives you good tools (a Secrets manager, and controls over whether a Repl is public), and they genuinely help when you use them. What Reeve adds: a check of what your deployed app actually exposes from the outside, in case a key slipped into code or a Repl is more public than you thought, explained in plain words you can act on. And if checking it yourself sounds like a chore, that's the part we take over.

Want it handled, not just checked?

Reeve Care keeps watching your app, backs up your data, and helps you fix what breaks, so you can keep building instead of worrying.

Learn about Reeve Care

FAQ

Are Replit apps secure by default?

Replit gives you the pieces to be secure (Secrets, deployment controls), but "by default" depends on whether keys stayed in Secrets, whether your Repl is private, and whether your database rules are on. The only way to know is to check what's exposed, which Reeve does free in about 20 seconds.

Is it safe to keep API keys in my Replit code?

It's much safer to keep them in Replit Secrets than in your code. A key written into a file can be read if that code runs in the browser or your Repl is public. Reeve finds keys in your loaded app and tells you which are safe to expose and which need to move into Secrets.

Can people see my code if my Repl is public?

Yes. A public Repl means your source, and anything hardcoded in it, can be read by anyone with the link. Reeve checks what your deployed app reveals from the outside so you can tell whether private details are showing.

Will scanning my Replit app break anything?

No. Reeve only looks at what's already public from the outside. It never logs in, never changes anything, and never downloads your files. Read-only, like checking whether a door is locked without stepping inside.

I put my keys in Replit Secrets instead of in the code. Does that make them private?

It keeps them out of your files, which is worth doing and solves a real problem. It does not make a value private once your app sends it to a browser. If the code that uses the key runs in the visitor's browser, the key travels there whatever it was stored in. A secrets manager guards a value at rest, and your app is what carries it out to the visitor.

My Replit app is small and nobody knows the URL. Is that enough?

No, and the reason is that nobody has to know you. Automated crawlers work through public sites looking for key-shaped strings and open database endpoints continuously, without any idea who owns them. Being unknown is not the same as being unreachable.

Where do I look to see whether my database is open?

If you use Supabase, open the project and go to Authentication, then Policies. Every table in the public schema is listed with whether Row Level Security is enabled. Anything disabled is readable by anyone holding your project URL and publishable key, both of which are inside your published app.

Written by

Vlad Tkachenko

Founder, Reeve

I spend my time looking at apps built with Lovable, Bolt, v0, Cursor and Replit, and at the short list of mistakes that keep turning up in them.

More about the author

Built somewhere else? We've got the same honest rundown for:

← See all builder safety guides

Automated external check, not a full audit. Absence of findings is not a guarantee of safety.