Insecure Cookies Fix Next.js: Vibe-Coded App Guide
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:
Secure, HttpOnly, or SameSite.cookies() calls in Server Components, Route Handlers, or middleware. These are common places where cookies are set without proper attributes.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:
secure: true, thinking it's fine because they test on localhost. This is a critical flaw.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).document.cookie, an XSS attack can steal it. Always set httpOnly: true for authentication cookies.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.