CWE-601 in APIs
- CWE ID
- CWE-601
- Category
- Input Validation
- Severity
- MEDIUM
- Short Name
- Open Redirect
What is CWE-601: URL Redirection to Untrusted Site ('Open Redirect')
CWE-601 describes a weakness where an application uses untrusted data in a URL or path that causes the application to redirect the user to an untrusted site. The core issue is that the application blindly trusts user-supplied input for redirection without validating whether the destination is safe or within an expected domain.
Attackers exploit this by crafting URLs that redirect victims to malicious sites, phishing pages, or credential harvesting forms. The weakness often appears when applications use query parameters like ?next=, ?redirect=, or ?url= to determine where to send users after authentication, logout, or other actions.
CWE-601 in API Contexts
In API environments, CWE-601 manifests through several common patterns. APIs often include redirection endpoints for OAuth flows, post-authentication redirects, or deep linking functionality. The weakness becomes particularly dangerous when APIs serve as backend services for mobile apps or single-page applications that rely on client-side redirects.
Consider an OAuth callback endpoint: /api/oauth/callback?redirect_url=https://malicious-site.com. If the API accepts any redirect URL without validation, an attacker can register a client ID and craft URLs that redirect users to phishing sites after authentication. Similarly, password reset flows might use /api/reset?token=...&redirect=https://evil.com to send users to malicious pages after the reset process.
API-specific scenarios include:
- Deep linking in mobile APIs where
?url=parameters determine app destinations - Payment processing callbacks that redirect users to merchant sites
- Admin panels where redirect parameters determine post-action destinations
- SSO integrations that redirect users after authentication
The risk escalates when APIs serve multiple clients or when redirect destinations aren't properly scoped to trusted domains.
Detection
Detecting CWE-601 requires both static analysis and dynamic testing. Static analysis involves reviewing code for redirect logic that uses unvalidated user input. Look for patterns like:
res.redirect(req.query.redirect);
res.location(req.body.url).send();
window.location = req.query.next;
header('Location: ' + unsafeUrl);Dynamic testing involves actively probing endpoints with various redirect payloads. Test with:
- External domains you control to verify redirects occur
- Subdomain variations to test partial validation bypasses
- Protocol variations (http://, https://, //) to test scheme validation
- URL encoding tricks to bypass simple string checks
middleBrick automatically scans for CWE-601 by testing redirect parameters across your API endpoints. The scanner submits crafted payloads to parameters commonly used for redirection and verifies if the API blindly follows untrusted destinations. middleBrick's 12 security checks include input validation testing that specifically targets open redirect vulnerabilities, providing you with a security score and prioritized findings that map to CWE-601.
The scanner tests parameters like redirect, next, url, return, callback, and similar patterns across all endpoints, checking if they accept external URLs without proper validation. This black-box approach finds vulnerabilities without requiring source code access or credentials.
Remediation
Fixing CWE-601 requires implementing proper validation and maintaining allowlists of trusted destinations. Here are code-level solutions:
// Allowlist approach - preferred method
const TRUSTED_DOMAINS = ['https://yourdomain.com', 'https://app.yourservice.com'];
function validateRedirectUrl(inputUrl) {
try {
const url = new URL(inputUrl);
if (TRUSTED_DOMAINS.includes(url.origin)) {
return url.toString();
}
} catch (e) {
// Invalid URL format
}
return null; // Reject invalid or untrusted URLs
}
// Express.js example
app.get('/api/redirect', (req, res) => {
const redirectUrl = validateRedirectUrl(req.query.redirect);
if (redirectUrl) {
res.redirect(redirectUrl);
} else {
res.redirect('/default-destination');
}
For relative paths only:
function validateRelativeRedirect(inputPath) {
if (inputPath.startsWith('/') && !inputPath.includes('..')) {
return inputPath;
}
return '/default';
}
// Or using a path join to prevent directory traversal
const path = require('path');
function safeRedirect(relativePath) {
const safePath = path.join('/', relativePath);
return safePath;
}Additional mitigations:
- Use POST-Redirect-GET patterns with server-side stored destinations
- Implement CSRF tokens for state-changing operations
- Log and monitor suspicious redirect attempts
- Consider using path-based routing instead of URL parameters when possible
For OAuth implementations, validate the redirect_uri against registered client URIs stored in your database rather than accepting arbitrary URLs. This prevents attackers from registering malicious redirect destinations.