Quick Answer
Replit's one-click deployment makes it incredibly easy to ship apps to production, but deployed Repls frequently contain hardcoded secrets visible in the code tab, unprotected API endpoints, hardcoded localhost references, and no rate limiting. The gap between "running on Replit" and "safe for real users" is significant.
The Replit Deployment Problem
Replit removed every friction point between writing code and deploying it. An AI-generated app can go from prompt to public URL in minutes. This speed is Replit's greatest feature and its biggest security risk. When deployment is frictionless, security review gets skipped entirely.
CodeRabbit's State of AI vs Human Code Generation Report (December 2025) found security issues up to 2.74x higher in AI co-authored pull requests than in human-only ones. Replit's AI assistant generates code at conversational speed, and the one-click deploy button ships it to a public URL before anyone reviews it.
GitGuardian's State of Secrets Sprawl 2024 found that 12.8 million new secrets were exposed in public GitHub repositories in 2023. On Replit, a key hardcoded in source travels with the code: collaborators you invite can read it, and so can anyone who remixes your app. Replit's Secrets tool only protects the keys you actually put in it.
Secrets in the Code Tab
Replit has a Secrets feature (environment variables), but AI-generated code often places API keys directly in the source code rather than using Replit Secrets. Anyone who can open or remix your app's code can read those keys. Values stored in Secrets stay hidden from visitors to your app's cover page and from people who remix it.
// ❌ BAD - Secrets hardcoded in Replit source (visible in code tab)
const stripe = new Stripe('sk_live_abc123secretkey');
const openai = new OpenAI({ apiKey: 'sk-abc123openaikey' });
const supabaseUrl = 'https://abc.supabase.co';
const supabaseKey = 'eyJhbGciOiJIUzI1NiIs...';
// ✅ GOOD - Use Replit Secrets (Tools > Secrets)
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
const supabaseUrl = process.env.SUPABASE_URL;
const supabaseKey = process.env.SUPABASE_SERVICE_KEY;
Unprotected API Endpoints
Replit AI generates Express or Flask endpoints without any authentication. When you publish with Public access, these endpoints are reachable by anyone at your app's .replit.app address. Attackers can find deployed Repls through search engines and test every endpoint for unprotected access.
// ❌ BAD - Every endpoint is public
app.delete('/api/users/:id', async (req, res) => {
await db.delete(users).where(eq(users.id, req.params.id));
res.json({ deleted: true });
});
app.get('/api/admin/stats', async (req, res) => {
const stats = await db.select().from(analytics);
res.json(stats);
});
// ✅ GOOD - Auth middleware on every sensitive route
const requireAuth = (req, res, next) => {
const token = req.headers.authorization?.split(' ')[1];
if (!token) return res.status(401).json({ error: 'Unauthorized' });
try {
req.user = jwt.verify(token, process.env.JWT_SECRET);
next();
} catch {
return res.status(401).json({ error: 'Invalid token' });
}
};
const requireAdmin = (req, res, next) =>
req.user?.role === 'admin' ? next() : res.status(403).json({ error: 'Forbidden' });
app.delete('/api/users/:id', requireAuth, requireAdmin, async (req, res) => {
await db.delete(users).where(eq(users.id, req.params.id));
res.json({ deleted: true });
});
Hardcoded Localhost in Deployed Code
Replit AI often generates code referencing http://localhost:3000 for API calls. This works during development in Replit but breaks or creates subtle bugs when deployed. Frontend code making fetch calls to localhost will fail in production, because the browser sends those requests to the visitor's own machine instead of your server.
Zero Rate Limiting
Deployed Repls have no rate limiting by default. The OWASP API Security Top 10 (2023) lists unrestricted resource consumption as API4. Without rate limiting, attackers can brute-force authentication, scrape data, or simply run up your API costs by making thousands of requests per second.
| Security Gap | Replit Default | Production Requirement |
|---|---|---|
| API Keys | Hardcoded in source | Replit Secrets / env vars |
| Authentication | None on endpoints | Auth middleware on every route |
| Rate Limiting | None | Per-IP and per-user limits |
| CORS | Often cors(), which allows every origin |
Whitelist specific domains |
| Code Visibility | Readable by everyone you share the app with | Limit access; keep keys in Secrets |
How to Secure Your Deployed Repl
- Move all secrets to Replit Secrets. Search your code for
sk_,key,token, andpasswordstring literals. - Check who has access to your app (the Invite button in the Project Editor) and remove anyone who does not need it.
- Add authentication middleware to every API endpoint that reads or writes data.
- Replace localhost URLs with relative paths or environment-based URLs.
- Add rate limiting with
express-rate-limitor equivalent. - Run automated scanning. Tools like VibeDoctor's Vibe Check automatically scan your codebase for exposed secrets, missing auth, and configuration issues. Free to sign up.
Related reading: the best vibe coding tools in 2026.
FAQ
Are Replit Secrets actually secure?
They are the right place for keys. Replit encrypts Secrets (AES-256 at rest, TLS in transit) and gives them to your app as environment variables. Visitors to your app's cover page cannot see them, and people who remix your app see only the names, not the values. Collaborators you invite can see the values, so treat collaborator access as access to your keys. Use Secrets for API keys, database passwords, and tokens in Replit projects.
Can people see my Replit source code?
Anyone you give access to can, and anyone who remixes your app gets a copy of its code. Replit's current docs say apps are not listed publicly on Replit and that access is managed from the Invite button in the Project Editor. Review that list before you publish, and keep every key in Secrets so a shared copy of the code holds no credentials.
Should I use Replit for production apps?
Replit Deployments are intended for production use, and the infrastructure is reliable. The security issues are in the generated code, not in Replit's hosting platform. You can run a secure production app on Replit - you just need to add the security layers that AI generation skips.
How do I add rate limiting to a Replit Express app?
Install express-rate-limit and add it as middleware: app.use(rateLimit({ windowMs: 15 * 60 * 1000, max: 100 })). This limits each IP to 100 requests per 15 minutes. For auth endpoints, use stricter limits (10-20 per 15 minutes).
Does Replit Agent have the same security issues?
Yes. Replit Agent generates code with the same vulnerability patterns as Replit's standard AI and other AI coding tools. The agent creates functional code quickly but does not reliably add security middleware or rate limiting unless specifically prompted.