AI-coded apps

    Replit App Exposed Database: How to Secure It

    A Replit workspace moving a database credential from a public .env file into the private Replit Secrets panel.

    A Replit app most often exposes its database in one of two ways: a plain .env file committed to a public repl, where anyone can read every file including that one, or database credentials placed in client-side code that ships to users. On a public Replit repl, files are visible to everyone, so a .env is not private. The fix is to store secrets in Replit Secrets, which are kept separate from your files, and to make the repl private if the code itself is sensitive. Then keep database access on the server, enable Row Level Security if a public key can reach your data, and rotate any credential that was exposed.

    Short answer

    A Replit database gets exposed when secrets live in files a public repl reveals, or when database access happens in client code. Per Replit's Secrets documentation, secrets belong in Replit Secrets, which are stored separately from your files and injected as environment variables, rather than in a .env that a public repl exposes. Keep database credentials and queries on the server, not in the client. If you use a service like Supabase where a public key reaches the database, enable Row Level Security and test it, per Supabase's RLS guidance. Finally, rotate any credential that was exposed, since a leaked one should be treated as compromised.

    How a Replit app exposes its database

    There are two common exposure paths, and they are different problems. The first is secrets sitting in files that a public repl makes readable: a committed .env, a config file, or a hardcoded connection string. Because a public repl shows all of its files to anyone, any secret in those files is effectively published, including a database URL or password.

    The second path is database access from the client. If your app connects to the database directly from browser or client code, the credentials or keys needed for that connection ship to users, who can read them. Both paths end with someone outside your team holding what they need to reach your data, so securing a Replit app means closing both: keep secrets out of visible files, and keep database access on the server.

    Are .env files public on Replit?

    On a public repl, effectively yes. A public Replit repl exposes its entire file tree to anyone who views it, so a .env file committed there is readable, and any secret inside it is exposed. This surprises developers who assume .env is special, but Replit treats it as just another file, and a public repl publishes files.

    The safe alternative is Replit Secrets. Secrets you add through Replit's Secrets feature are stored separately from your files, are not shown in the file tree, and are injected into your app as environment variables at runtime, so they stay private even on a public repl. If your code is itself sensitive, you can also make the repl private, but the more important habit is to never put a real secret in a file and instead always use Secrets.

    Use Replit Secrets instead of a .env file

    Moving your secrets into Replit Secrets is the core fix. Add each secret, such as a database URL, an API key, or a service credential, through the Secrets feature rather than writing it into a .env or source file, and read it in your code through the environment variable it provides. This keeps the value out of every file a repl could reveal while still making it available to your running app.

    Do this for every secret, not just the obvious ones. A database connection string, a third-party API key, and a signing secret all belong in Secrets, and none belong in a committed file. If you previously kept them in a .env, move them to Secrets, remove them from the file, and rotate them, since anything that lived in a public repl should be considered already exposed.

    Keep database access server-side

    The second fix is architectural: keep database credentials and queries on the server, not in the client. Your app's frontend should call your own server code, which holds the credentials and talks to the database, rather than connecting to the database directly from the browser with credentials that ship to the user. This way the secret never leaves the server, no matter who inspects the client.

    Where you use a backend service whose model is a public client key, such as Supabase, the client can talk to the service directly, but only because access is governed by policies rather than by hiding a credential. In that case the equivalent of server-side protection is Row Level Security, which constrains what the public key can do. Either way, the principle is the same: nothing that grants broad database access should ship to the client.

    How to set up RLS

    If your Replit app uses a service like Supabase where a public key reaches the database, Row Level Security is what keeps that access safe. Enable RLS on every table the client can reach, then write policies that grant each role only what it needs, for example letting users read and write only their own rows and giving the anonymous role access only to genuinely public data. Enable RLS first, since a table with it off is fully open to the public key.

    Then verify the policies rather than assuming them. Query your tables as the anonymous role and confirm you cannot read or modify data you should not, because a policy that is too permissive leaves you no safer than none. This testing is the step that turns RLS from a box you ticked into protection you have confirmed, and it is essential before an app with a public key holds real data.

    Containment: rotate exposed credentials

    If a credential was already exposed, whether in a public repl or in client code, rotate it. Treat any database URL, password, API key, or service credential that was reachable as compromised, and issue a new one, because the exposed value may already have been copied. Rotation is the step that actually protects you, since removing the file or making the repl private afterward does not undo exposure that already happened.

    Pair rotation with an assessment of what was reachable. Determine which credentials were exposed and for how long, and what data they could access, so you know whether you also have a disclosure obligation. Then confirm the new credentials live only in Replit Secrets and server code, so the same exposure does not recur.

    Fixes compared

    The exposures map to specific fixes. The table below pairs each one with its remedy.

    ExposureWhat is wrongFix
    .env in a public replEvery file is readable, including secretsUse Replit Secrets, or make the repl private
    DB credentials in client codeThe connection string ships to usersKeep database access on the server
    Missing RLS with a public keyThe public key reaches all dataEnable and test Row Level Security
    Hardcoded key in a fileThe secret is committedMove it to Secrets and rotate it
    Sensitive code in a public replThe source itself is exposedMake the repl private

    Read the table against your app to find which exposures apply. Most Replit database leaks come from the first two rows, secrets in visible files and database access in the client, so those are where to look first.

    Securing checklist

    A short sequence closes the common gaps. The checklist below covers it.

    CheckActionDone?
    Move to SecretsPut every secret in Replit Secrets, not a .env[ ]
    Repl visibilityMake the repl private if the code is sensitive[ ]
    Server-side databaseKeep credentials and queries off the client[ ]
    Enable RLSTurn on Row Level Security and test as the anon role[ ]
    Rotate credentialsRotate anything that was exposed[ ]

    The two that resolve most cases are moving secrets into Replit Secrets and keeping database access server-side, because together they stop both exposure paths. Rotating exposed credentials is the containment step that makes the fix real rather than cosmetic.

    Verify with a scan

    After securing the backend, it is worth verifying that no secret still ships in the app you deploy, since a leftover hardcoded credential or a client-side database key can persist even after you move things to Secrets. Verification is what confirms the fix reached the shipped build.

    A scanner like PTKD.com analyzes your app build and reports findings ordered by severity and mapped to OWASP MASVS, including secrets embedded in the app, so you can confirm no database credential or key leaked into what you deploy. To be clear about the boundary: PTKD does not manage your Replit Secrets or configure RLS. It checks the built app for exposed secrets, which complements moving credentials server-side and locking down database access.

    What to take away

    • A Replit app exposes its database mainly through secrets in files a public repl reveals, or database access in client code.
    • On a public repl every file is readable, so a .env is not private; store secrets in Replit Secrets, which stay private even on a public repl.
    • Keep database credentials and queries on the server, and never ship anything that grants broad database access to the client.
    • If a public key reaches the database, enable and test Row Level Security so the key is constrained by policy.
    • Rotate any exposed credential, and verify with PTKD.com that no secret shipped in your deployed app.
    • #replit
    • #exposed database
    • #replit secrets
    • #row level security
    • #backend security

    Frequently asked questions

    Are .env files public on Replit?
    On a public repl, effectively yes. A public Replit repl exposes its entire file tree to anyone who views it, so a committed .env file is readable and any secret inside it is exposed. Replit treats .env as just another file. The safe alternative is Replit Secrets, which are stored separately, not shown in the file tree, and injected as environment variables, so they stay private even on a public repl.
    How does a Replit app expose its database?
    Two common ways: secrets sitting in files a public repl reveals, such as a committed .env or a hardcoded connection string, and database access happening in client code, where the credentials ship to users. Both end with someone outside your team holding what they need to reach your data, so securing the app means closing both paths.
    How do I use Replit Secrets instead of a .env?
    Add each secret, such as a database URL or API key, through Replit's Secrets feature rather than writing it into a .env or source file, and read it in code through the environment variable it provides. This keeps the value out of every file a repl could reveal. Move any existing .env secrets to Secrets, remove them from the file, and rotate them.
    How do I set up RLS for a Replit app?
    If your app uses a service like Supabase where a public key reaches the database, enable Row Level Security on every client-reachable table, then write least-privilege policies granting each role only what it needs. Enable RLS first, since a table with it off is fully open to the public key, and test the policies by querying as the anonymous role to confirm they hold.
    What do I do if a database credential was exposed?
    Rotate it. Treat any database URL, password, or key that was reachable in a public repl or client code as compromised, and issue a new one, since removing the file afterward does not undo exposure that already happened. Assess what was reachable and for how long, then confirm the new credentials live only in Replit Secrets and server code.
    How do I confirm no secret shipped in my deployed app?
    Verify the build, since a leftover hardcoded credential or a client-side database key can persist even after you move things to Secrets. A scanner like PTKD.com (https://ptkd.com) analyzes your build and reports secrets embedded in the app, mapped to OWASP MASVS. It does not manage Replit Secrets or configure RLS, but it confirms no credential leaked into what you deploy.

    Keep reading

    Scan your app in minutes

    Upload an APK, AAB, or IPA. PTKD returns an OWASP-aligned report with copy-paste fixes.

    Try PTKD free