← All posts
unvalidated redirectsopen redirectvibe codingAI securityNext.js security

How to Prevent Unvalidated Redirects in Vibe-Coded Apps

O

OverMCP Team

Quick answer

Unvalidated redirects and forwards occur when your app accepts a URL from user input (like a query parameter) and redirects the browser to it without checking where it goes. In vibe-coded apps, AI tools often generate redirect logic that trusts user input, letting attackers send users to phishing sites. To prevent this, always validate redirect destinations against an allowlist of known, safe URLs — never redirect to arbitrary input.

How to Prevent Unvalidated Redirects in Vibe-Coded Apps

If you're building fast with AI coding tools like Cursor, Bolt.new, or Lovable, you've probably added a redirect feature: after login, after form submission, or when handling legacy URLs. These redirects are convenient, but they're also a classic security hole — and AI-generated code is especially prone to missing validation.

An unvalidated redirect vulnerability lets an attacker craft a link like https://yourapp.com/login?redirect=https://evil.com. If your code blindly redirects to that URL, the user ends up on a phishing site that looks like yours. This is a common entry on the OWASP Top 10, and vibe-coded apps are prime targets because AI models often optimize for functionality, not security.

What to check first

Before you dive into code, run through this quick checklist:

  • [ ] Does your app use res.redirect(), NextResponse.redirect(), or window.location with user-controlled input?
  • [ ] Are there any query parameters named redirect, next, url, return, to, or destination?
  • [ ] Do you have a list of allowed redirect domains or paths?
  • [ ] Have you scanned your app for secret leaks or exposed URLs? Use a free AI app security scanner to catch these automatically.
  • [ ] Is your redirect logic in an API route, middleware, or client-side code?
  • If you answered yes to the first two, you likely have an unvalidated redirect vulnerability.

    Step-by-step fix

    Here's how to fix unvalidated redirects in a typical Next.js app built with vibe coding.

    Step 1: Identify the vulnerable code.

    AI tools often generate something like this:

    // app/api/auth/callback/route.ts (vulnerable)
    import { NextRequest, NextResponse } from 'next/server';
    
    export async function GET(request: NextRequest) {
      const redirectUrl = request.nextUrl.searchParams.get('redirect');
      // AI-generated: no validation!
      return NextResponse.redirect(new URL(redirectUrl || '/dashboard'));
    }

    This is dangerous because redirectUrl comes directly from the user.

    Step 2: Implement an allowlist.

    Create a list of allowed destinations. For internal paths, you can use a set of safe paths:

    const ALLOWED_REDIRECTS = new Set([
      '/dashboard',
      '/settings',
      '/profile',
      '/onboarding',
    ]);
    
    function isSafeRedirect(url: string): boolean {
      try {
        const parsed = new URL(url, 'https://yourapp.com');
        // Only allow same-origin or specific external domains
        if (parsed.origin === 'https://yourapp.com') {
          return ALLOWED_REDIRECTS.has(parsed.pathname);
        }
        // For external, use a separate allowlist
        const EXTERNAL_ALLOWLIST = ['https://trusted-partner.com'];
        return EXTERNAL_ALLOWLIST.includes(parsed.origin + parsed.pathname);
      } catch {
        return false;
      }
    }

    Step 3: Use the validation in your route.

    export async function GET(request: NextRequest) {
      const redirectParam = request.nextUrl.searchParams.get('redirect');
      const safeRedirect = redirectParam && isSafeRedirect(redirectParam)
        ? redirectParam
        : '/dashboard';
      return NextResponse.redirect(new URL(safeRedirect, request.url));
    }

    Step 4: For client-side redirects (e.g., after form submit), never use `window.location` with user input.

    Instead, use a similar validation function on the client or always redirect to a server endpoint that validates.

    Step 5: Test with malicious payloads.

    Try:

  • https://yourapp.com/login?redirect=https://evil.com
  • https://yourapp.com/login?redirect=//evil.com
  • https://yourapp.com/login?redirect=%68%74%74%70%3A%2F%2Fevil.com (URL-encoded)
  • https://yourapp.com/login?redirect=/../evil.com
  • Your app should reject all of these.

    Common mistakes

    AI-generated redirect code often makes these errors:

  • Trusting the host header. Some AI models use request.headers.get('host') to build the redirect URL. Attackers can spoof the Host header, leading to open redirect.
  • Only checking the start of the URL. Checking if the URL starts with / is not enough — an attacker can use //evil.com which is interpreted as a protocol-relative URL.
  • Not decoding URL-encoded characters. Attackers can encode http://evil.com as %68%74%74%70%3A%2F%2Fevil.com to bypass simple string checks.
  • Using regex incorrectly. A regex like /^https:\/\/yourapp\.com/ can be bypassed with https://yourapp.com.evil.com.
  • No allowlist at all. The most common mistake: AI simply doesn't add validation because the prompt didn't ask for it.
  • Why vibe-coded apps are especially vulnerable

    AI coding tools are trained on vast amounts of public code, which includes many insecure examples. When you prompt "add a redirect after login," the AI often generates the simplest working code — which is almost always insecure. The AI doesn't know your security requirements unless you explicitly ask. And since many indie developers ship fast without a security review, these vulnerabilities make it to production.

    To catch these issues before they reach users, consider continuous security monitoring that scans your code and deployed app for open redirects and other common flaws. You can also use a security headers checker to ensure your app sets the Referrer-Policy header, which can reduce the impact of some redirect attacks.

    How to test automatically

    You can add a simple automated test:

    // test/redirect.test.ts
    import { isSafeRedirect } from '@/lib/redirect';
    
    describe('isSafeRedirect', () => {
      it('should allow valid internal paths', () => {
        expect(isSafeRedirect('/dashboard')).toBe(true);
      });
    
      it('should reject external URLs', () => {
        expect(isSafeRedirect('https://evil.com')).toBe(false);
      });
    
      it('should reject protocol-relative URLs', () => {
        expect(isSafeRedirect('//evil.com')).toBe(false);
      });
    
      it('should reject encoded attacks', () => {
        expect(isSafeRedirect('%2Fevil.com')).toBe(false);
      });
    
      it('should reject URLs with different host', () => {
        expect(isSafeRedirect('https://yourapp.com.evil.com/dashboard')).toBe(false);
      });
    });

    Run this test in your CI pipeline. Vibe-coded apps often skip testing, but adding a few key security tests saves headaches later.

    Final thoughts

    Unvalidated redirects are easy to introduce and easy to fix — if you know to look. When you're vibe-coding, add a note in your prompt: "Include validation for all redirect parameters using an allowlist." And after deployment, run a quick scan with OverMCP to catch any you missed. It's a small step that protects your users from phishing and your app's reputation.

    FAQ

    What is an unvalidated redirect vulnerability?

    An unvalidated redirect vulnerability occurs when an application accepts a user-controlled URL and redirects the browser to that URL without verifying its destination. Attackers can exploit this to send users to malicious sites, often for phishing or malware distribution.

    How do AI coding tools create this vulnerability?

    AI models generate code that works functionally but often omits security checks unless explicitly prompted. For redirects, the AI typically trusts the input parameter and redirects directly, because that's the simplest implementation seen in training data.

    Can a security scanner detect unvalidated redirects?

    Yes. OverMCP's secret leak scanner can find exposed URLs and parameters, and combined with runtime analysis, it can detect insecure redirect patterns. Automated scanning is the fastest way to find these issues in vibe-coded apps.

    Is your app secure?

    Free scan in 30 seconds. No signup needed.

    Scan My App Free