Is Replit safe? What the platform protects, and what your app still needs

Replit is safe as a platform: it isolates environments, encrypts secrets, keeps development and production databases apart and scans code before you publish. The app Agent builds is yours. Replit's shared responsibility model puts access control and pen testing of your app on you, and that is where leaks show: routes without an owner check, keys in the bundle, apps left Public.

The team behind Keybrum's attacksUpdated 16 min read

In short

  • Replit runs the platform: isolated environments, encrypted Secrets, DDoS filtering at the edge, SOC 2 Type II. Its own shared responsibility model makes access control and pen testing of your app your job.
  • Since the July 2025 database deletion, every app has separate development and production databases. Agent reads production only through a read replica, and production keeps 7 days of point-in-time recovery by default.
  • The browser never talks to Replit's database. Your data leaves through your own Express routes, so the leaks sit there: no sign-in check, or a sign-in check with no owner check.
  • Security Center Level 1 is free and checks dependencies only. Level 3 adds a black-box test of the Preview, while your published app runs with its own secrets, database and users.
  • Test the published URL after every republish: signed out, as a second account, and for secret keys in the JavaScript.
On this page

Is Replit safe? The short answer

Yes for the platform, with a condition for your app. Replit isolates development environments from each other, encrypts secrets with AES-256, encrypts traffic and stored data, filters DDoS at the edge and holds a SOC 2 Type II attestation. It also blocks malicious packages at install time and runs a security scan before each publish. None of that decides who can read the data inside the app Agent wrote for you.

Replit says so itself. Its shared responsibility model lists user management, access control, the data your app handles and penetration testing of your app as yours. Replit answers for the Agent, the platform and the infrastructure. You own the code Agent generates, including how it signs people in and what it lets each of them read.

The worry behind many of these searches dates from July 2025, when Replit Agent deleted the production database of SaaStr founder Jason Lemkin during a code freeze. Replit's CEO called it unacceptable and the company moved apps to separate development and production databases. Today Agent can change the development database but only reads production through a read-only replica, and production keeps 7 days of point-in-time recovery by default. That incident was about the agent. The risks below are about the app.

What Replit is responsible for, and what you are

AreaWho owns itWhat it means for your app
Platform, runtime, edge and encryptionReplitSandboxes, patches, DDoS and WAF, TLS. After a critical Node.js flaw in January 2026, published apps got the patched runtime on their next republish.
Secrets storageReplitValues encrypted at rest and never logged in plain text. Putting every key in Secrets, not in code, is your part.
Dependency vulnerabilitiesReplit detects, you fixNew CVEs in your packages appear in the Security pane. The fix reaches production when you republish.
Backups of code and Replit databasesReplitProduction gets point-in-time recovery; scheduled daily backups are optional.
Who can open the published appReplit gives the switch, you choosePublic, password protected, workspace only or invite only.
User management and access controlYouWho can sign in, and which records each user can read or change.
Code review and pen testing of your appYouReplit's scans help. The responsibility stays with you.
Privacy and compliance of your appYouGDPR, HIPAA, PCI DSS: they apply to what you built.
Condensed from Replit's shared responsibility model.

The stack Replit Agent builds, and where it leaks

Web apps are Replit's default output, and each one is full stack. Replit's docs describe the pieces: Clerk's React components in the frontend, Clerk's Express middleware on the API routes, and drizzle-kit migrating a PostgreSQL 16 database. In practice: a React app, an Express server, and Postgres through the Drizzle ORM.

That shape matters. On Supabase or Firebase, the browser queries the database and database rules protect the data. In a Replit app, the browser never reaches the database: every record passes through a route in your own server. So the leaks in a Replit app sit in that server code, and in what the build ships to the browser.

LayerWhat Replit sets upWhere leaks happen
FrontendReact, compiled into the JavaScript every visitor downloadsKeys bundled into that JavaScript (if the frontend builds with Vite, every VITE_ variable it reads ships there), and admin screens hidden only by a React condition
APIExpress routes, also used by a mobile app in the same projectRoutes with no sign-in check, or a sign-in check but no owner check
DatabasePostgreSQL 16 through Drizzle: one database for development, one created for production when you publishNot reachable from the browser. It leaks through the API, or through a leaked production connection string
AuthClerk by default on Starter, Core and Pro; Replit Auth by default on EnterpriseSign-in is handled for you. Authorization, who owns which record, is your code
FilesApp Storage: Google Cloud Storage buckets that are always private, read by your serverThe route that serves a file decides who gets it
SecretsThe Secrets tool, read as environment variables, with separate production secretsSafe on the server. Exposed once copied into frontend code, a project file or the Agent chat
AIReplit AI Integrations (paid plans), billed to your Replit credits at public API pricesAn AI route with no sign-in and no limit lets strangers spend your credits

What Replit's own security tools catch

Replit's own security tools are worth using. Here is what each one covers:

ToolWhat it checksCost and default
Package FirewallBlocks packages Socket flags as malicious or compromised, at npm install or pip install timeOn by default for every builder, nothing to set up
Dependency scans and Level 1Match new CVEs against your packages, automatically or on demandFree
Auto-Protect patchesAgent prepares and tests a patch for a vulnerable dependencyOff until an admin sets a severity; billed as Agent work
Scan while you buildA lightweight review of the files Agent changes, for insecure patterns and hardcoded secretsAutomatic, no separate report
Publish checksA scan before each publish. Block publishing of critical vulnerabilities stops critical findings from shippingSetting in Publish > Advanced
Level 2: Security AgentMaps routes and data flows, runs Semgrep and HoundDog.ai, then a model judges what is exploitable: SQL injection, XSS, CSRF, data in logsPaid plans
Level 3: AI pentestLevel 2 plus a black-box test of the running Preview. On Clerk apps it tests signed out and as a synthetic user, plus a second synthetic user when it needs to check ownershipExtra plan and access requirements

Run them. Then know their limits, which Replit's docs state plainly:

  • Level 1 only reads your dependencies. A clean dependency scan says nothing about your own routes.
  • Publish checks do not run Level 2 or Level 3. Passing one says nothing about your access rules either.
  • Level 3 tests the Preview, not the published app. The published app runs with its own secrets, its own database and, with Clerk, its own user store. A clean Preview does not prove what strangers reach at your public URL.
  • A source review reasons about code. Replit's own research found AI-only scans nondeterministic, which is why it pairs the model with static analysis (Semgrep, HoundDog.ai), and its docs say a scan is not a complete security review.

Replit security concerns, with concrete examples

These are the holes that remain after Replit's defaults, in the order we would check them. Each one is a type of mistake, not a specific app.

RiskWhat a stranger can doHow it happens on Replit
Route with no sign-in checkRead every record a list route returns, with no accountA route added without the auth check. Clerk's clerkMiddleware() alone only reads the session; the route must check getAuth(req).userId
Sign-in check, no owner checkSign up, change an id in a request, then read or edit another customer's recordThe query filters on the record id only. Replit's own login tutorial warns that two test customers may see each other's reservations
Admin page guarded in the browserCall the admin API directly and skip the screenThe role check lives in a React component, not in the Express route
Secret key in the bundleCharge cards, send email or run AI calls on your accountA key put in a VITE_ variable or a frontend file, both shipped to every visitor
AI route without limitsRun prompts on your Replit creditsReplit AI Integrations bills usage to you, and the route has no sign-in or rate limit
Unsigned Stripe webhookSend a fake payment event that grants a paid planA manual Stripe setup whose handler never verifies the Stripe-Signature header
App published as Public by mistakeOpen an internal tool or a beta full of real dataApps in a personal workspace publish as Public by default

How to check your Replit app

Six checks, from free and fast to thorough. The outside ones run against your own published URL only.

  1. 1

    Check who can open the app

    Open Tools > Publishing and look at Sharing. An internal tool or a beta with real data belongs in Password protected, Workspace only or Invite only, available on every plan since May 2026. Changing it means unpublishing, then publishing again.

  2. 2

    Run the free scan, then the deep one

    In Tools > Security Center, run Level 1: it is free and lists vulnerable packages. On a paid plan, run Level 2 for a source review, or Level 3 to add a test of the running Preview. Send accepted findings to Agent, rerun, then republish.

  3. 3

    Search what you ship for keys

    Build the app and search the output for secret key prefixes (command below), then search the project for VITE_ and read every value it exposes. Paste anything suspicious into the API key leak checker: it runs in your browser and says which keys are secret.

  4. 4

    Call your routes signed out

    Use the app signed in with the Network tab open and note the /api/ routes that return personal data. Then call each one with no session. Every route that returns user data should answer 401, and every AI route too.

  5. 5

    Repeat as a second account

    Sign up twice, as Replit's own login tutorial recommends. As account B, open account A's records by their ids: a booking, an invoice, a profile, a file. Anything other than 403 or 404 is an IDOR vulnerability.

  6. 6

    Check headers and leftovers

    Paste your URL into the security headers checker. On your live site, /.env and the .map file next to a JavaScript file should return nothing useful; the exposed .env guide says what to rotate if one does.

bash
npm run build
grep -rlE "sk_live_|rk_live_|sk-proj-|sk-ant-|whsec_|postgres(ql)?://" dist 2>/dev/null
Lists the built files that contain a Stripe, OpenAI, Anthropic or webhook secret, or a database connection string. Replace dist with the folder your frontend builds into. Any match is a key to rotate.
bash
# Your own app only. Signed out: expect 401, never records.
curl -i https://YOUR-APP.replit.app/api/bookings

# An AI route signed out: expect 401, never a model's answer
curl -i -X POST https://YOUR-APP.replit.app/api/chat \
  -H "content-type: application/json" \
  -d '{"message":"hello"}'
Against your own app only. A 200 with records from the first call means anyone on the internet can read them. A model's answer from the second means anyone can spend your credits.

Fixes, with prompts for Agent

Agent writes these fixes well when the prompt names the rule. Paste the prompts, then read the diff before you accept it.

Every route: check the session, then the owner

Both route bugs have one fix. Refuse calls without a session, then put the signed-in user in the query, so a record that belongs to someone else is simply not found. Clerk recommends clerkMiddleware() with getAuth() for API routes; its older requireAuth() helper is deprecated and redirects instead of answering 401.

js
import { clerkMiddleware, getAuth } from "@clerk/express";
import { and, eq } from "drizzle-orm";

app.use(clerkMiddleware()); // reads the session, blocks nothing on its own

function requireUser(req, res, next) {
  if (!getAuth(req).userId) return res.status(401).json({ error: "Sign in required" });
  next();
}

// Before: any signed-in user reads any booking by changing the id
app.get("/api/bookings/:id", requireUser, async (req, res) => {
  const [booking] = await db.select().from(bookings)
    .where(eq(bookings.id, req.params.id));
  res.json(booking);
});

// After: the owner is part of the query
app.get("/api/bookings/:id", requireUser, async (req, res) => {
  const { userId } = getAuth(req);
  const [booking] = await db.select().from(bookings)
    .where(and(eq(bookings.id, req.params.id), eq(bookings.userId, userId)));
  if (!booking) return res.status(404).end();
  res.json(booking);
});
With Replit Auth the pattern is the same: filter on the user id your auth middleware puts on the request.
text
Audit every route in the Express server.
1. List each route with its method, whether it requires sign-in,
   and which table it reads or writes.
2. Every route that returns or changes user data must answer 401
   without a session.
3. Every read, update and delete on a user-owned table must filter on
   the signed-in user's id. Answer 404 when the record belongs to
   someone else.
4. Admin routes must check the role in the server, not only in React.
Show me the list before and after, and a test plan with two accounts.
Prompt for Replit Agent.

Keys: only publishable keys reach the browser

Secret keys live in Secrets and are read in the server with process.env. The frontend only gets keys made to be public, such as Clerk's or Stripe's pk_ keys. A secret key that was ever in the bundle must be rotated at the provider: deleting it from the code does not take it back. The guide to API keys exposed in the frontend has the rotation steps per provider.

text
Find every API key, token or connection string in the frontend code,
in any VITE_ variable and in any file of the project. Move each secret
into Replit Secrets, read it only in the Express server, and add a
server route for the frontend to call instead. Then list the keys you
moved so I can rotate them at each provider.
Prompt for Replit Agent.

AI routes and the Stripe webhook

An AI route needs the same requireUser check plus a limit per user, so one account cannot drain your credits; the express-rate-limit example in Replit's security checklist is a start, and the unprotected AI endpoint guide goes further. A Stripe webhook is the one route that must stay open, so it proves itself with a signature instead of a session:

js
// Register before app.use(express.json()): Stripe signs the raw body
app.post("/api/stripe/webhook", express.raw({ type: "application/json" }), (req, res) => {
  let event;
  try {
    event = stripe.webhooks.constructEvent(
      req.body,
      req.headers["stripe-signature"],
      process.env.STRIPE_WEBHOOK_SECRET,
    );
  } catch {
    return res.status(400).send("Invalid signature");
  }
  // handle event.type here, then answer quickly
  res.json({ received: true });
});

app.use(express.json());
Stripe verifies the exact raw body, so express.json() must not parse it first. More in the Stripe webhook guide.

Security headers

Agent apps need a server, so they publish on Autoscale or a Reserved VM: set the headers in your Express server. app.use(helmet()) (from the helmet package) adds a Content-Security-Policy, HSTS, X-Frame-Options and other protective headers in one line. Test the Preview after adding it: a strict policy can block scripts your app loads from other domains. A hand-built static deployment sets its headers in the .replit file instead.

Replit deployment security: the traps after the first fix

  • A fix is not live until you republish. Agent edits the development copy, and dependency patches wait as pending republish. Then test the public URL: it reads its own values under Publishing > Adjust settings > Production app secrets.
  • Remixes carry your history. Remixing a public app copies its files, configuration and checkpoint history; only secret values stay behind. A key you deleted from a file can still sit in an older checkpoint, so rotate it.
  • Keys pasted into the Agent chat leave Secrets. Replit's own model says not to paste API keys or tokens into the chat: Agent can use a secret without seeing it, and a pasted key becomes an unmanaged copy. The same goes for a key your code prints to the logs. Rotate any key that went either way.
  • Collaborators can read secret values. Multiplayer collaborators see them in the Secrets tool. Organization members without the Owner role cannot, but Replit notes they can print them from the environment. Give edit access only to people you would hand the keys to.
  • The production connection string is a full credential. It works from any PostgreSQL client. If it lands in a chat, a ticket or a screenshot, the app owner or a workspace admin can use Regenerate credentials in the production database's Settings tab: the old string stops working at once. Apps moved off the legacy Neon development database keep the old string as NEON_DATABASE_URL in Secrets: never share it either.
  • SQL you ran by hand stays in development. Publishing copies tables, views and row level security policies, but not functions, triggers or grants. A trigger or grant you added for safety is missing in production until you add it there.

Test the published app after every deploy

Replit's scans read your code and test your Preview. The open question is what a stranger reaches at your public URL, with production data, after each republish. That is what Keybrum attacks, and only on apps whose owner has proved ownership. On a Replit app it calls the API routes your JavaScript uses signed out and as a second account, checks AI routes and the Stripe webhook for missing protection, and looks for secret keys in the bundle, a served .env and missing security headers. Each finding comes with the request that worked, and the fix goes to your coding agent through MCP.

Replit app security checklist

  • Sharing set to the narrowest option that fits; Public only for apps meant for everyone
  • Security Center Level 1 run, plus Level 2 or 3 on a paid plan; findings fixed and republished
  • Block publishing of critical vulnerabilities turned on in Publish > Advanced
  • No secret key in frontend code, in a VITE_ variable, in any project file, in the Agent chat or in the logs
  • Every /api route that touches user data answers 401 signed out
  • Every query on user data filters on the signed-in user's id, tested with two accounts
  • Admin routes check the role in the server
  • AI routes require sign-in and have a per-user limit
  • The Stripe webhook verifies the signature with constructEvent
  • Security headers sent by Express
  • Errors show a generic message to users; details stay in the logs
  • Production recovery window checked, and scheduled backups on for data you cannot lose
  • Production connection string kept inside Replit, regenerated if it ever leaked

The same rules apply on every AI app builder. The vibe coding security checklist covers them across stacks, and vibe coding security risks explains why generated apps keep shipping the same holes.

Questions

Is Replit safe to use?

Yes, as a platform: Replit isolates environments, encrypts secrets and data, filters DDoS and holds a SOC 2 Type II attestation. Whether an app you build there is safe depends on its code and settings. Under Replit's own model, access control and pen testing of your app are your job.

Is Replit safe for production apps?

It can host them: production gets its own database with point-in-time recovery and its own secrets, and Agent cannot change that database. Before real users arrive, check the Sharing setting, run Security Center, test every route signed out and as a second account, and retest after each republish.

What are the main Replit security concerns?

Most come from the app, not the platform: API routes that skip the sign-in or owner check, secret keys shipped to the browser, AI routes anyone can call on your credits, and apps left Public that should be private.

Can people see my code or secrets on Replit?

Visitors of an app's cover page never see secret values, and people who remix your app get the secret names with empty values. Your files and checkpoint history do copy into a remix, so a key written in a file is exposed. Multiplayer collaborators can read secret values, and organization members without the Owner role can print them from the environment.

Does Replit scan my app for vulnerabilities?

Yes. Package Firewall and dependency scans are free, Agent checks the files it changes with Semgrep, and paid plans add a source review (Level 2) and a black-box test of the Preview (Level 3). Replit's docs say a scan is not a complete security review, so test the published app too.

Is a Replit deployment public by default?

In a personal workspace, yes: published apps default to Public, while organization workspaces default to a private option. Since May 2026 every plan can publish as Password protected, Workspace only or Invite only, unless a workspace admin turns an option off. Development URLs are private by default unless you turn off Private preview.

Did Replit Agent delete a production database?

Yes. In July 2025, during SaaStr founder Jason Lemkin's trial, the agent deleted his production database during a code freeze. Replit's CEO called it unacceptable and the company introduced separate development and production databases. Agent now reads production only through a read-only replica and cannot change it.

Sources

  1. 1.Replit shared responsibility model, Replit Docs
  2. 2.Security scan levels, Replit Docs
  3. 3.Project Security Center, Replit Docs
  4. 4.Agent security scans, Replit Docs
  5. 5.Black-box pen tests, Replit Docs
  6. 6.Package Firewall, Replit Docs
  7. 7.Development and production databases, Replit Docs
  8. 8.Connection details, Replit Docs
  9. 9.Data recovery, Replit Docs
  10. 10.Secrets, Replit Docs
  11. 11.Security checklist, Replit Docs
  12. 12.Changelog, January 16, 2026: Node.js security patch, Replit Docs
  13. 13.Who can access your app, Replit Docs
  14. 14.Users & Auth, Replit Docs
  15. 15.Clerk Auth, Replit Docs
  16. 16.Add login, Replit Docs
  17. 17.Remix an app, Replit Docs
  18. 18.Replit AI Integrations, Replit Docs
  19. 19.Changelog, May 8, 2026: private publishing for everyone, Replit Docs
  20. 20.How Replit Secures AI-Generated Code, Replit Blog
  21. 21.Clerk Express SDK reference, Clerk Docs
  22. 22.Env variables and modes, Vite documentation
  23. 23.Webhook signature verification, Stripe Docs
  24. 24.Replit makes vibe-y promise to stop its AI agents making vibe coding disasters, The Register
  25. 25.Thousands of AI 'vibe coding' apps may expose sensitive medical, business data, eWeek

Your app is public. So are its mistakes.

Check what any attacker can already see in it, free, in ten seconds. The full attack, with proof and fixes: €49 once, or €29 a month on a plan.

or continue with Google or GitHub