Referrer-Policy: Prevent Data Leaks via the Referer Header
URLs containing tokens or PII automatically leak to external domains through the Referer header. A single header configuration resolves this vulnerability.
In Short
The Referer header (with a single “r” — a historical typo perpetuated from the RFC) is sent automatically by the browser with every request and contains the URL of the page the user is coming from. If your URL contains session tokens, PII (Personally Identifiable Information) parameters, or sensitive internal paths, they are leaked to any domain you request — CDNs, analytics, ad networks, social plugins.
Referrer-Policy: strict-origin-when-cross-origin is the modern standard that allows the full referrer on same-origin, only the origin on cross-origin HTTPS, and nothing on HTTPS→HTTP downgrades.
In the context of GDPR Art. 5 (data minimization) and Art. 32 (security by design), managing the Referer is a legal responsibility, not just a best practice.
Concrete Leakage Cases
Password Reset Token
User password reset URL:
https://company.com/reset?token=abc123def456&email=user@partner.com
On this page, there is an external link (footer, ad, analytics):
<a href="https://help.example.com/contact">Contact</a>
When the user clicks or if the page makes an automatic request to help.example.com, the browser sends:
Referer: https://company.com/reset?token=abc123def456&email=user@partner.com
help.example.com (or whatever CDN/analytics is in between) sees the token + email. If their logs are accessible to employees or compromised, an attacker can perform a password reset on behalf of the user.
Admin URLs with Sensitive UUIDs
https://company.com/admin/users/12345/medical-record/edit
On the page, <script src="https://googletagmanager.com/gtm.js"> — Google receives:
Referer: https://company.com/admin/users/12345/medical-record/edit
Medical PII data leaked to Google Analytics. Potential direct GDPR breach (Art. 9 — special categories of data, health).
Private Search Queries
https://intranet.company.com/search?q=turnover-2024-confidential
Any external link → Referer with the confidential query sent to a third party.
Anatomy of Referrer-Policy
Referrer-Policy: strict-origin-when-cross-origin
| Policy | Behavior |
|---|---|
no-referrer | No Referer ever sent — paranoid |
no-referrer-when-downgrade | Legacy browser default — Referer only on same protocol HTTPS→HTTPS |
origin | Only the origin (https://company.com), no path/query |
origin-when-cross-origin | Full URL on same-origin, only origin on cross-origin |
strict-origin | Only origin on HTTPS→HTTPS, nothing on HTTPS→HTTP |
strict-origin-when-cross-origin | Modern default — full on same-origin, origin on cross-origin HTTPS, nothing on downgrade |
same-origin | Full on same-origin, nothing on cross-origin |
unsafe-url | Full URL always — dangerous, do not use |
Recommendation for 99% of cases: strict-origin-when-cross-origin (default Chrome 85+, Firefox 87+).
Step-by-Step Implementation
Step 1 — Global Header
nginx:
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
Apache:
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Caddy:
header Referrer-Policy strict-origin-when-cross-origin
Express (Helmet):
app.use(helmet.referrerPolicy({ policy: 'strict-origin-when-cross-origin' }));
Step 2 — Per-link Override for Paranoid Cases
For highly sensitive links (admin → external), use the rel="noreferrer" HTML attribute:
<a href="https://external.com" rel="noreferrer">External</a>
Combined with noopener (anti-tabnabbing):
<a href="https://external.com" rel="noreferrer noopener" target="_blank">External</a>
Step 3 — Move Tokens Out of Query Strings
Fundamental best practice: password reset tokens, magic links, session tokens must NOT be in the URL query. Use:
- POST body for form submissions
- HttpOnly Session cookie for session identifiers
- URL fragment (
#token=xxx) for client-side tokens (the fragment is not sent in the Referer and does not appear in server logs)
If the URL absolutely must contain a token (magic link in email):
- Token is single-use (consumed on first visit)
- Token expires quickly (15 min - 24h max)
- Destination page has
Referrer-Policy: no-referrerstrict - Destination page immediately redirects to a URL without the token
Step 4 — Audit Existing URLs
# Search logs for URLs with PII / tokens
grep -E "token=|email=|password=|key=" /var/log/nginx/access.log
Migrate discovered URLs to POST body or session cookies.
Common Misconceptions
“Referrer-Policy reduces referral traffic in Google Analytics.” — Partially true. strict-origin-when-cross-origin sends only the origin to external domains (GA receives https://company.com, not the exact URL). For internal analytics, use server-side tracking or first-party solutions.
“The Referer header is opt-in anyway; modern browsers strip it.” — Incorrect. Browsers send the Referer by default — Referrer-Policy is the control mechanism. Without an explicit header, the default depends on the browser (strict-origin-when-cross-origin in Chrome 85+, but not universal).
“GDPR doesn’t explicitly require this.” — GDPR Art. 32 requires “appropriate technical and organizational measures.” European DPAs (CNIL France, Garante Italy) have fined companies for leaking PII via Referer in 2023-2024. It is implicitly mandatory.
Check Now
ARTEMIS detects missing Referrer-Policy in any Site scan (2 EUR) plus 36 other checks.
🔗 Complementary CAI Technology Solutions
- ARTEMIS — Referrer-Policy verification + 36 other headers/tests.
- Auditope — Holistic web audit (SEO + Performance + GDPR + UX).
- Lexnomia — Auditor-grade GDPR evaluation — leaking PII is a key category.
- BeLegal — Free 5-minute GDPR check.
- AriaUnited — EU funding consultancy for privacy / data minimization investments.