← All posts
weak authenticationvibe codingsecurityMFAAI coding tools

How to Fix Weak Authentication in Vibe-Coded Apps

O

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:

  • [ ] Password storage: Are passwords hashed with bcrypt, Argon2, or scrypt? Never MD5 or SHA-1.
  • [ ] MFA availability: Does your app offer two-factor authentication? At least for admin accounts.
  • [ ] Session expiry: Do sessions expire after inactivity? Default to 24 hours maximum.
  • [ ] Rate limiting: Are login attempts limited to 5 per minute per IP? Without it, brute force works.
  • [ ] Password policy: Minimum 8 characters, with uppercase, number, and symbol requirements.
  • [ ] Account lockout: After 5 failed attempts, lock the account for 15 minutes.
  • [ ] Secure cookies: Are session cookies marked HttpOnly, Secure, and SameSite=Lax?
  • [ ] Password reset: Does reset use a time-limited token sent via email, not a predictable link?
  • 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.

    Is your app secure?

    Free scan in 30 seconds. No signup needed.

    Scan My App Free