← All posts
nextjscookiessecurityvibe-codingfix

Insecure Cookies Fix Next.js: Vibe-Coded App Guide

O

OverMCP Team

Quick answer

To fix insecure cookies in a Next.js app built with vibe coding, you need to set the Secure, HttpOnly, and SameSite attributes on every cookie your app sets. In production, always use Secure and SameSite=Lax or Strict, and ensure HttpOnly is enabled for session cookies to prevent JavaScript access. For a step-by-step fix, read on.

What to check first

Before diving into code changes, run a quick audit of your cookie usage. Here's a checklist to identify insecure cookies:

  • List all cookies: Open your browser's DevTools (Application tab > Cookies) and note every cookie your app sets. Look for cookies without Secure, HttpOnly, or SameSite.
  • Check your Next.js config: Look for any cookies() calls in Server Components, Route Handlers, or middleware. These are common places where cookies are set without proper attributes.
  • Review third-party libraries: If you're using an authentication library like NextAuth.js, check its configuration for cookie settings.
  • Test in production: Insecure cookies often appear only in production because Secure is ignored on http://localhost. Deploy to a staging environment or use a tool like OverMCP's security headers checker to see your live cookie attributes.
  • Step-by-step fix

    Here's a practical workflow to fix insecure cookies in your Next.js app.

    1. Set cookie attributes in Route Handlers

    When setting cookies in Route Handlers (API routes), always specify httpOnly, secure, and sameSite options. For example, if you have a login endpoint:

    // app/api/login/route.ts
    import { NextResponse } from 'next/server';
    
    export async function POST(request: Request) {
      const { token } = await request.json();
      
      const response = NextResponse.json({ success: true });
      
      response.cookies.set('session', token, {
        httpOnly: true,
        secure: process.env.NODE_ENV === 'production', // Use Secure in production
        sameSite: 'lax', // or 'strict' for higher security
        path: '/',
        maxAge: 60 * 60 * 24 * 7, // 7 days
      });
      
      return response;
    }

    Important: The secure attribute should be true in production. If you're behind a proxy (like Vercel), you may need to set secure: true unconditionally if your app is always served over HTTPS.

    2. Use `cookies()` in Server Components correctly

    In Server Components, you can set cookies when creating them with cookies().set(). Here's an example:

    // app/actions.ts (Server Action)
    'use server';
    import { cookies } from 'next/headers';
    
    export async function setPreference(pref: string) {
      cookies().set('pref', pref, {
        httpOnly: true,
        secure: process.env.NODE_ENV === 'production',
        sameSite: 'lax',
      });
    }

    3. Update NextAuth.js configuration

    If you're using NextAuth.js, configure cookies in the cookies option:

    // pages/api/auth/[...nextauth].ts or app/api/auth/[...nextauth]/route.ts
    import NextAuth from 'next-auth';
    
    export default NextAuth({
      // ...
      cookies: {
        sessionToken: {
          name: 'next-auth.session-token',
          options: {
            httpOnly: true,
            sameSite: 'lax',
            path: '/',
            secure: process.env.NODE_ENV === 'production',
          },
        },
      },
    });

    4. Check middleware for cookie manipulation

    If you have middleware that reads or modifies cookies, ensure it respects the same attributes. Here's a safe way to read a cookie without changing it:

    // middleware.ts
    import { NextResponse } from 'next/server';
    import type { NextRequest } from 'next/server';
    
    export function middleware(request: NextRequest) {
      // Just read the cookie; don't set it here unless necessary
      const session = request.cookies.get('session');
      // ...
      return NextResponse.next();
    }

    5. Verify with a security scanner

    After making changes, deploy to production and run a scan using OverMCP's free AI app security scanner to confirm your cookies are secure. The scanner will flag any cookies missing proper attributes.

    Common mistakes

    Vibe-coded apps often make these cookie security mistakes:

  • Forgetting `Secure` in production: Many developers set cookies without secure: true, thinking it's fine because they test on localhost. This is a critical flaw.
  • Using `sameSite: 'none'` unnecessarily: To use SameSite=None, you must also set Secure, but this reduces CSRF protection. Avoid it unless you need cross-site cookies (e.g., for embedded widgets).
  • Not setting `HttpOnly` on session tokens: If your session token is accessible via document.cookie, an XSS attack can steal it. Always set httpOnly: true for authentication cookies.
  • Ignoring third-party cookies: Sometimes AI-generated code uses third-party libraries that set insecure cookies. Audit all cookies, not just your own.
  • Setting cookies without `path`: If you don't specify path, the cookie defaults to the current path, which can lead to unexpected behavior and potential security issues.
  • FAQ

    Why is `Secure` cookie attribute important?

    Secure ensures the browser only sends the cookie over HTTPS, preventing interception by man-in-the-middle attacks. In production, your app should always use HTTPS, and without Secure, cookies can be sent over plain HTTP, leaking session tokens.

    Can I fix insecure cookies without changing code?

    You can mitigate some issues by configuring your hosting platform to set security headers, but cookie attributes must be set in the application code. For example, you can't force Secure from your server configuration if your app sets cookies without it. Use a security headers checker to see what's missing.

    How do I test cookie security locally?

    To test Secure cookies locally, use a tool like ngrok to expose your local server over HTTPS, or set NODE_ENV=production and use a self-signed certificate (though browsers will warn). Alternatively, use a staging deployment to test.

    Conclusion

    Fixing insecure cookies is a critical step in securing your vibe-coded Next.js app. By following the steps above, you can ensure your user sessions are protected. For continuous protection, consider setting up continuous security monitoring with OverMCP to catch issues early.

    Is your app secure?

    Free scan in 30 seconds. No signup needed.

    Scan My App Free