Open Redirect Vulnerability in Express Applications

Medium Risk Web Security
javascriptexpressopen-redirectphishingurl-validation

What it is

Open redirect vulnerabilities occur when Express applications redirect users to URLs from untrusted sources without validation. Attackers can craft malicious URLs that redirect users to phishing sites or malicious domains, bypassing the trust users have in the legitimate domain. This is commonly exploited in phishing attacks where users trust the initial legitimate domain but are redirected to attacker-controlled sites.

const express = require('express');
const app = express();

// VULNERABLE: redirects to user-controlled URL
app.get('/redirect', (req, res) => {
    const targetUrl = req.query.url;
    
    // DANGEROUS: no validation
    res.redirect(targetUrl);
});

// Attack: /redirect?url=http://evil.com/phishing

app.get('/login', (req, res) => {
    const returnUrl = req.query.return;
    
    if (authenticateUser(req)) {
        // VULNERABLE: redirects after login
        res.redirect(returnUrl || '/');
    }
});
const express = require('express');
const app = express();

// Allowlist of safe redirect URLs
const ALLOWED_REDIRECTS = [
    '/dashboard',
    '/profile',
    '/settings'
];

// SECURE: validates redirect URL
app.get('/redirect', (req, res) => {
    const targetUrl = req.query.url;
    
    // Validate URL is relative and safe
    if (isValidRedirectUrl(targetUrl)) {
        res.redirect(targetUrl);
    } else {
        res.redirect('/');
    }
});

app.get('/login', (req, res) => {
    const returnUrl = req.query.return;
    
    if (authenticateUser(req)) {
        // Safe: validate before redirect
        const safeUrl = isValidRedirectUrl(returnUrl) 
            ? returnUrl : '/';
        res.redirect(safeUrl);
    }
});

function isValidRedirectUrl(url) {
    if (!url) return false;
    
    // Must be relative path
    if (!url.startsWith('/')) return false;
    
    // No protocol (prevents //evil.com)
    if (url.startsWith('//')) return false;
    
    // Check against allowlist
    return ALLOWED_REDIRECTS.includes(url);
}

💡 Why This Fix Works

The vulnerable code redirects to user-controlled URLs without validation, enabling phishing attacks. The secure version validates that URLs are relative paths, don't contain protocols, and match an allowlist of safe destinations.

Why it happens

Using query parameters or request data directly in res.redirect() without validation.

Root causes

Redirecting to User-Controlled URLs

Using query parameters or request data directly in res.redirect() without validation.

Missing URL Validation

Not validating that redirect URLs are relative or belong to allowed domains.

Trusting Referer Headers

Using HTTP Referer headers for redirect destinations without validation.

Fixes

1

Use Allowlist for Redirect URLs

Maintain an allowlist of valid redirect URLs or domains.

2

Validate URLs are Relative

Ensure redirect URLs start with '/' and don't contain protocols.

3

Use Indirect References

Map user input to safe redirect destinations via lookup table.

Detect This Vulnerability in Your Code

Sourcery automatically identifies open redirect vulnerability in express applications and many other security issues in your codebase.