Referrer-Policy: stop leaking URLs (and tokens) to other sites

Published October 30, 2026 · about a 6-minute read

Here's a leak that hides in plain sight. Every time someone on your site clicks a link to another site — or your page loads an image, script or font from a third party — the browser can tell that other server exactly which page of yours the user was on. The full URL. If anything sensitive is sitting in that URL, you just handed it to someone else's logs. The Referrer-Policy header is how you control that, and it's one of the quickest security headers to get right.

What actually leaks

When a browser makes a request triggered by your page, it may attach a Referer header (yes, misspelled — a 1990s typo enshrined in the spec forever) naming the URL the request came from. That's useful for analytics, and mostly harmless — until your URLs contain things they shouldn't. The classic disasters:

None of this throws an error. It's a silent, continuous outflow, and most teams never notice it's happening.

The modern default (and why you shouldn't just trust it)

The good news: browsers got much saner about this. When your site sends no policy at all, current browsers default to strict-origin-when-cross-origin. Under that default:

That's a reasonable baseline. But "the browser's default is fine" isn't a security posture — it means you're trusting every browser version your users run, you've set no explicit intent, and you have nothing stricter on the pages that actually need it. I'd rather state the policy myself, as a header, so it's deliberate and auditable like any other security header.

The values, from loosest to strictest

ValueWhat it sends
unsafe-urlFull URL, always, everywhere — including HTTPS→HTTP. Don't use this.
no-referrer-when-downgradeFull URL except on HTTPS→HTTP. The old default; too loose now.
originOnly your origin, to everyone, always.
origin-when-cross-originFull URL same-origin, origin only cross-origin.
strict-origin-when-cross-originLike above, but sends nothing on HTTPS→HTTP. The modern default and a solid baseline.
same-originFull URL to your own site, nothing to any other site.
strict-originOnly your origin, and nothing on HTTPS→HTTP.
no-referrerNever send a referrer at all.

What I'd actually set

Keep it simple. Send a site-wide header as your baseline:

Referrer-Policy: strict-origin-when-cross-origin

Then tighten the pages whose URLs can carry secrets. On a password-reset route, account settings, or anything with a token or ID in the path, drop to same-origin or no-referrer. You can set it per-response on the server, or per-element in HTML (a referrerpolicy attribute on a specific link or image), but a sensible global header plus a stricter override on sensitive routes covers almost everyone.

The part most posts skip

Referrer-Policy reduces the blast radius. It does not fix the underlying mistake. If a password-reset token or a session ID is in your URL in the first place, the header is damage control — it just narrows who you leak it to. The real fix is to keep secrets out of URLs: put tokens in the request body or short-lived, single-use, and out of the query string.

So treat the header as the belt and the URL hygiene as the suspenders. Set Referrer-Policy because it's cheap and it closes a real leak to analytics and ad networks — and separately, audit whether anything sensitive is riding in your URLs at all. There's a privacy-law angle too: leaking account identifiers or emails to third-party domains through the referrer is exactly the kind of incidental data sharing a GDPR review is meant to catch.

Like every header, this one is invisible until you check for it, and a deploy or CDN change can silently drop it. The only way to know Referrer-Policy is actually set — and set the way you intended — is to read your live response headers from outside, and keep reading them.

Check your security headers in seconds

Perimeter inspects your Referrer-Policy and the rest of your security headers — Content-Security-Policy, HSTS, X-Frame-Options and more — alongside your TLS, DNS and accessibility posture. And it re-checks on a schedule, so a header a deploy quietly drops gets flagged before it becomes a standing leak. Free, no signup.

Monitor your headers → · Agency plan $29/mo, up to 25 domains