How to Fix Weak Authentication in Vibe-Coded Apps
OverMCP Team
Quick answer
Weak authentication in vibe-coded apps often includes missing multi-factor authentication (MFA), insecure password storage, and weak session management. To fix it, implement a proven authentication library like NextAuth.js with proper session configuration, enforce strong password policies, and add MFA using TOTP or WebAuthn. Scan your app with a free AI app security scanner to catch missing authentication checks before launch.
Why weak authentication is a hidden risk in vibe-coded apps
When you build an app with AI coding tools like Cursor, Bolt.new, or v0, authentication is often treated as an afterthought. The AI generates a basic login form, you connect a database, and you're done. But AI models tend to produce the simplest possible version—no password strength checks, no MFA, no rate limiting on login attempts. This leaves your app vulnerable to credential stuffing, brute-force attacks, and session hijacking.
I've seen solo founders rush to launch a SaaS MVP only to discover that their "secure" app had no lockout after failed logins, passwords stored in plain text in a Supabase table, and session tokens that never expired. In one case, a hacker used a leaked API key from a secret leak scanner to access the admin panel, which had no MFA. The result: a full account takeover within hours.
OverMCP scans for these exact patterns. Our continuous security monitoring alerts you when authentication weaknesses appear in your codebase. But first, let's go through the manual fixes every vibe-coded app needs.
What to check first
Before rewriting your entire auth system, run through this checklist:
If you find any of these missing, you have weak authentication. Let's fix them.
Step-by-step fix
1. Use a battle-tested auth library
Don't write auth from scratch. AI-generated custom auth is almost always flawed. Use NextAuth.js (Auth.js) for Next.js apps or Passport.js for Express.
Example: Replace your AI-generated auth with NextAuth.js in a Next.js app:
// pages/api/auth/[...nextauth].js
import NextAuth from 'next-auth';
import CredentialsProvider from 'next-auth/providers/credentials';
import bcrypt from 'bcrypt';
import { getUserByEmail } from '../../../lib/db';
export default NextAuth({
providers: [
CredentialsProvider({
name: 'Credentials',
credentials: {
email: { label: 'Email', type: 'email' },
password: { label: 'Password', type: 'password' }
},
async authorize(credentials) {
const user = await getUserByEmail(credentials.email);
if (user && bcrypt.compareSync(credentials.password, user.password)) {
return { id: user.id, email: user.email };
}
return null;
}
})
],
session: {
strategy: 'jwt',
maxAge: 24 * 60 * 60 // 24 hours
},
callbacks: {
async jwt({ token, user }) {
if (user) token.id = user.id;
return token;
},
async session({ session, token }) {
session.user.id = token.id;
return session;
}
}
});2. Add MFA with a TOTP library
Use speakeasy for TOTP generation. Add a setup page in your app:
// pages/api/mfa/setup.js
import speakeasy from 'speakeasy';
import QRCode from 'qrcode';
export default async function handler(req, res) {
if (req.method !== 'POST') return res.status(405).end();
const secret = speakeasy.generateSecret({ name: 'MyApp' });
// Store secret.base32 for the user in your database
const otpauthUrl = secret.otpauth_url;
const qrCode = await QRCode.toDataURL(otpauthUrl);
res.json({ qrCode, secret: secret.base32 });
}Then verify tokens on login:
const verified = speakeasy.totp.verify({
secret: user.mfaSecret,
encoding: 'base32',
token: req.body.token
});3. Enforce password strength on signup
Add validation in your signup API:
function isStrongPassword(password) {
const minLength = 8;
const hasUpper = /[A-Z]/.test(password);
const hasLower = /[a-z]/.test(password);
const hasNumber = /[0-9]/.test(password);
const hasSymbol = /[!@#$%^&*(),.?":{}|<>]/.test(password);
return password.length >= minLength && hasUpper && hasLower && hasNumber && hasSymbol;
}4. Add rate limiting
Use a middleware like express-rate-limit for API routes:
import rateLimit from 'express-rate-limit';
const loginLimiter = rateLimit({
windowMs: 60 * 1000, // 1 minute
max: 5,
message: 'Too many login attempts, please try again later.'
});
app.post('/api/auth/login', loginLimiter, async (req, res) => {
// your login logic
});5. Secure session cookies
If you're using a custom session (not recommended), ensure cookies are set properly:
res.setHeader('Set-Cookie', `session=${sessionToken}; HttpOnly; Secure; SameSite=Lax; Max-Age=${24*60*60}; Path=/`);For NextAuth.js, this is handled automatically in production.
Common mistakes
1. Storing passwords in plain text
AI models often skip hashing because it adds complexity. One user reported that their Bolt.new app stored passwords in a users table as plain text. The fix: always hash with bcrypt.hashSync(password, 10) before saving.
2. No MFA for admin accounts
Vibe-coded apps rarely include MFA setup flows. If your app has an admin panel, add MFA immediately. A leaked admin password (common from an exposed .env file) without MFA is a direct path to data breach.
3. Long-lived sessions with no rotation
AI-generated code often sets session expiry to "never" or a year. This makes session hijacking trivial. Always limit session lifetime and rotate tokens after login.
4. Weak password reset tokens
AI might generate a reset link like /reset-password?token=12345. That's guessable. Use a cryptographically random token (e.g., crypto.randomBytes(32).toString('hex')) with a 1-hour expiry.
5. Missing rate limiting on auth endpoints
Without rate limiting, an attacker can try thousands of passwords per minute. Implement rate limiting on login, signup, and password reset endpoints.
How OverMCP catches weak authentication
OverMCP scans your entire codebase for authentication weaknesses—hardcoded secrets, missing hashing, insecure session config, and more. Connect your Vercel, GitHub, or any app repo and get a detailed report in minutes. For example, our Vercel security scanner checks your deployed environment variables and serverless functions for auth misconfigurations.
The best part: OverMCP runs continuously. When you push new code, we re-scan and alert you if a new vulnerability appears. No more wondering if your vibe-coded app is secure.
FAQ
What is weak authentication in a vibe-coded app?
Weak authentication means missing or inadequate mechanisms to verify user identity—like no MFA, weak password storage, or short session timeouts. AI tools often omit these by default.
How do I know if my app has weak authentication?
Run a free AI app security scanner to check for common issues like plaintext passwords, missing MFA, and insecure session cookies. Also manually review your auth code for the checklist above.
Can I add MFA to an existing vibe-coded app without rewriting everything?
Yes. Use a library like speakeasy to generate TOTP secrets and add a verification step after login. You don't need to change your entire auth flow—just add a check for MFA token on successful password verification.