Skip to main content

Loose Referrer Policy (no-referrer-when-downgrade) Detected

Issue No: 112

Category: Html Head Tags

Issue type: Warning

Priority: Important

Description

The no-referrer-when-downgrade referrer policy causes browsers to send the full URL (including path and query string) in the HTTP Referer header for cross-origin HTTPS-to-HTTPS requests. This was the browser default prior to Chrome 85 (2020). Modern browsers now default to strict-origin-when-cross-origin, which sends only the origin (e.g. https://example.com) instead of the full URL (https://example.com/page?token=abc123). Explicitly setting the old loose policy overrides the modern default and leaks sensitive URL parameters to third-party destinations.

How do we capture it

  1. Check the HTTP Referrer-Policy response header for each crawled page:

    • Extract the header value.
    • Record referrer_policy_header.
  2. Check for <meta name="referrer"> in the page <head>:

    • Extract the content attribute value.
    • Record referrer_meta_value.
  3. Determine the effective policy:

    • HTTP response header takes precedence over the meta tag.
    • If the header is absent, the meta tag is effective.
    • If neither is present, the effective policy is the browser default (strict-origin-when-cross-origin).
    • Record effective_policy.
  4. Classify the policy:

    • Mark is_no_referrer_when_downgrade = true if the effective policy is exactly no-referrer-when-downgrade.
    • Mark is_loose_policy = true if the effective policy is no-referrer-when-downgrade or unsafe-url.
    • Mark is_valid_value = false if the value is not in the set of valid Referrer-Policy tokens.
  5. Detect conflicts:

    • If both the HTTP header and meta tag are present and differ, set has_conflict = true.
  6. Scan the URL and query string for sensitive parameters:

    • Check the current page's URL query string for common sensitive parameter names.
    • Sensitive parameter patterns: token, key, api_key, auth, session, secret, password, access_token, refresh_token, code, state, nonce, utm_ prefixed params with PII patterns.
    • Record url_has_sensitive_params = true and list the parameter names in sensitive_params.

What to store

FieldTypeComment
site_idintegerFK → sites(id)
page_idintegerFK → pages(id)
referrer_meta_presentbooleanWhether <meta name="referrer"> exists in <head>
referrer_meta_valuetextcontent value of the referrer meta tag; NULL if absent
referrer_policy_headertextValue of the Referrer-Policy HTTP response header; NULL if absent
effective_policytextThe resolved policy (header > meta > browser default)
is_no_referrer_when_downgradebooleanWhether effective policy is exactly no-referrer-when-downgrade
is_loose_policybooleanWhether effective policy is no-referrer-when-downgrade or unsafe-url
is_valid_valuebooleanWhether effective policy is a recognised Referrer-Policy token
has_conflictbooleanWhether HTTP header and meta tag declare different policies
url_has_sensitive_paramsbooleanWhether the page URL contains sensitive query parameters
sensitive_paramstext[]List of detected sensitive parameter names in the URL
checked_attimestampWhen this check was last performed

Condition for trigger

The following rules evaluate stored fields and produce diagnostics in the audit report.

  • Trigger Rule 1: Loose Policy (no-referrer-when-downgrade)

    • Target Field: is_no_referrer_when_downgrade
    • Evaluation Logic: is_no_referrer_when_downgrade = true AND url_has_sensitive_params = false
    • Severity: WARNING
    • Diagnostic Message: "The referrer policy is set to no-referrer-when-downgrade, which sends the full URL (including path and query string) to cross-origin HTTPS destinations via the Referer header. The modern browser default (strict-origin-when-cross-origin) sends only the origin. Update the policy to strict-origin-when-cross-origin or stricter."
  • Trigger Rule 2: Loose Policy With Sensitive URL Parameters

    • Target Field: is_loose_policy, url_has_sensitive_params
    • Evaluation Logic: is_loose_policy = true AND url_has_sensitive_params = true
    • Severity: CRITICAL
    • Diagnostic Message: "The referrer policy is [effective_policy] and the page URL contains sensitive parameters ([sensitive_params]). These parameters are being leaked in the Referer header to every cross-origin resource loaded on this page (analytics, ads, fonts, CDN assets). Change the policy to no-referrer or strict-origin immediately."
  • Trigger Rule 3: Meta Tag and HTTP Header Conflict

    • Target Field: has_conflict
    • Evaluation Logic: has_conflict = true
    • Severity: CRITICAL
    • Diagnostic Message: "The Referrer-Policy HTTP header ([referrer_policy_header]) and <meta name=\"referrer\"> tag ([referrer_meta_value]) declare different policies. The HTTP header takes precedence. Remove the conflicting meta tag or align both to the same intended policy."
  • Trigger Rule 4: Invalid Referrer Policy Value

    • Target Field: is_valid_value
    • Evaluation Logic: is_valid_value = false AND effective_policy IS NOT NULL
    • Severity: WARNING
    • Diagnostic Message: "The referrer policy value [effective_policy] is not a valid Referrer-Policy token. Browsers will ignore an invalid value and fall back to the default policy. Use a valid value: no-referrer, no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, or unsafe-url."
  • Trigger Rule 5: unsafe-url Policy Detected

    • Target Field: effective_policy
    • Evaluation Logic: effective_policy = 'unsafe-url'
    • Severity: CRITICAL
    • Diagnostic Message: "The referrer policy is set to unsafe-url, which sends the full URL (including path, query string, and any sensitive parameters) for ALL requests — including HTTP (downgrade) requests. This is the most permissive policy and leaks sensitive URL data broadly. Replace with strict-origin-when-cross-origin at minimum."

Sources

Long description

The HTTP Referer header (note the historical misspelling) is sent by browsers on each request and tells the server the URL of the page that initiated the request. This header is used by analytics platforms, advertising networks, and CDNs to understand referral traffic. The Referrer-Policy governs how much of the originating URL is included in that header.

Policy comparison table

PolicySent to same-originSent to cross-origin HTTPSSent to HTTP (downgrade)
no-referrerNothingNothingNothing
strict-originOrigin onlyOrigin onlyNothing
strict-origin-when-cross-origin (modern default)Full URLOrigin onlyNothing
origin-when-cross-originFull URLOrigin onlyNothing
originOrigin onlyOrigin onlyOrigin only
no-referrer-when-downgrade (old default)Full URLFull URLNothing
unsafe-urlFull URLFull URLFull URL

The key distinction is between "origin only" (https://example.com) and "full URL" (https://example.com/path?token=secret). The no-referrer-when-downgrade policy sends the full URL to cross-origin HTTPS destinations — meaning every third-party resource load (fonts, analytics scripts, CDN assets) receives the full URL including all query parameters.

Why this changed in Chrome 85

Chrome 85 (August 2020) changed the browser default from no-referrer-when-downgrade to strict-origin-when-cross-origin. Firefox and Safari followed. Sites that explicitly set no-referrer-when-downgrade now need to do so deliberately — the browser no longer silently applies the loose policy. Explicitly declaring the old loose policy is a regression to less safe behaviour.

Sensitive parameter leakage scenario

Consider a checkout page: https://shop.example.com/checkout?session_id=abc123&return_token=xyz789. If the page loads a Google Font, a Stripe payment script, and a Google Analytics tag, all three receive a request with Referer: https://shop.example.com/checkout?session_id=abc123&return_token=xyz789. The session_id and return_token values are now visible to three separate third parties.

Recommended policy

For most sites: strict-origin-when-cross-origin. This is the modern browser default and provides a good balance:

  • Same-origin requests get the full URL (preserving internal analytics accuracy).
  • Cross-origin requests get only the origin (preventing parameter leakage to third parties).
  • No data is sent on HTTP downgrade requests.

Common failure patterns:

  • The policy was explicitly set years ago to maintain referral analytics accuracy and was never updated when browsers changed their defaults.
  • A third-party tag manager or analytics script injects a meta tag that sets no-referrer-when-downgrade.
  • The policy conflicts between the HTTP header (set by a WAF or CDN rule) and the HTML meta tag (set in the page template).
  • unsafe-url was set during debugging and was never reverted to a safe value.
  • No policy is explicitly set and the browser default is assumed to be no-referrer-when-downgrade, which is no longer true in modern browsers.

How to Fix

  1. Set the Referrer-Policy HTTP response header at the server or CDN level:

    • Apache: Header always set Referrer-Policy "strict-origin-when-cross-origin"
    • Nginx: add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    • CDN (Cloudflare, etc.): add the header via a Transform Rule or Page Rule.
    • Setting the header at the server level means it applies to all pages automatically.
  2. Remove or update the <meta name="referrer"> tag if it sets a loose policy:

    • If you want a consistent sitewide policy, set it via the HTTP header and remove the meta tag entirely.
    • If you need per-page policy overrides, use the meta tag to set a stricter policy on sensitive pages (e.g. no-referrer on checkout pages).
  3. For pages with sensitive URL parameters, use no-referrer or strict-origin to ensure parameters are never leaked:

    • <meta name="referrer" content="no-referrer"> on checkout, authentication callback, and password-reset pages.
  4. Audit third-party scripts that may inject <meta name="referrer"> tags via tag manager. Check the tag manager container for any referrer policy overrides.

  5. Verify the effective policy using browser DevTools:

    • Open Network tab → click any cross-origin request → inspect the Referer request header.
    • Confirm it shows only the origin (e.g. https://example.com) and not the full path with parameters.
  6. Test that analytics are not broken: after changing the policy, verify that referral traffic reporting in Google Analytics / Matomo still works. strict-origin-when-cross-origin preserves the Referer header for cross-origin HTTPS requests (origin only), so direct referral source tracking remains functional.


Additional technical notes

Referrer-Policy via <link> element

In addition to the HTTP header and <meta> tag, individual <a> and <link> elements can carry a referrerpolicy attribute that overrides the page-level policy for that specific link or resource:

<a href="https://external.com" referrerpolicy="no-referrer">Visit</a>

This per-element override is useful for links to sensitive external destinations where the page-level strict-origin-when-cross-origin policy still sends the origin but you want no referrer sent at all.

Referrer-Policy and analytics impact

Changing from no-referrer-when-downgrade to strict-origin-when-cross-origin may cause changes in analytics referral data:

  • Internal traffic referral: same-origin requests still receive the full URL, so internal analytics are unaffected.
  • External referrals TO this site: not affected — this policy governs what the current page sends, not what incoming traffic reports.
  • Outbound referrals FROM this site to third-party analytics tools: only the origin is sent, not the full path. This can reduce granularity in tools that read the Referer header to attribute traffic sources.
  • Google Analytics via its own JS tag: GA uses its own measurement protocol and does not rely on the Referer header for standard page view tracking. Changing the policy does not affect GA data collection.

OWASP recommendation

The OWASP Secure Headers Project lists Referrer-Policy: strict-origin-when-cross-origin as the recommended default. It is included in the OWASP HTTP Security Headers cheat sheet as a baseline requirement for all web applications. Sites without an explicit policy (or with a loose policy) fail OWASP header compliance checks.

Policy inheritance and nested iframes

The Referrer-Policy HTTP header and <meta> tag apply to the document they are served with. Nested iframes are governed by their own document's policy, not the parent frame's policy. For embedded third-party content (payment iframes, chat widgets), the embedded document's own origin server controls the referrer policy for requests it initiates.


Validation checklist

Before marking this issue resolved, confirm all of the following:

  • curl -I {url} output includes Referrer-Policy: strict-origin-when-cross-origin (or stricter).
  • No <meta name="referrer" content="no-referrer-when-downgrade"> is present on any page.
  • No <meta name="referrer" content="unsafe-url"> is present on any page.
  • Pages with sensitive URL parameters use no-referrer or strict-origin policy.
  • Browser DevTools confirms cross-origin requests show only the origin in the Referer header, not the full URL with parameters.