Referrer-Policy 값별로 Referer에 실리는 것: 전체 URL, 출처만, 아무것도 없음
링크를 누르거나 이미지를 불러올 때 브라우저가 Referer에 무엇을 담는지는 Referrer-Policy가 정합니다. 여덟 가지 값의 차이, URL에서 늘 빠지는 부분, 헤더·meta·속성의 관계, 리다이렉트와 Origin 헤더에 미치는 영향을 명세 기준으로 정리했습니다.
비밀번호 재설정 페이지 주소가 https://example.com/account/reset?token=8f3a라고 해 봅시다. 이 페이지에 외부 도움말 링크나 다른 도메인의 이미지가 하나 있으면, 브라우저는 그 요청의 Referer 헤더에 지금 페이지의 주소를 담아 보낼 수 있습니다. 쿼리 문자열의 토큰까지 함께요. W3C Referrer Policy 명세는 이런 경우를 도입부에서 직접 예로 듭니다. URL에 세션 식별자가 들어 있는 HTTPS 애플리케이션, 그리고 URL 자체가 권한이 되는 “capability URL”입니다.
Referrer-Policy는 이 헤더에 무엇을 담을지 정하는 규칙입니다. 결과는 세 가지 중 하나입니다. 다듬은 전체 URL, 출처(origin)만, 또는 헤더 없음.
어떤 정책이든 빠지는 부분
어떤 정책이든 URL을 그대로 보내지는 않습니다. Referrer Policy 8.4절의 “strip url” 알고리즘은 다음을 지웁니다.
- 프래그먼트(
#뒤) - 사용자 이름과 비밀번호(
https://user:pass@host/의user:pass)
RFC 9110 10.1.3절도 같은 내용을 요구합니다. 사용자 에이전트는 Referer 값을 만들 때 프래그먼트와 userinfo를 넣어서는 안 됩니다(MUST NOT). 또 같은 알고리즘은 원래 URL의 스킴이 로컬 스킴이면 리퍼러 자체를 만들지 않습니다.
“출처만” 보내는 정책은 여기서 경로와 쿼리까지 지웁니다. 스킴, 호스트, 포트만 남고, 브라우저는 유효한 URL이 되도록 끝에 /를 붙입니다. 그래서 출처만 보내면 값은 https://example.com/이 됩니다.
반대로 “전체 URL”에는 경로와 쿼리 문자열이 그대로 남습니다. 앞의 예에서는 https://example.com/account/reset?token=8f3a가 그대로 나갑니다. 프래그먼트만 빠질 뿐입니다.
여덟 가지 값
https://example.com/page?q=1에 있는 문서가 세 곳으로 요청을 보낸다고 하면, 각 정책의 결과는 다음과 같습니다. Referrer Policy 8.3절 “Determine request’s Referrer” 알고리즘과 3장의 예시를 그대로 따른 것입니다.
| 정책 | 같은 출처 https://example.com/other |
다른 출처 https://not.example.com/ |
HTTPS에서 HTTP로 http://not.example.com/ |
|---|---|---|---|
no-referrer |
없음 | 없음 | 없음 |
no-referrer-when-downgrade |
전체 URL | 전체 URL | 없음 |
same-origin |
전체 URL | 없음 | 없음 |
origin |
출처 | 출처 | 출처 |
strict-origin |
출처 | 출처 | 없음 |
origin-when-cross-origin |
전체 URL | 출처 | 출처 |
strict-origin-when-cross-origin |
전체 URL | 출처 | 없음 |
unsafe-url |
전체 URL | 전체 URL | 전체 URL |
이름 앞의 strict-는 마지막 열을 가리킵니다. 명세의 조건은 “TLS로 보호된 문서에서 잠재적으로 신뢰할 수 있는(potentially trustworthy) URL이 아닌 곳으로 가는 요청”이고, 명세 예시에서는 http:// 주소가 그 경우입니다. 이때 strict- 계열과 no-referrer-when-downgrade는 아무것도 보내지 않습니다. 시작 문서가 처음부터 HTTP라면 이 조건에 해당하지 않으므로, 예를 들어 strict-origin은 어디로든 출처를 보냅니다.
몇 가지는 따로 짚어 둘 만합니다.
- 같은 출처인지는 요청의 출처와 요청이 지금 향하는 URL의 출처를 비교해서 판단합니다.
origin-when-cross-origin절의 노트는http://example.com/에서https://example.com/으로 가는 것처럼 스킴만 올라가도 다른 출처 요청으로 본다고 적습니다. - 명세 10.1절은
origin,origin-when-cross-origin,unsafe-url이 안전한 사이트의 출처나 URL을 암호화되지 않은 전송으로 흘릴 수 있다고 적고 있습니다.unsafe-url은 명세 스스로 “이름이 거짓말을 하지 않는다”고 경고하는 값입니다. strict-origin은 같은 출처 요청에도 출처만 보냅니다. 같은 사이트 안에서 어느 페이지에서 왔는지 알고 싶다면 맞지 않습니다.
정책을 정하는 곳
Referrer Policy 4장은 요청의 정책이 정해지는 경로를 다섯 가지로 꼽습니다.
- 응답 헤더
Referrer-Policy <meta name="referrer" content="...">a,area,img,iframe,link요소의referrerpolicy속성a,area,link요소의rel="noreferrer"- 상속(
srcdociframe이나 blob URL로 만든 문맥)
헤더 이름은 Referer의 오타를 따르지 않습니다. 정책 헤더는 Referrer-Policy, 요청 헤더는 Referer입니다.
fetch()에서는 요청마다 지정할 수 있습니다. Fetch 표준의 Request 생성자는 referrerPolicy 옵션을 요청의 정책으로 그대로 쓰고, referrer: ""를 주면 요청의 리퍼러를 no-referrer로 둡니다.
// 이 요청만 출처까지만 보낸다
await fetch("https://api.partner.example/v1/items", {
referrerPolicy: "strict-origin",
});
// 이 요청은 Referer를 보내지 않는다
await fetch("https://cdn.partner.example/pixel.gif", { referrer: "" });
요소 속성이나 fetch() 옵션으로 아무것도 정하지 않은 요청의 정책은 빈 문자열입니다. 현재 Fetch 표준의 main fetch 알고리즘은 이 빈 값을 요청의 policy container가 가진 정책으로 채웁니다. Referrer Policy 6장은 HTML 표준이 문서 응답의 정책을 그 문서에 정해 두고, 그 문서에서 나가는 요청의 기준으로 쓴다고 설명합니다. 그래서 개별 요청에 따로 정하지 않으면 문서의 정책이 적용됩니다.
헤더에 값을 여러 개 쓰면
명세 8.1절은 Referrer-Policy 헤더의 토큰을 앞에서부터 읽으면서, 알아보는 값이 나올 때마다 정책을 그 값으로 덮어씁니다. 모르는 값은 건너뜁니다. 그래서 마지막으로 인식한 값이 이깁니다. 11.1절은 이것을 새 값을 배포하는 방법으로 설명합니다. 앞에 오래된 브라우저도 아는 값을 두고, 뒤에 새 값을 둡니다.
Referrer-Policy: no-referrer, strict-origin-when-cross-origin
새 값을 아는 브라우저는 뒤의 값을 쓰고, 모르는 브라우저는 앞의 값에서 멈춥니다. 다만 명세는 이 동작이 referrerpolicy 속성에는 적용되지 않는다고 따로 적습니다. 속성의 경우에는 스크립트로 값을 넣었다가 다시 읽어 보면 그 값을 지원하는지 알 수 있다고 안내합니다.
리다이렉트 응답의 헤더도 정책을 바꾼다
Fetch 표준의 HTTP-redirect fetch는 리다이렉트를 따라가기 전에 Referrer Policy의 “Set request’s referrer policy on redirect”를 호출합니다. 이 알고리즘은 리다이렉트 응답의 Referrer-Policy 헤더를 8.1절과 같은 방식으로 해석하고, 그 결과가 인식된 값이면서 빈 문자열이 아닐 때만 요청의 정책을 바꿉니다. 헤더가 없거나 모르는 값만 있으면 정책은 그대로입니다.
여기서 중요한 것은 바뀐 정책이 무엇에 적용되느냐입니다. main fetch는 첫 요청을 보내기 전에 요청의 리퍼러를 계산해 요청에 저장합니다. 리다이렉트를 따라갈 때는 같은 요청으로 main fetch가 다시 실행되는데, 리퍼러가 이미 no-referrer이면 계산을 건너뛰고, URL이면 첫 단계에서 저장된 그 값을 새 정책으로 다시 줄입니다.
그래서 리다이렉트는 남아 있는 정보를 얼마나 보낼지는 바꿀 수 있어도, 이미 지워진 정보를 되살리지는 못합니다.
no-referrer로 보낸 요청은 처음부터 리퍼러가no-referrer입니다. 리다이렉트 응답이Referrer-Policy: unsafe-url을 내려 줘도Referer는 생기지 않습니다.- 첫 단계에서 출처만 남았다면 경로와 쿼리는 이미 사라졌습니다. 이후 단계의 정책이 느슨해져도 보낼 수 있는 것은 그 출처까지입니다.
- 첫 단계에서 전체 URL이 남았다면, 예를 들어
strict-origin-when-cross-origin에서 같은 출처로 간 요청이라면, 리다이렉트 응답이unsafe-url을 지정하면서 다른 출처로 보낼 때 그 전체 URL이 다른 출처로 갑니다. 명세 10.2절은 더 느슨한 정책으로 바꾸는 것을 금지하지 않는다고 밝힙니다.
반대로 단축 URL이나 로그인 중계처럼 리다이렉트를 내 서버가 돌려준다면, 그 응답에 엄격한 정책을 붙여 다음 요청에 실리는 값을 줄일 수 있습니다. 리다이렉트 상태 코드 자체는 HTTP 리다이렉트 글에서 다뤘습니다.
Origin 헤더에도 영향이 있다
Referrer-Policy는 Referer만 바꾸지 않습니다. Fetch 표준 3.2절의 “append a request Origin header” 알고리즘은 요청을 다음 순서로 확인합니다.
- 요청의 response tainting이
cors이거나 모드가websocket또는webtransport이면 출처를 그대로 붙이고, 정책은 보지 않습니다. main fetch는cors모드로 다른 출처에 보내는 요청, 예를 들어 다른 출처로 가는fetch()의 response tainting을cors로 둡니다. - 그 밖의 요청 중
GET이나HEAD에는 이 알고리즘이Origin을 붙이지 않습니다. - 그 밖의 요청이라도 모드가
cors이면 정책을 보지 않고 출처를 그대로 붙입니다. 같은 출처로 보내는fetch()POST가 여기에 해당합니다.fetch()의 기본 모드는cors이고, 같은 출처 요청의 response tainting은basic으로 남기 때문입니다. - 나머지 요청, 예를 들어
navigate나no-cors모드인 요청은 정책에 따라Origin이null이 됩니다.no-referrer: 항상nullno-referrer-when-downgrade,strict-origin,strict-origin-when-cross-origin: HTTPS 출처에서 HTTPS가 아닌 URL로 갈 때nullsame-origin: 다른 출처로 갈 때null
서버가 CSRF 방어로 Origin 값을 확인하고 있다면, 사이트 전체에 no-referrer를 걸었을 때 GET도 HEAD도 아니면서 이미 navigate 모드인 요청은 4단계의 정책 분기에 이르고, no-referrer에서 그 분기는 Origin을 null로 둡니다. 같은 정책에서도 같은 출처 fetch() POST는 실제 출처를 그대로 보냅니다. 이 알고리즘의 노트는 CORS 프로토콜처럼 출처 공유를 명시적으로 선택하지 않은 모든 요청에서 리퍼러 정책을 고려한다고 설명합니다. CORS 요청과 Origin의 관계는 CORS preflight 글에 정리했습니다.
기본값은 어디서 오나
정책을 아무 데서도 정하지 않으면 브라우저 기본값이 쓰입니다. 그런데 이 기본값은 확인할 문서가 바뀌었습니다.
https://www.w3.org/TR/referrer-policy/에 있는 W3C 문서는 2017년 1월 26일자 Candidate Recommendation입니다. 이 판은 빈 정책을no-referrer-when-downgrade로 처리한다고 적고 있습니다.- 2026년 10월 6일자 Fetch 표준은 빈 정책을 HTML 표준의 policy container 값으로 채우고, Referrer Policy 참조로는
https://w3c.github.io/webappsec-referrer-policy/를 가리킵니다.
즉 지금 Fetch가 따르는 기본값은 2017년 판이 아니라 HTML 표준과 Fetch가 가리키는 판 쪽에서 정해집니다. 그래서 이 글은 2017년 판의 기본값을 지금 브라우저의 동작으로 소개하지 않습니다. 실무에서 할 일은 단순합니다. 기본값에 기대지 말고 응답 헤더로 정책을 명시하면 됩니다. motitory.com은 public/_headers에서 모든 정적 응답에 Referrer-Policy: strict-origin-when-cross-origin을 붙이고 있습니다.
값을 고를 때는 다음 기준으로 판단할 수 있습니다.
- URL에 토큰이나 개인 식별 정보가 들어가는 페이지라면
no-referrer나same-origin을 씁니다. 같은 사이트 안의 분석이 필요하면same-origin이 맞습니다. - 일반 페이지라면
strict-origin-when-cross-origin이 무난합니다. 같은 출처에는 전체 URL을 주고, 다른 출처에는 출처만, HTTP로는 아무것도 주지 않습니다. unsafe-url,origin,origin-when-cross-origin은 HTTPS 페이지의 정보가 HTTP 요청에 실릴 수 있으니 이유가 분명할 때만 씁니다.
정책이 막지 못하는 것
- Referrer-Policy는 보내는 쪽의 약속입니다. Referrer Policy 9.1절은 사용자 에이전트가 사용자에게 리퍼러를 끄는 옵션을 줄 수 있다고 하고, Fetch 표준도 같은 내용을 노트로 적고 있습니다. RFC 9110은 리퍼러를 무조건 지우는 중간 장비가 있다고 적습니다. 그러니 서버는
Referer가 없거나 줄어든 요청도 처리할 수 있어야 하고, 접근 제어를Referer에 맡겨서는 안 됩니다. RFC 9110도 모든 요청에 이 헤더가 있지는 않다고 적고 있습니다. - 명세 1.2절은 capability URL이 리퍼러 말고도 다른 경로로 샐 수 있고, 리퍼러 통제만으로는 그 경로를 다 막지 못한다고 적습니다. RFC 9110 17.9절은 민감한 값을 애초에 URI에 넣지 않는 방법을 권합니다. 폼에서 POST를 쓰거나, URI를 만들기 전에 값을 변환하거나, 서버가 만든 다른 URI로 리다이렉트하는 방법입니다.
참고한 문서
- W3C Referrer Policy (Candidate Recommendation, 2017-01-26): 1.2, 2, 3
3.9, 4, 4.1, 4.4, 6, 8.18.4, 9.1, 10.1, 10.2, 11.1절 - WHATWG Fetch Standard (Living Standard, 2026-10-06 판): 2.2.5 Requests, 3.2
Originheader, 4.1 Main fetch, 4.5 HTTP-redirect fetch, 4.6 HTTP-network-or-cache fetch, 5.4 Request class - RFC 9110 HTTP Semantics: 10.1.3 Referer, 17.9 Disclosure of Sensitive Information in URIs
2026년 10월 18일에 링크와 내용을 확인했습니다. Fetch 표준은 계속 바뀌는 문서이므로 위 내용은 이날 받은 판을 기준으로 합니다.