DEV Community

Cover image for Open Redirect: When a Real google.com Link Turns Malicious
Ícaro Molinari
Ícaro Molinari

Posted on

Open Redirect: When a Real google.com Link Turns Malicious

In December 2025, Check Point's researchers flagged something odd: thousands of phishing emails landing in inboxes with a real, valid google.com link inside them.

Not a lookalike domain. Not a typo-squat. The actual google.com.

Nearly 3,200 companies got hit. Over 9,300 emails, all disguised as Google voicemail or file-share notifications, all carrying a link that genuinely pointed at Google's own servers. Clicking it sent victims through a CAPTCHA (for "legitimacy") and then on to a fake Microsoft login page built to steal credentials. (SC Media)

Nobody hacked Google. Nobody forged the domain. The attackers just found a corner of Google's own infrastructure that would forward a visitor anywhere they asked, and used it as a launchpad.

That corner has a name: Open Redirect. And it's a lot more common, and a lot older, than a single 2025 headline suggests.

This Bug Has Been Everywhere

Microsoft's own security team wrote about this exact pattern back in 2021, after tracking a single campaign that used over 350 unique phishing domains, all funneled through open redirect links on trusted platforms. Their reasoning for why it works so well: people are trained to check the domain in a link, and an open redirect lets the visible domain be completely legitimate. (Microsoft Security Blog)

It's not just email providers, either. Cofense's threat intel team tracked phishing campaigns abusing .gov websites across dozens of countries, and found that almost 60% of the abused government domains shared the exact same vulnerable code path, traced back to a single Liferay CMS bug, CVE-2024-25608. (Cofense)

One bug class. One shared root cause. Reused across governments, cloud platforms, and email systems, for years.

So let's actually look at what it is, and why it keeps showing up.

The Bug, In Its Simplest Form

Open Redirect happens when your app takes a destination from the user and sends them there without checking it first.

https://example.com/login?redirect=/dashboard
Enter fullscreen mode Exit fullscreen mode

Somewhere on the backend:

destination = request.query["redirect"]
return redirect(destination)
Enter fullscreen mode Exit fullscreen mode

Change the parameter, and the server obeys just as happily:

https://example.com/login?redirect=https://attacker.example
Enter fullscreen mode Exit fullscreen mode
HTTP/1.1 302 Found
Location: https://attacker.example
Enter fullscreen mode Exit fullscreen mode

This isn't a hypothetical. In 2024, a bug bounty researcher found this exact pattern on Tumblr's own logout endpoint, where a redirect_to parameter sent users wherever the URL said, no validation attached. (writeup)

It also showed up in Expedia's login and logout flow, reported through HackerOne in 2023. (report)

It even shipped inside Ruby on Rails itself. CVE-2023-22797 was an open redirect baked into Action Pack's redirect_to helper, meaning any Rails app using it by default inherited the bug. (HackerOne)

If a framework used by hundreds of thousands of production apps can ship this by accident, "we'd never make that mistake" isn't a real defense.

The Method Doesn't Matter

A quick myth to clear up: this isn't a GET-only problem.

The destination can arrive in a POST body, a PUT payload, a JSON field, anywhere the server reads user-supplied data from. The only question that matters:

Does anything the user controls decide where the redirect goes?

If yes, and nothing validates it, you have the bug. The HTTP verb is just the delivery truck.

"Wait, Isn't This Just MITM?"

No, and this mix-up trips people up a lot.

  • Open Redirect: the server itself honestly generates a malicious Location header, because it trusted a parameter it shouldn't have. HTTPS does nothing to stop this, the channel was never the problem.
  • MITM (man-in-the-middle): someone sits between the browser and server, altering traffic in transit. This requires actual network positioning, not just a crafted URL.

If you've ever tested this in Burp Suite by editing a redirect parameter, you weren't simulating MITM. You already controlled the browser and configured the proxy yourself. That's a lab setup, not an attacker's vantage point.

The Version That Never Touches Your Server

Here's where it gets genuinely sneaky.

Everything so far assumed the server decides the redirect. But plenty of redirect logic lives entirely in JavaScript, in the browser, after the page has already loaded. When that's the case, your server logs never see the attack happen.

const destination = location.hash.substring(1);
window.location = destination;
Enter fullscreen mode Exit fullscreen mode

Perfectly ordinary code. Probably built for some deep-linking feature. But it reads directly from the URL fragment and acts on it with zero validation.

https://example.com/redirect#https://attacker.example
Enter fullscreen mode Exit fullscreen mode

The part after # never gets sent to the server at all, it's pure client-side. The victim's own browser reads it and redirects them. No server involved, no request log, nothing for a WAF to catch.

Why This One Is Scary: HackerOne Found It on Its Own Site

Here's the part I find genuinely funny. HackerOne, the bug bounty platform, runs one of the largest security researcher communities on earth.

Report #398054, disclosed publicly on their own platform: a DOM-based XSS vulnerability on hackerone.com itself, caused by an insecure message event listener tied to a Marketo contact form. (HackerOne)

The presentation tool reveal.js had the same class of bug (CVE-2020-8127): a postMessage handler that let a caller invoke arbitrary internal methods, turned into a working XSS chain. (writeup)

The common thread: a page listens for cross-window messages and trusts whatever arrives.

window.addEventListener("message", event => {
  process(event.data); // who sent this?
});
Enter fullscreen mode Exit fullscreen mode

Anyone who can get the victim to open a popup or iframe can fire data into that handler. The fix is one line, and it's the one line that keeps getting skipped:

window.addEventListener("message", event => {
  if (event.origin !== "https://trusted-partner.com") return;
  process(event.data);
});
Enter fullscreen mode Exit fullscreen mode

There's a reason location.hash in particular is a favorite for bug bounty hunters: it's never sent to the server, which means it's invisible to server logs, WAFs, and most automated scanners entirely. You can only find this class of bug by actually reading the client-side JavaScript. (dev.to writeup)

The One Question That Explains All of It

Every example above, the Tumblr redirect, the Rails CVE, the HackerOne postMessage bug, the Google Cloud phishing campaign, comes back to one question:

Where did the data come from, and where did it end up?

Security people call the origin a source and the destination a sink. Common sources:

Source Where it shows up
location.hash / location.search URL fragment and query string
event.data Cross-window messages (postMessage)
document.cookie Only non-HttpOnly cookies
input.value Form fields
API responses Anything a user or third party can influence

Common sinks:

Sink Risk
window.location = data Open Redirect
element.innerHTML = data DOM XSS
eval(data) Arbitrary code execution
document.write(data) Unsanitized DOM injection

Neither a source nor a sink is a bug on its own. The vulnerability lives in the unguarded path between them.

A Five-Question Checklist

Next time you're staring at a piece of code and trying to decide if it's a problem:

  1. Where did the data come from?
  2. Can an attacker influence it?
  3. Where does it end up?
  4. Is there validation between the two?
  5. What actually happens if it's abused?

That's the entire audit. No memorized vulnerability list required.

The Takeaway

Open Redirect and DOM XSS both survive because they exploit a very human habit: we check the domain, and we trust it once it looks right.

An attacker doesn't need to break into google.com, hackerone.com, or a government .gov site. They just need one endpoint that forwards a visitor without asking questions, and 350 phishing domains, or 9,300 emails, later, it's still working.

Go check your own postMessage listeners and redirect logic today. It costs one afternoon. The alternative costs a lot more.

Top comments (0)