pwnmyvibecode_

Is your Replit app safe?

Replit is a safe place to write and host code. The risks sit in your app: API keys typed into source files instead of the Secrets pane, source code that other people can view, and an Express server shipped without secure cookies or security headers.

Updated

Check your live site now

Free, no signup, read only. A grade and plain fixes in seconds.

What Replit takes care of, and what it leaves to you

Replit runs your code in its own container, gives your deployment an HTTPS address, and provides a Secrets pane that stores values as environment variables. Replit Agent can build a full app for you, often a Node or Python server with a React front end and a Postgres database.

What Replit does not decide for you: whether a key ends up in a file, who can see your source, whether your login cookie has the right flags, and whether your server sends security headers. The agent writes that code, and it does what the prompt asks, which is not always what is safe.

Replit security mistakes to look for

  • Keys pasted straight into code, like const openai = new OpenAI({ apiKey: 'sk-...' }). If anyone can view the Repl's source, they can read the key.
  • A key read correctly from process.env on the server, then sent to the browser in an API response or baked into the front end build.
  • Front end env variables with a public prefix (VITE_ in a Vite app) holding secret values, which puts them in the JavaScript bundle.
  • A .env file in a folder the server serves as static files, so yoursite/.env downloads.
  • Session cookies without the Secure flag. express-session sets HttpOnly by default but not Secure.
  • No security headers at all, because a plain Express server sends none by default.
  • CORS set to reflect any origin with credentials, added to silence a browser error during development.

Use the Secrets pane, not your source files

Put every key in the Secrets pane and read it as an environment variable. Values stored there are not part of your source files, so they do not show up when someone views your code. Your code then looks like this:

server.js
// server side only
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

If a key was ever written into a file, rotate it with the provider after you move it. Removing it from the file does not help anyone who already copied it, and it may still be in your version history.

Check who can see your Repl's source. If it is public, treat every file in it as public. Also check that your deployment has the secrets it needs, since the deployed app reads its environment at runtime.

Fixing cookies and headers in a Replit Express app

Replit deployments sit behind a proxy that terminates HTTPS. Express needs trust proxy set so it knows the request was secure, otherwise express-session will not send a cookie marked Secure.

server.js
app.set("trust proxy", 1);
app.disable("x-powered-by");
app.use(session({
  secret: process.env.SESSION_SECRET,
  resave: false,
  saveUninitialized: false,
  cookie: { secure: true, httpOnly: true, sameSite: "lax" },
}));

For security headers, the helmet package sets a sensible group with one line. Or add them yourself:

server.js
app.use((req, res, next) => {
  res.setHeader("Strict-Transport-Security", "max-age=31536000; includeSubDomains");
  res.setHeader("Content-Security-Policy", "default-src 'self' https: data: blob: 'unsafe-inline' 'unsafe-eval'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'; form-action 'self'; upgrade-insecure-requests");
  res.setHeader("X-Frame-Options", "SAMEORIGIN");
  res.setHeader("X-Content-Type-Options", "nosniff");
  res.setHeader("Referrer-Policy", "strict-origin-when-cross-origin");
  res.setHeader("Permissions-Policy", "camera=(), microphone=(), geolocation=()");
  next();
});
prompt for your agent
Audit this Replit app for security. Move every API key out of the source into environment variables read with process.env, and list the names I need to add in the Secrets pane. Make sure no secret is sent to the browser or put in a VITE_ variable. Set trust proxy, make the session cookie Secure and HttpOnly, add security headers with helmet, and remove any CORS rule that reflects the request origin with credentials.

Replit security checklist before you deploy

  1. Search the project for sk-, sk_live_, AKIA, ghp_ and BEGIN PRIVATE KEY. Move each hit to the Secrets pane and rotate it.
  2. Confirm no VITE_ or other public-prefixed variable holds a secret.
  3. Make sure the server does not serve the project root as static files.
  4. Set trust proxy and Secure plus HttpOnly on the session cookie.
  5. Add security headers, with helmet or by hand.
  6. Check the Repl's visibility, and the version history if a key was ever committed.
  7. Test the deployed URL, not the development preview.

How to verify the deployed Replit app

Open yourapp/.env in a private window. You should get a 404 or your normal page, never a file. Then open DevTools, go to Application, Cookies, and check that your session cookie shows Secure and HttpOnly.

An outside scan does these checks in one pass: secret keys in your HTML and JavaScript bundles, public .env and .git files, security headers, http to https redirect, cookie flags and CORS. It does not log in, so it cannot test whether one user can read another user's data through your API, and it cannot see your Repl's source. Those need a manual review.

Questions

Is Replit safe to use?

Yes. The platform isolates your code and hosts it over HTTPS. The things to watch are in your project: keys in source files, public source, and server settings the agent left at their defaults.

Can other people see my Replit secrets?

Values in the Secrets pane are not part of your source code. A key typed directly into a file is a different story: anyone who can view the source can read it.

Why is my session cookie not marked Secure on Replit?

Usually because Express does not know the request came over HTTPS. Set app.set('trust proxy', 1) and cookie.secure to true in your session config.

Should I test the replit.dev preview or the deployed URL?

The deployed URL. That is what your users hit, and its settings and secrets can differ from the development preview.