← All posts
open redirectNext.js securityvibe codingAI app securityweb vulnerabilities

How to Prevent Open Redirect in Vibe-Coded Next.js Apps

O

OverMCP Team

Quick answer

Open redirect vulnerabilities let attackers redirect users from your legitimate site to malicious ones. In vibe-coded Next.js apps, they often appear when developers use the next/router push or Link component with user-supplied URLs without validation. Fix them by never trusting raw query parameters for redirects—use a whitelist of allowed destinations or strict URL parsing.

What to check first

Before diving into fixes, check these common spots in your vibe-coded Next.js app:

  • [ ] Search for `window.location` assignments – especially in client components or API routes.
  • [ ] Inspect `router.push` and `router.replace` calls – see if they use query.redirect or similar params.
  • [ ] Review all `<Link>` components – check for href attributes that include dynamic values from the URL.
  • [ ] Look at API routes – find any 3xx redirect responses that take a URL from the request.
  • [ ] Check OAuth callback handlers – these often redirect after login and are prime targets.
  • Step-by-step fix

    1. Never trust raw query parameters

    When you need to redirect after an action (like login), avoid using the redirect URL directly:

    // ❌ Vulnerable
    const { redirect } = router.query;
    router.push(redirect || '/dashboard');

    Instead, validate the URL strictly:

    // ✅ Safe
    const { redirect } = router.query;
    const allowedDomains = ['https://yourapp.com', 'https://app.yourapp.com'];
    try {
      const url = new URL(redirect);
      if (allowedDomains.includes(url.origin)) {
        router.push(redirect);
      } else {
        router.push('/dashboard');
      }
    } catch {
      router.push('/dashboard');
    }

    2. Use a redirect whitelist (best practice)

    Create a centralized map of allowed redirects:

    // lib/redirects.js
    const ALLOWED_REDIRECTS = {
      'dashboard': '/dashboard',
      'settings': '/settings',
      'profile': '/profile',
    };
    
    export function safeRedirect(key) {
      return ALLOWED_REDIRECTS[key] || '/dashboard';
    }

    Then use it in your component:

    const { redirect } = router.query;
    router.push(safeRedirect(redirect));

    3. Validate redirects in API routes

    For API routes that issue redirects:

    // ❌ Vulnerable
    res.redirect(303, req.query.redirect);
    
    // ✅ Safe
    const allowed = ['https://yourapp.com/dashboard', 'https://yourapp.com/settings'];
    if (allowed.includes(req.query.redirect)) {
      res.redirect(303, req.query.redirect);
    } else {
      res.redirect(303, '/dashboard');
    }

    4. Use a dedicated security scanner

    Manually checking every redirect is error-prone. Use a free AI app security scanner to automatically detect open redirects in your vibe-coded app. OverMCP scans both client and server-side code for this vulnerability, saving you hours of manual review.

    Common mistakes

  • Using `next/router` with raw query params – AI tools like Cursor often generate router.push(redirectUrl) without validation. Always sanitize.
  • Trusting OAuth providers – Even if your OAuth provider returns a redirect_uri, validate it yourself. An attacker can manipulate the initial request.
  • Whitelisting by domain only – An attacker could use https://yourapp.com.evil.com to bypass a simple domain check. Use exact URL matching or parse the URL properly.
  • Forgetting about `Link` component – Dynamic href in <Link> can also be exploited. Use the same validation logic.
  • Not testing edge cases – URLs with encoded characters, trailing slashes, or fragments can bypass weak checks.
  • FAQ

    What is an open redirect vulnerability?

    An open redirect is when your app redirects users to a URL supplied by an attacker, often via a ?redirect= parameter. This can be used in phishing attacks to trick users into visiting malicious sites that look like yours.

    How do vibe-coded apps get open redirects?

    AI coding tools often generate convenience patterns like router.push(redirect) without security validation. Since the developer didn't write the code line by line, these flaws are easy to miss.

    Can I fix open redirects without breaking my app?

    Yes. Use a whitelist approach: define all allowed redirect destinations in a config file. If your app needs dynamic redirects, validate the URL's origin against your own domain using the URL constructor and a strict list of allowed hosts.

    Is your app secure?

    Free scan in 30 seconds. No signup needed.

    Scan My App Free