In this lesson, you will learn how to prevent attackers from hijacking your OAuth2 callback flow by strictly validating redirect URIs.
The Open Redirect Vulnerability
When your Node.js application initiates an OAuth2 flow, you provide a redirect_uri to the authorization server. After the user approves access, the server redirects the user back to that URL.
An "Open Redirect" vulnerability occurs if your application dynamically redirects a user based on user-provided input without validation. An attacker could craft a malicious link: https://your-app.com/callback?redirect=https://evil-site.com. If your code blindly uses that redirect parameter to perform a res.redirect(), your server will send the user—and potentially sensitive authorization codes—to an attacker-controlled domain.
Implementing Strict Whitelisting
Never trust the redirect_uri or any "return to" parameter passed in the query string unless it matches a pre-defined whitelist stored in your configuration.
Instead of accepting arbitrary URLs, map your allowed redirect paths to a set of static strings or a secure pattern. Here is how to implement a safe check in your callback handler:
const ALLOWED_REDIRECTS = [
'/dashboard',
'/profile',
'/settings'
];
function handleCallback(req, res) {
const destination = req.query.redirect_uri;
// Validate that the destination is in our whitelist
if (ALLOWED_REDIRECTS.includes(destination)) {
return res.redirect(destination);
}
// Fallback to a safe default if the input is missing or malicious
res.redirect('/dashboard');
}
Why Exact Matching Matters
In professional OAuth2 implementations, you should register specific, exact redirect URIs with your identity provider (e.g., Auth0, Google, or your internal OIDC server). When receiving the callback, your server must ensure the redirect_uri received by the authorization server matches the one you originally sent.
If you allow dynamic redirects for "post-login" landing pages, ensure you only allow relative paths or use a strict whitelist of hostnames. By rejecting any input that doesn't match your known, trusted paths, you effectively neutralize the risk of an attacker using your authentication flow as a phishing delivery mechanism.
Key Takeaway: Never perform a redirect based on unvalidated user input; always use an allowlist of permitted destinations to ensure users are only ever sent to trusted parts of your application.