Using Referrer-Policy to Prevent URL Token Leaks

Sensitive authentication tokens, password reset hashes, and session identifiers are frequently passed through URL query strings during user authentication flows. When a user navigates to an external site or a webpage loads third-party assets, web browsers automatically transmit the full URL in the HTTP Referer header to the recipient server. Implementing a strict Referrer-Policy header resolves this vulnerability by instructing the browser to strip the path and query string—or drop the header entirely—before transmitting request metadata, thereby ensuring that private tokens remain hidden from external domains, third-party trackers, and server access logs.

The Mechanism of URL Token Leakage

URL query strings are not designed to store confidential data, yet workflows such as magic-link logins, OAuth callbacks, and password resets often append one-time tokens directly to the URL (for example, https://example.com/reset?token=secret123).

When a user visits a page containing this URL structure, two common actions trigger cross-origin requests:

  1. Third-Party Subresources: The page loads external scripts, fonts, stylesheets, images, or analytics trackers.
  2. Outbound Navigation: The user clicks an external link to navigate away from the current application.

By default, older or unconfigured browsers send the Referer request header containing the complete URL—including the protocol, domain, path, and query string—to the destination server. As a result, third-party servers, content delivery networks (CDNs), and intermediary proxies capture and log the sensitive token in their access logs, exposing it to potential interception and misuse.

How Referrer-Policy Solves the Issue

The Referrer-Policy HTTP response header allows server administrators to define the exact rules browsers must follow when populating the Referer header. By enforcing strict constraints, developers can prevent query strings from ever leaving the user's browser during cross-origin traffic.

The browser evaluates the policy before generating network requests. Depending on the rule applied, the browser modifies the Referer header value into one of three formats:

  • Full URL: Protocol, domain, path, and query string.
  • Origin Only: Protocol and domain (e.g., https://example.com/).
  • Empty: The Referer header is omitted entirely.

Strict Referrer-Policy Options

To ensure query strings containing tokens are never exposed externally, web applications must use one of the following strict policies:

  • no-referrer: Directs the browser to never send the Referer header with any request, regardless of destination or security level. This provides maximum privacy and eliminates query string leakage entirely.
  • strict-origin: Sends only the origin (scheme, host, and port) over HTTPS connections, completely omitting the path and query string. If a request downgrades to insecure HTTP, no header is sent.
  • strict-origin-when-cross-origin: Sends the full URL for same-origin requests, allowing internal tracking and application functionality. When a cross-origin request is made over HTTPS, the browser strips the path and query string, sending only the origin. Requests downgrading from HTTPS to HTTP send no header.

Implementation Methods

To protect URLs across an entire application, the Referrer-Policy should be applied at the web server or application framework level as an HTTP header:

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

If server configuration is inaccessible, the policy can be specified within the <head> tag of an HTML document:

<meta name="referrer" content="strict-origin-when-cross-origin">

For specific hyperlinks that direct users off-site, developers can apply element-level protection using the rel attribute to ensure the full URL is not forwarded:

<a href="https://external-example.com" rel="noreferrer">External Link</a>

Defense-in-Depth

While configuring a strict Referrer-Policy stops the browser from leaking query strings to external parties, security best practices dictate that sensitive tokens should ideally not be placed in URLs. Query parameters remain vulnerable to browser history storage, shoulder surfing, and local device inspection. Using modern alternatives—such as HTTP request bodies, secure cookies, and the History API (history.replaceState()) to scrub tokens from the address bar immediately after processing—combined with strict Referrer-Policy headers creates a robust defense against credential exposure.