Mahamudul Hasan Rubel
HomeAboutProjectsSkillsExperienceBlogPhotosContact
Mahamudul Hasan Rubel

Senior Software Engineer crafting high-performance web applications and SaaS platforms.

Navigation

  • Home
  • About
  • Projects
  • Skills
  • Experience
  • Blog
  • Photos
  • Contact

Get in Touch

Available for senior/lead roles and consulting.

bd.mhrubel@gmail.comHire Me

© 2026 Mahamudul Hasan Rubel. All rights reserved.

Built with using Next.js 16 & Tailwind v4

Back to Blog
SecurityJune 22, 20264 min read

Preventing Open Redirect Vulnerabilities: A Guide for Developers

Learn to stop open redirect vulnerabilities by validating destination URLs. Protect your Node.js and PHP apps from phishing attacks with these practical tips.

securitynodejsphpweb-securityinput-validationredirectsWebBackend

During a recent audit of a legacy codebase, I found a login controller that was essentially a one-click ticket for a phishing campaign. The application accepted a ?next= parameter to redirect users after authentication, but it didn't bother checking where that parameter actually pointed. It was a classic open redirect. By simply changing the URL, an attacker could send unsuspecting users to a pixel-perfect clone of our login page hosted on a different domain.

If you’re handling redirects based on user input, you’re holding a loaded gun. It’s easy to fix, but it requires a shift in how you think about untrusted data.

Understanding the Open Redirect Risk

An open redirect happens when your application takes a user-provided URL and redirects the browser to it without validation. Attackers love these because they look legitimate. If a user sees https://your-app.com/login?next=https://malicious-site.com, they might trust the first part of the URL and ignore the second.

We’ve seen this lead to credential harvesting and drive-by downloads. The fix isn't to stop using redirects, but to enforce strict input validation on the destination. Before you touch security, make sure you've also addressed other entry points like preventing mass assignment vulnerabilities with DTOs in Laravel and Express to ensure your data layer stays clean.

The Wrong Turn: Blind Trust

My first instinct years ago was to use a regex to check if the URL started with /. It failed almost immediately. Attackers can bypass simple starts-with checks using double slashes (//malicious.com), which browsers often interpret as a protocol-relative URL.

Never trust a string just because it looks like a relative path. If you aren't careful, you’ll end up with vulnerabilities similar to those I’ve documented when preventing path traversal in Node.js and PHP.

Secure Redirects in Node.js

In Node.js, we should use the built-in URL constructor to parse the input. If the URL is absolute, we compare the hostname against a whitelist of allowed domains. If it’s relative, we ensure it starts with a single /.

JAVASCRIPT
const { URL } = require(CE9178">'url');

function isSafeRedirect(url, allowedHost) {
  try {
    // Check for protocol-relative bypasses
    if (url.startsWith(CE9178">'//')) return false;
    
    // If itCE9178">'s a relative path, it's usually safe
    if (url.startsWith(CE9178">'/')) return true;

    // If it's an absolute URL, validate the host
    const parsed = new URL(url);
    return parsed.hostname === allowedHost;
  } catch (e) {
    return false;
  }
}

This approach forces us to be explicit. If you're building out your auth flow, remember that preventing session fixation is just as critical as redirect security.

Handling Redirects in PHP

PHP’s parse_url function is your best friend here. Don't try to roll your own validation with strpos.

PHP
function is_safe_redirect($url, $allowed_host) {
    $parsed = parse_url($url);

    #6A9955">// Relative paths have no host
    if (!isset($parsed['host'])) {
        return str_starts_with($url, '/');
    }

    #6A9955">// Absolute URLs must match our domain
    return $parsed['host'] === $allowed_host;
}

The logic here is roughly 5 lines of code, yet it prevents a high-severity phishing vector. I’ve seen developers try to strip characters or use blocklists, but that’s a losing game. Always use an allowlist approach.

Best Practices for Application Security

  1. Prefer Relative Paths: Whenever possible, strip the domain entirely and only redirect to paths within your own app.
  2. Use an Allowlist: If you must redirect to external sites, maintain a hardcoded list of allowed hostnames.
  3. Use Indirect References: Instead of passing ?next=https://external.com, pass an ID like ?next=dashboard. Map that ID to a URL on your server side. This is the most robust way to prevent an open redirect.
  4. Validate Early: Perform this check at the controller level before the response headers are sent.

Frequently Asked Questions

Why not just use regex to block "http"?

Regex is fragile. Attackers can use different encodings, whitespace, or protocol-relative URLs (e.g., //example.com) to bypass simple filters. Always use a proper URL parsing library.

Is it safe to redirect to a subdomain?

It depends. If your subdomains are user-generated or hosted by third parties, an attacker might be able to host content there. Only redirect to subdomains you explicitly trust and control.

What if I need to redirect to multiple domains?

Use a configuration file or an environment variable that defines a strict whitelist. Never build a redirect system that allows arbitrary domains passed via a URL parameter.

Final Thoughts

I’m still not a fan of allowing arbitrary redirects. If I were refactoring a large system today, I’d push for a "redirect service" that only supports a predefined map of paths. It removes the dynamic nature of the input entirely. We often focus on complex threats, but sometimes the most effective security is just saying "no" to user input that doesn't strictly follow the rules. Keep your validation logic simple, test your edge cases, and stop passing around raw URLs.

Back to Blog

Similar Posts

SecurityJune 22, 20264 min read

XXE Prevention: Hardening PHP and Node.js XML Parsers

Master XXE prevention by hardening your XML parsers in PHP and Node.js. Learn the specific flags and settings needed to stop unauthorized data access.

Read more
SecurityJune 22, 20264 min read

Preventing Session Fixation: Hardening Authentication Flows in Node.js and Laravel

Learn how to prevent session fixation by properly regenerating session IDs during login. Secure your Node.js and Laravel apps with these battle-tested tips.

Read more
SecurityJune 22, 20264 min read

Preventing Race Conditions in Distributed Transactions for Node.js and Laravel

Master preventing race conditions in distributed systems. Secure your concurrent state updates in Node.js and Laravel with robust locking strategies.

Read more