A continuation of Janady13/crawler-signal-reference / framework-html-meta-referrer.md. The complete source identity, every recorded occurrence, and linked equations are on its first page.
Source transcript · continued
Download complete source text ↓1,887 lines · 60.9 KB
### Per route overrides
5. [ ] Sensitive routes (intake, password reset, admin) have stricter policies.
6. [ ] YMYL clients have `same-origin` minimum at default.
7. [ ] Federal portal routes have appropriate stricter policy.
### HTML meta tag
8. [ ] Meta tag included as fallback for environments without HTTP header control.
9. [ ] Meta tag value matches HTTP header (consistency).
10. [ ] Meta tag uses correctly spelled "referrer" (not "referer").
### YMYL specific
11. [ ] Arkansas Counseling and Wellness: `same-origin` policy.
12. [ ] Handled Tax: `same-origin` policy.
13. [ ] Per page overrides for highly sensitive content.
### Federal subcontractor
14. [ ] WeCoverUSA: `strict-origin-when-cross-origin` baseline.
15. [ ] Sensitive federal routes: stricter (`same-origin` or `no-referrer`).
16. [ ] Aligns with NIST 800-53 information disclosure controls.
### Per link / element
17. [ ] External links use `rel="noreferrer noopener"` where appropriate.
18. [ ] External CDN images use `referrerpolicy="no-referrer"` where appropriate.
19. [ ] Iframes have appropriate referrerpolicy attribute.
### Analytics and affiliate
20. [ ] Affiliate functionality verified working (origin attribution sufficient).
21. [ ] Google Analytics receiving expected data.
22. [ ] No broken cross site tracking that should work.
### Privacy compliance
23. [ ] Privacy policy documents referrer behavior.
24. [ ] HIPAA/financial privacy alignment for YMYL clients.
25. [ ] GDPR data sharing minimization.
### Header coordination
26. [ ] HTTP header takes precedence over meta tag (verified).
27. [ ] All Bubbles security headers consistently set (snippets/security-headers.conf).
### Documentation
28. [ ] Per client referrer policy documented.
29. [ ] Rationale for policy choice documented.
30. [ ] Override routes documented.
### Verification
31. [ ] Test endpoint logs verify expected Referer values.
32. [ ] Browser DevTools network tab shows expected headers.
33. [ ] `referrer-policy-audit.sh` shows all sites configured.
### Mistake checking
34. [ ] No `unsafe-url` policy on production sites.
35. [ ] No `no-referrer-when-downgrade` (legacy; use modern default).
36. [ ] Spelling correct in meta tags ("referrer" not "referer").
### Cross cutting
37. [ ] Login pages have appropriate referrer policy.
38. [ ] Password reset pages have `no-referrer` policy.
39. [ ] API endpoints have appropriate policy.
### After deployment
40. [ ] Post deploy verification via `curl -sI` confirms all expected policies.
A site that passes all 40 has correctly configured referrer policy across all routes with appropriate privacy levels per client context.
---
## 19. COMMON PITFALLS
Fifteen patterns to recognize and avoid.
**Pitfall 1: Misspelled meta name as "referer".**
Symptom: `<meta name="referer" content="...">` ignored by browsers.
Why it breaks: meta tag name must be "referrer" (two R's).
Fix: change to `<meta name="referrer" content="...">`.
**Pitfall 2: No policy set; default `unsafe-url` behavior in old browsers.**
Symptom: full URLs sent to external sites including sensitive query parameters.
Why it breaks: no explicit policy; legacy browsers may default permissively.
Fix: set explicit policy (modern default `strict-origin-when-cross-origin`).
**Pitfall 3: `unsafe-url` set explicitly.**
Symptom: full URLs sent to all destinations.
Why it breaks: maximum privacy leakage.
Fix: change to `strict-origin-when-cross-origin` or stricter.
**Pitfall 4: `no-referrer` everywhere breaks affiliate.**
Symptom: affiliate program shows zero attribution.
Why it breaks: too strict; affiliate networks need referrer.
Fix: relax to `strict-origin-when-cross-origin` (origin sufficient for affiliate).
**Pitfall 5: YMYL site has standard policy.**
Symptom: Arkansas Counseling site sends path information to external sites.
Why it breaks: insufficient privacy for healthcare context.
Fix: tighten to `same-origin`.
**Pitfall 6: Session tokens in URL leaked via referrer.**
Symptom: external site logs show URLs containing session tokens.
Why it breaks: tokens in URLs combined with permissive referrer.
Fix: stricter referrer plus move tokens out of URLs.
**Pitfall 7: External links missing `noreferrer noopener`.**
Symptom: clicking external links exposes window.opener; potential security issue.
Why it breaks: target="_blank" without noopener has security implications.
Fix: always use `rel="noreferrer noopener"` for external `target="_blank"` links.
**Pitfall 8: HTML meta tag conflicts with HTTP header.**
Symptom: page sets `<meta name="referrer" content="no-referrer">` but HTTP header says `strict-origin-when-cross-origin`.
Why it breaks: usually HTTP wins; meta tag ignored.
Fix: align both, or remove meta tag if HTTP header is set.
**Pitfall 9: Federal site without policy.**
Symptom: WeCoverUSA security audit flag.
Why it breaks: NIST 800-53 controls reference referrer policy.
Fix: set policy and document.
**Pitfall 10: Policy lost on redirects.**
Symptom: redirects don't include the Referrer-Policy header.
Why it breaks: `add_header` in nginx may not apply to redirect responses without `always` keyword.
Fix: ensure `always` keyword in nginx directive.
**Pitfall 11: Policy set per location but not globally.**
Symptom: most pages have policy; 404 pages don't.
Why it breaks: location specific add_header; not inherited to default 404.
Fix: put add_header in server block, not location block. Or use snippets/include.
**Pitfall 12: WordPress site has no referrer policy.**
Symptom: WordPress site exposes referrer everywhere.
Why it breaks: WordPress doesn't set Referrer-Policy by default.
Fix: add to .htaccess or use security plugin.
**Pitfall 13: Strict policy breaks legitimate cross site tracking.**
Symptom: business intelligence dashboard shows referrer dropoff after policy change.
Why it breaks: `same-origin` or `no-referrer` blocks cross site analytics.
Fix: review what tracking is needed; choose appropriate policy.
**Pitfall 14: Mixing legacy `rel="noreferrer"` and new `referrerpolicy` attribute.**
Symptom: link has both attributes with conflicting values.
Why it breaks: behavior may vary by browser.
Fix: choose one approach per link.
**Pitfall 15: Forgetting policy on password reset emails.**
Symptom: password reset link page sends full URL referrer to embedded resources.
Why it breaks: reset tokens leak via referrer.
Fix: set `no-referrer` on password reset pages specifically; use POST for reset action.
---
## 20. DIAGNOSTIC COMMANDS
Reference of commands useful for referrer policy investigation.
### Inspect HTTP header
```bash
# Check Referrer-Policy header
curl -sI https://example.com/ | grep -i "Referrer-Policy"
# Per route check
curl -sI https://example.com/intake/ | grep -i "Referrer-Policy"
# Verify "always" keyword effect (redirect should also have header)
curl -sIL https://example.com/redirect-source/ | grep -i "Referrer-Policy"
```
### Inspect meta tag
```bash
# Check meta tag
curl -s https://example.com/ | grep -oE 'meta name="referrer" content="[^"]+"'
# Also check for misspelled version (should be absent)
curl -s https://example.com/ | grep -c 'meta name="referer"'
# Expected: 0
```
### Cross check both layers
```bash
URL=$1
HTTP_POLICY=$(curl -sI "$URL" | grep -i "Referrer-Policy" | head -1 | tr -d '\r')
META_POLICY=$(curl -s "$URL" | grep -oE 'meta name="referrer" content="[^"]+"' | head -1)
echo "URL: $URL"
echo "HTTP header: $HTTP_POLICY"
echo "Meta tag: $META_POLICY"
if [ -n "$HTTP_POLICY" ] && [ -n "$META_POLICY" ]; then
HTTP_VALUE=$(echo "$HTTP_POLICY" | sed 's/.*: *//')
META_VALUE=$(echo "$META_POLICY" | sed 's/.*content="\([^"]*\)".*/\1/')
if [ "$HTTP_VALUE" = "$META_VALUE" ]; then
echo "ALIGNED: same value in both layers"
else
echo "MISMATCH: HTTP says '$HTTP_VALUE', meta says '$META_VALUE'"
fi
fi
```
### Bulk audit across all sites
```bash
referrer-policy-audit.sh
```
### Test what referrer is sent
For development testing, set up a logging endpoint:
```python
# /opt/bubbles/test-endpoints/referrer-logger.py
from fastapi import FastAPI, Request
app = FastAPI()
@app.get("/log-referrer")
async def log_referrer(request: Request):
referer = request.headers.get("referer", "(none)")
return {
"received_referer": referer,
"your_origin": request.headers.get("origin", "(none)"),
}
```
Run on port 9999:
```bash
uvicorn referrer-logger:app --port 9999
```
Then click link from your site to `http://localhost:9999/log-referrer`; verify the response shows expected Referer value.
### Check outbound links
```bash
# Find external links on a page
curl -s https://example.com/ | grep -oE 'href="https?://[^"]+"' | grep -v "example.com" | sort -u
```
### Verify nginx configuration
```bash
nginx -t
# Or show effective config for a site
nginx -T 2>/dev/null | grep -A 20 "server_name example.com"
```
### After configuration changes
```bash
nginx -t && systemctl reload nginx
# Verify
curl -sI https://example.com/ | grep -i "Referrer-Policy"
```
### Browser DevTools
In Chrome DevTools:
1. Open the page.
2. Open Network tab.
3. Click an outbound link.
4. In the request to the destination, examine `Referer:` header value.
5. Verify it matches expected policy behavior.
---
## 21. CROSS-REFERENCES
* [framework-http-security-headers.md](framework-http-security-headers.md): the HTTP `Referrer-Policy` header is the canonical layer for setting this policy. This HTML meta tag framework is the supplementary layer.
* [framework-html-meta-charset.md](framework-html-meta-charset.md): meta tag placement order in head.
* [framework-html-meta-viewport.md](framework-html-meta-viewport.md): order in head (after charset and viewport).
* [framework-html-meta-color-scheme.md](framework-html-meta-color-scheme.md): order in head.
* [framework-html-meta-author.md](framework-html-meta-author.md): the privacy considerations for author identity tie into referrer privacy considerations.
* [framework-http-performance-headers.md](framework-http-performance-headers.md): the Server header relates to information disclosure (similar privacy concept).
* [UNIVERSAL-RANKING-FRAMEWORK.md](UNIVERSAL-RANKING-FRAMEWORK.md): referrer policy not ranking but user trust and privacy signals matter.
* [SEO-BUILD-REFERENCE.md](SEO-BUILD-REFERENCE.md) v2.4: the build playbook including security headers.
* W3C Referrer Policy specification: https://www.w3.org/TR/referrer-policy/
* MDN Referrer-Policy HTTP header: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy
* MDN meta name=referrer: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta/name
* MDN referrerpolicy attribute: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/referrerpolicy
* MDN rel="noreferrer": https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel/noreferrer
* NIST SP 800-53 Rev 5: https://csrc.nist.gov/publications/detail/sp/800-53/rev-5/final
* OWASP Information Exposure Through Referrer: https://owasp.org/www-community/attacks/Information_Exposure_Through_Referer
---
## APPENDIX A: ONE PAGE QUICK REFERENCE
For the person who just wants the answer.
### The Bubbles rule
**Set `Referrer-Policy: strict-origin-when-cross-origin` via nginx HTTP header on every site. YMYL clients get `same-origin`.**
### The canonical patterns
```nginx
# Standard
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# YMYL (healthcare, financial)
add_header Referrer-Policy "same-origin" always;
# Federal subcontractor (with per route)
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
location /federal-portal/ {
add_header Referrer-Policy "same-origin" always;
}
```
### The HTML fallback
```html
<meta name="referrer" content="strict-origin-when-cross-origin">
```
### The spelling rule
* HTTP request header: `Referer:` (one R, misspelled historically).
* Everything else: `Referrer` (two R's, correct spelling).
### Five rules to memorize
1. **Default: `strict-origin-when-cross-origin` (matches modern browser default).**
2. **YMYL: `same-origin` (Arkansas Counseling, Handled Tax).**
3. **Federal: `strict-origin-when-cross-origin` minimum; stricter per route.**
4. **HTTP header preferred over meta tag.**
5. **External `target="_blank"` links: `rel="noreferrer noopener"`.**
### Five commands every operator should know
```bash
# 1. Check policy
curl -sI URL | grep -i "Referrer-Policy"
# 2. Verify meta tag spelling (should be "referrer" not "referer")
curl -s URL | grep -E 'meta name="(referer|referrer)"'
# 3. Audit all Bubbles sites
referrer-policy-audit.sh
# 4. Test what referrer is sent (with test endpoint)
# Click external link; check destination logs
# 5. Apply changes
nginx -t && systemctl reload nginx
```
### Three end to end tests
```bash
# 1. HTTP header set
URL=https://example.com/
POLICY=$(curl -sI "$URL" | grep -i "Referrer-Policy" | head -1)
[ -n "$POLICY" ] && echo "OK: $POLICY" || echo "FAIL: no policy"
# 2. Spelling correct in meta tag
WRONG=$(curl -s "$URL" | grep -c 'meta name="referer"')
[ "$WRONG" = "0" ] && echo "OK: spelling correct" || echo "FAIL: misspelled"
# 3. Per route overrides work for YMYL clients
SENSITIVE_POLICY=$(curl -sI "$URL/intake/" | grep -i "Referrer-Policy")
echo "Intake route policy: $SENSITIVE_POLICY"
```
If all three pass AND `curl -sI` consistently shows expected Referrer-Policy header across all routes AND verification endpoint receives expected Referer values, the referrer layer is correctly wired.
---
End of framework-html-meta-referrer.md.