How to Fix Open Redirect Vulnerabilities in Next.js
OverMCP Team
TL;DR: To fix open redirect vulnerabilities in Next.js, always validate the redirect URL against an allowlist of trusted domains on the server side. Never trust user input directly in redirect() or nextUrl without checking the origin. Use middleware or server-side checks to block malicious redirects that could lead to phishing attacks.
Open redirect vulnerabilities occur when an application uses user-supplied input (like a URL parameter) to construct a redirect destination without proper validation. In Next.js, this often happens in API routes, middleware, or client-side redirect logic. An attacker can craft a link that redirects users to a malicious site, enabling phishing, credential theft, or malware distribution.
What Is an Open Redirect Vulnerability?
An open redirect is a security flaw where an attacker can redirect users from a legitimate domain to a malicious one. For example, if your app at example.com uses a ?redirect= parameter to send users back after login, an attacker could create a link like example.com/login?redirect=https://evil.com. If the app blindly redirects to that URL, users end up on the attacker's site, often without noticing.
How Open Redirects Occur in Next.js
Common scenarios in Next.js apps:
router.push() or redirect() with unsanitized query parametersnextUrl.searchParams in middlewareredirect_uri parameterExample of Vulnerable Code
// pages/api/auth/callback.js (or app/api/auth/callback/route.js)
export async function GET(request) {
const { searchParams } = new URL(request.url);
const redirectTo = searchParams.get('redirect'); // user-controlled
// No validation!
return NextResponse.redirect(redirectTo);
}An attacker can call /api/auth/callback?redirect=https://phishing-site.com and users will be redirected there.
Step-by-Step Fix: Validate Redirect URLs
1. Use an Allowlist of Trusted Domains
Create a configuration file that lists allowed domains and protocols.
// lib/redirect.js
const ALLOWED_DOMAINS = [
'example.com',
'app.example.com',
'www.example.com',
];
const ALLOWED_PROTOCOLS = ['https:'];
export function isSafeRedirect(url) {
try {
const parsed = new URL(url);
return (
ALLOWED_PROTOCOLS.includes(parsed.protocol) &&
ALLOWED_DOMAINS.includes(parsed.hostname)
);
} catch {
return false;
}
}2. Apply Validation in API Routes
// app/api/auth/callback/route.js
import { NextResponse } from 'next/server';
import { isSafeRedirect } from '@/lib/redirect';
export async function GET(request) {
const { searchParams } = new URL(request.url);
const redirectTo = searchParams.get('redirect');
if (redirectTo && !isSafeRedirect(redirectTo)) {
// Log the attempt or redirect to a default safe page
console.warn('Blocked unsafe redirect:', redirectTo);
return NextResponse.redirect(new URL('/dashboard', request.url));
}
const safeUrl = redirectTo || '/dashboard';
return NextResponse.redirect(new URL(safeUrl, request.url));
}3. Protect Middleware Redirects
If you use Next.js middleware to redirect users based on query parameters, apply the same validation.
// middleware.js
import { NextResponse } from 'next/server';
import { isSafeRedirect } from '@/lib/redirect';
export function middleware(request) {
const url = request.nextUrl.clone();
const redirectParam = url.searchParams.get('redirect');
if (redirectParam) {
if (!isSafeRedirect(redirectParam)) {
// Remove the malicious parameter
url.searchParams.delete('redirect');
return NextResponse.redirect(url);
}
}
return NextResponse.next();
}
export const config = {
matcher: '/api/auth/:path*',
};4. Use Relative URLs When Possible
Instead of passing full URLs, use relative paths (e.g., /dashboard). If you must accept a URL, ensure it's a relative path by checking that it starts with / and does not contain ://.
export function isRelative(url) {
return url.startsWith('/') && !url.includes('://');
}5. Encode the Redirect URL
When storing or passing redirect URLs, encode them to prevent injection. But encoding alone is not sufficient — always validate.
Additional Prevention Strategies
next.config.js redirects which are safe.How OverMCP Helps
OverMCP is a security scanning platform designed for vibe-coded apps built with AI tools like Cursor, Bolt.new, and Lovable. It automatically detects open redirect vulnerabilities and other common issues in your Next.js codebase, providing actionable fixes before you deploy.
FAQ
What is an open redirect vulnerability in Next.js?
An open redirect vulnerability occurs when a Next.js application redirects users to a URL provided in a query parameter or form input without validating that the destination is safe. Attackers can exploit this to send users to malicious websites, often for phishing.
How do I test my Next.js app for open redirects?
Try appending ?redirect=https://evil.com to any endpoint that performs redirects (like login or callback pages). If your browser navigates to evil.com, your app is vulnerable. Also check API routes and middleware that use redirect().
Can I fix open redirects without an allowlist?
Yes, you can use relative redirects (only accept paths starting with /) or validate the URL against a regex for your own domain. However, an allowlist is the most robust approach because it explicitly defines trusted destinations and prevents bypasses.