다음은 Sec-Fetch-Dest / Sec-Fetch-Mode / Sec-Fetch-Site 헤더에 대한 정리입니다.
이들은 Fetch Metadata Request Headers로,
브라우저가 서버에게 “이 요청이 어떤 맥락에서 발생했는지”를 알려 웹 보안(특히 CSRF, XS-Leaks 등)을 강화하기 위한 목적을 갖습니다.
🔒 Fetch Metadata Request Headers 설명
1) Sec-Fetch-Dest
요청의 목적지 리소스 유형(destination) 을 나타냅니다.
브라우저가 어떤 리소스를 가져오려는지 서버에 알려주는 값입니다.
📌 주요 값들
| 값 | 의미 |
| document | 문서 전체(탭 로드 등) |
| iframe | iframe 로드 |
| script | JS 파일 요청 |
| style | CSS 파일 요청 |
| image | 이미지 요청 |
| font | 폰트 요청 |
| fetch | fetch() 또는 XHR 요청 |
| empty | 목적지를 특정할 수 없음(예: <a href>, <form>) |
2) Sec-Fetch-Mode
요청의 모드(fetch mode) 를 나타냅니다.
이는 Fetch API의 mode와 거의 동일합니다.
📌 주요 값들
| 값 | 의미 | |
| cors | cors 규칙 허용 | CORS 규칙에 따라 요청 |
| no-cors | cors 규칙 비허용 | CORS 규칙에 따라 요청하지않고, 응답 읽지 못하는 제한된 요청 |
| same-origin | 동일 출처 요청 | 출처가 같아야만 요청 가능 same-origin / cross-origin same-site / cross-site |
| navigate | 페이지 이동 / 문서 이동 요청 | 문서 이동 |
| websocket | WebSocket 연결 |
*SOP(Same-Origin-Policy)
*CORS(Cross-Origin-Resource-Sharing): 교차 출처 요청 허용하기 위한 정책 메커니즘 (Origin 헤더, preflight)
*origin = scheme://host(subdomain.SLD.TLD):port
*site = eTLD+1
Q. CORS ≠ cross-origin
CORS라는 용어가 가진 태생적 혼란 때문에 생기는 부분입니다. 하나씩 아주 명확하게 정리해볼게요.
1. CORS는 무엇의 약자인가?
CORS = Cross-Origin Resource Sharing
즉, 교차 출처 리소스 공유.
중요한 포인트:
CORS는 “교차 출처 요청”을 뜻하는 것이 아니라,
“교차 출처 요청을 허용하기 위한 정책 메커니즘”을 말한다.
따라서 mode: "cors"는 교차 출처 요청이 아니라
CORS 정책 검사가 적용되는 요청을 의미한다.
2. mode: cors면 “다른 출처 요청”이 맞지 않나요?
정확히 말하면 그렇지 않다.
🔍 mode: "cors"는 “교차 출처 요청을 CORS 규칙에 따라 처리하는 모드”
- 실제로는 same-origin 에도 사용할 수 있다.
- fetch() 기본값이 mode: "cors"이기 때문에, same-origin 호출에도 쓰인다.
예:
fetch("/api/users")
// 같은 origin인에도 mode는 cors
즉, mode: cors는:
다른 출처 요청이라서cors인 것이 아니라,- 브라우저가 CORS 규칙(Origin 헤더, preflight 등)을 적용하는 방식이다.
3. 그렇다면 no-cors는 왜 “same-origin”이 아닌가?
no-cors는 “보안적으로 제한된 상태에서의 요청 모드”다 = CORS 규칙 허용X = Origin 헤더X = preflight X
동일 출처일 수도 / 타 출처일 수도 있다.
no-cors는 “브라우저가 교차 출처 요청을 허용하긴 하지만,
JavaScript에서는 응답 내용을 읽을 수 없도록 강하게 제한한 모드”.
예:
fetch("https://example.com/image.ping", { mode: "no-cors" })
동일 출처라도 다음을 둘 다 가능:
- same-origin
- cross-origin
따라서 no-cors ≠ same-origin이다.
🔥 핵심 요약
- same-origin: 요청이 어디로 가는 출처 관계
- cors/no-cors: 브라우저가 요청을 어떤 규칙으로 처리할지
이 둘은 개념이 완전히 다르다.
4. 그러면 왜 same-origin이라는 별도 용어가 있나?
Sec-Fetch-Site / fetch() / SOP 같은 브라우저 보안 모델에서는
“요청이 어디로 향하는가(출처 비교)”가 중요하기 때문.
- same-origin
- same-site
- cross-site
- cross-origin (same-site보다 더 넓은 개념)
즉, 출처 정보와 ≠ 보안 모드(mode)는 서로 다른 Layer짜리 정보이다.
5. “다른 출처 요청이라면 cors가 아니라 cross-origin이 더 일관적이지 않나?”
개념적으로는 맞는 지적! 하지만 역사적 사정이 있다.
역사적 이유
- 원래 웹은 “Same-Origin Policy(SOP)”만 있었다.
- 교차 출처 요청을 허용하기 위해 나온 새로운 사양 이름이
Cross-Origin Resource Sharing (CORS). - fetch()와 브라우저 API가 만들어질 때
CORS가기능 이름이 아니라 “모드 이름”이 되어버렸다.
즉,
- cross-origin은 출처 관계
- cors는 처리 방식
을 의미한다는 구분이 생겼다.
반면 mode: "cross-origin" 같은 값은 존재하지 않는다.
(늦게 추가하기엔 생태계 호환 문제가 너무 크기 때문)
🔥 완전 요약 (매우 중요)
🔸 출처 관계(Origin Relationship)
- origin = scheme://host(subdomain.SLD.TLD):port ≠ path, query
- site = eTLD+1 (effective Top-Level-Domain)
| 용어 | 뜻 | URL A | URL B |
| same-origin | 같은 origin | https://example.com/app https://example.com https://localhost:3000/a |
https://example.com/api https://example.com:443 https://localhost:3000/b |
| cross-origin | 다른 origin | https://example.com https://example.com https://example.com http://localhost:3000 |
https://api.example.com http://example.com https://example.org http://localhost:4000 |
| same-site | 같은 site + 다른 origin | https://example.com https://a.example.com http://example.com https://example.com:443 |
https://sub.example.com https://b.example.com https//example.com https://example.com:8080 |
| cross-site | 다른 site + 다른 origin | https://example.com https://app.service.com http://foo.shop.co.kr https://example.com |
https://google.com https://cdn.other.net http://bar.news.co.kr https://example.co.uk |
🔸 Fetch Mode (브라우저 처리 방식)
- cors: CORS 규칙에 따라 요청
- no-cors: 응답을 읽지 못하는 제한된 요청
- same-origin: 출처가 같아야만 요청 가능
- navigate: 문서 이동
→ 이름이 비슷해 보여서 헷갈리는데, 서로 완전히 다른 차원이다.
더 알고 싶으면?
원하면 다음도 설명해줄게:
- SOP(동일 출처 정책) 체계도
- CORS preflight가 발생하는 조건
- Sec-Fetch-Site / Sec-Fetch-Mode와 CORS의 관계
- fetch() mode별 실제 예시 비교
원하는 내용 있어?
Q. domain(host) 구성 요소
도메인 이름 구조는 계층(hierarchy) 으로 이루어져 있으며, 각 구성 요소는 국제적으로 정해진 용어와 약어가 있습니다. 아래에 가장 정확하고 통용되는 표현을 정리했습니다.
🌐 도메인(host) 구성 요소
도메인은 일반적으로 아래 순서(좌→우)로 구성됩니다:
Subdomain.SLD.TLD
이 구성 요소들이 가진 정확한 영어 명칭 / 약어는 다음과 같습니다:
1) TLD (Top-Level Domain)
.com,
.org,
.kr,
.co.uk
- 맨 오른쪽에 있는 최상위 도메인
- 도메인 계층의 “최상위 레벨”
- 종류: gTLD(.com), ccTLD(.kr), sTLD(.edu) 등
2) SLD (Second-Level Domain)
example.com
- TLD 바로 왼쪽에 있는 도메인
- “도메인의 고유 이름”을 의미하는 경우가 많음 (organization/site의 이름)
3) Subdomain (서브도메인)
예:
www.example.com → www
api.example.com → api
beta.api.dev.example.com
- SLD 왼쪽에 위치한 모든 추가 레이블
- 여러 단계(sub-subdomain 등)도 가능함
Subdomain은 약어로 subdomain이라고 하며 일반적으로 SLD처럼
고정된 약어(SLD, TLD)처럼 줄여 쓰지 않는다.
🌟 도메인 전체 구조 요약
| 부분 | 예 | 영어 명칭 | 약어 |
| .com | 최상위 도메인 | Top-Level Domain | TLD |
| example | 기관/사이트명 | Second-Level Domain | SLD |
| www | 서브도메인 | Subdomain | (약어 없음) |
| www.example.com | 전체 도메인 | Fully Qualified Domain Name | FQDN |
🌐 추가로 자주 쓰는 전문 용어
■ eTLD
Effective Top-Level Domain
.co.uk
.go.kr
즉, 실제 “사이트를 구분하는 최상위 도메인 조합”
■ eTLD+1
사이트의 고유 식별자 역할을 하는 도메인
예:
- google.co.uk의 eTLD+1 = google.co.uk
- naver.com의 eTLD+1 = naver.com
SameSite 쿠키·Sec-Fetch-Site 계산 등이 이걸 기반으로 한다.
🔎 전체 계층 구조 예시
도메인:
api.v1.shop.example.co.uk
| 레이블 | 의미 |
| uk | TLD |
| co.uk | eTLD |
| example | SLD |
| shop | subdomain |
| v1 | subdomain |
| api | subdomain |
| 전체 | FQDN (Fully Qualified Domain Name) |
필요하다면:
- eTLD/eTLD+1을 어떻게 계산하는지
- SameSite/Sec-Fetch-Site가 이 구조를 어떻게 사용하는지
- 도메인과 호스트(host)의 차이
도 설명해줄게!
Q. TLD vs eTLD+1
“왜 .co.uk, .go.kr 등이 eTLD고, 왜 TLD라고 부르지 않나?”
이 질문을 이해하면 SameSite, 쿠키, 사이트 경계 정의가 완전히 명확해진다.
아래에서 혼란의 근본 원인을 깔끔히 설명해줄게.
🔥 먼저 결론부터
✔ TLD와 eTLD는 ‘완전히 다른 개념’이다.
TLD (Top-Level Domain) = DNS 계층 구조의 최상위 도메인
- .com
- .org
- .kr (co.kr / go.kr)
- .uk (co.uk)
- .gov
- .edu
- .jp
국제 DNS 규격상 맨 마지막 레이블 1개만 가능
즉, TLD는 항상 단일 레이블이다.
✔ eTLD(Effective Top-Level Domain)는 DNS 기준이 아니라 “웹 보안 정책을 위해 정의된 개념”
웹 브라우저가 “사이트 경계를 어디까지로 볼 것인가?”
이를 위해 사용하는 추가 개념이다.
예시:
| 도메인 | TLD (DNS 기준) | eTLD (보안 정책 기준) |
| example.com | .com | .com |
| example.co.uk | .uk | .co.uk |
| example.go.kr | .kr | .go.kr |
즉,
- DNS 기준 → .uk이 TLD
- 보안 정책 기준 → .co.uk가 eTLD
왜 이런 차이가 생길까?
🔥 왜 eTLD가 존재해야 할까?
이유: 일부 국가에서는 Second-level domain(SLD)을 공유 네임스페이스로 운영하기 때문
예:
영국(UK)
| .co.uk | 기업용 |
| .org.uk | 비영리 |
| .ac.uk | 교육기관 |
| .gov.uk | 정부기관 |
이들은 사실상 TLD처럼 동작한다.
예를 들어:
foo.co.uk
bar.co.uk
이 둘은 실제로:
- 서로 완전히 다른 사이트이고
- 서로 무관한 소유자
- 서로의 쿠키가 절대 공유되면 안 됨
그런데 DNS 기준으로는 둘 다 “same-site”로 판단해버릴 수도 있다.
왜?
TLD가 .uk라서 SLD는 co가 되어버림.
그러면 아래 문제가 생긴다:
foo.co.uk의 쿠키가 bar.co.uk에 자동으로 전송된다
→ 대참사(CSRF, 세션 공유, 보안 붕괴)
그래서 브라우저는 “이건 실제 TLD라고 취급해야 한다”
하고 .co.uk 전체를 effective TLD(eTLD) 로 본다.
🔥 eTLD+1(사이트 도메인)이란?
사이트를 구분하기 위한 브라우저의 공식 단위
= eTLD + 그 왼쪽 레이블 1개(SLD)
= SLD.eTLD
예:
| 전체 도메인 | eTLD | eTLD+1 (사이트 도메인) |
| maps.google.com | .com | google.com |
| sub.shop.naver.com | .com | naver.com |
| test.service.co.uk | .co.uk | service.co.uk |
| gov.department.go.kr | .go.kr | department.go.kr |
즉,
웹 브라우저는 eTLD+1을 “하나의 사이트”로 취급한다.
SameSite 쿠키, Sec-Fetch-Site, Storage Partitioning 모두 이 단위를 사용한다.
🔥 왜 eTLD와 TLD를 섞어 부를 수 없는가?
DNS 규격은 “단일 TLD”를 정의한다.
하지만 웹 보안은 “실제로 사이트 경계를 어떻게 설정해야 안전한가?”를 고민한다.
그래서 둘의 목적이 다르다:
| 개념 | 사용하는 곳 | 목적 |
| TLD | DNS | 인터넷 도메인 이름 체계 |
| eTLD | 브라우저(Web security, 웹 보안) | 쿠키/보안 경계 정의 |
TLD는 기술적 계층.
eTLD는 보안적 약속.
그래서 .co.uk를 TLD라고 부르는 것은 DNS 규격상 틀린 표현이다.
🔥 아주 직관적인 핵심 정리
✔ TLD = 도메인의 “맨 마지막 레이블”
→ DNS 규칙
✔ eTLD = “그 나라/기관이 사실상 TLD처럼 쓰는 영역까지 포함”
→ 웹 브라우저의 보안 규칙
✔ eTLD+1 = 사이트 소유자마다 다른 “실제 사이트 단위”
→ SameSite 쿠키 / Sec-Fetch-Site가 이걸 기반으로 동작
필요하면 더 알려줄게:
- Public Suffix List(PSL)가 어떻게 eTLD를 결정하는지
- 왜 *.github.io도 eTLD인지
- 실제 브라우저가 cross-site를 판단하는 알고리즘
어떤 걸 더 궁금해?
Q. eTLD+1 vs SLD.eTLD
아주 좋은 질문이고, 많은 개발자들이 처음에 똑같이 헷갈리는 지점이야.
왜 굳이 eTLD / eTLD+1 같은 이상한 용어를 쓰는지,
그리고 왜 “SLD.eTLD”라고 부르지 않는지까지 차근차근 명확하게 정리해줄게.
✔ 먼저 결론을 빠르게 요약하면
1) eTLD = Effective TLD = ‘실질적 최상위 도메인’
공식 TLD 보다는 더 넓고 복잡한 개념이다.
예:
- .com → TLD = eTLD
- .co.uk → TLD는 .uk / 사이트 구분은 .co.uk까지 필요함 → eTLD
- .go.kr → TLD는 .kr이지만 eTLD는 .go.kr
즉,
eTLD는 “사이트 구분 시 실제로 최상위로 취급해야 하는 단위”를 의미하며,
공식 TLD(“.com”, “.kr”)와 다를 수 있다.
2) eTLD+1 = ‘사이트 도메인(site domain)’
SLD.eTLD 맞다!
그런데 이걸 “SLD.eTLD”라고 안 부르는 이유가 있음.
3) 왜 SLD.eTLD 대신 eTLD+1을 쓰는가?
SLD라는 개념이 수많은 eTLD 체계에서 통일성 있게 존재하지 않기 때문이다.
SLD는 특정 TLD 체계에서만 의미가 있으며모든 도메인 체계에서 존재하는 개념이 아니다.
➡ 따라서 “eTLD 바로 왼쪽 레이블 1개까지 포함한 것”이라는 규칙이 가장 일관적
→ 그래서 “eTLD+1”이라는 표현이 만들어졌다.
이제 상세하게 설명할게.
1) eTLD는 “공식 TLD”가 아니다
공식적으로 TLD는 아래와 같다:
.com
.net
.kr
.uk
.jp
그런데 현실에서 사이트를 구분할 때는
다음처럼 “두 단계짜리” 또는 “세 단계짜리”가 필요하다:
- .co.uk / co.jp
- .ac.uk
- .go.kr
- .ne.jp
왜냐면:
- .uk, .kr, .jp는 “국가 도메인(ccTLD)”이고
- 그 아래에 등록자(개인/기업)가 직접 등록할 수 없는 중간 도메인들이 존재하기 때문
즉, 등록 가능 도메인(registrable domain) 을 구분해주는 구조가 존재한다.
예를 들어:
| 도메인 | 의미 |
| example.com | 등록 가능 |
| example.co.uk | 등록 가능 |
| example.go.kr | 등록 가능 |
| example.ne.jp | 등록 가능 |
이때 가장 오른쪽부터 “사이트의 경계(boundary)”가 정의된 부분이 바로 eTLD이다.
그러므로:
- .uk 는 TLD (등록 불가)
- .co.uk 는 eTLD (등록 가능 범위 바로 위)
- .go.kr 는 eTLD
- .com 도 eTLD (등록 구조가 단순)
➡ 그래서 TLD ≠ eTLD
➡ eTLD는 “사이트 경계 기준으로 정한 단위”라서 더 복잡함
이 전체 목록은 Public Suffix List(PSL) 이 관리한다.
2) eTLD+1은 “등록 가능한 최상위 도메인” = “사이트 도메인”
eTLD가 “사이트를 구분하는 단위”라면,
**eTLD+1은 “그 위에 붙는 사용자(사이트) 고유 도메인”**을 의미한다.
예:
- 도메인: www.api.google.co.uk
계층:
www.api.google.co.uk
eTLD
this + 1 = "google.co.uk" = eTLD+1
정리:
| FQDN | eTLD | eTLD+1 |
| sub.example.com | .com | example.com |
| a.b.c.naver.co.kr | .co.kr | naver.co.kr |
| foo.bar.amazon.co.jp | .co.jp | amazon.co.jp |
| sub.github.io | .github.io | github.io |
즉,
eTLD+1 = “사이트의 고유 이름이 되는 도메인”
(쿠키 보안, CORS, SameSite 정책, 브라우저 보안 모델 등에서 사이트를 표현하는 단위)
3) 왜 SLD.eTLD라고 안 부르는가?
네가 말한 것처럼:
eTLD+1 = SLD.eTLD 맞지 않나?
그럼 SLD.eTLD라고 표현하면 되잖아?
라고 생각할 수 있다.
하지만 SLD라는 개념 자체가 특정 TLD 체계에서만 의미가 있고, 글로벌하게 일관되지 않기 때문이다.
🔥 SLD가 일관적이지 않은 이유
예를 들어:
예시 1: .co.jp
amazon.co.jp
여기서 co는 SLD가 아니다.
왜냐하면 .co.jp 이 전체가 eTLD이기 때문.
SLD는 amazon이지만
그 아래 .co.jp 는 2단계 TLD처럼 취급된다.
예시 2: .github.io
user.github.io
- io → TLD
- github.io → eTLD
- 여기서는 github가 SLD
하지만 이건 GitHub Pages 규칙 때문에 특별히 eTLD로 지정된 것이다.
(PSL에 등록됨)
예시 3: 일부 국가 도메인은 3단계 구조도 존재
something.city.kawasaki.jp
여기서 eTLD는 .city.kawasaki.jp이고
그 왼쪽 1개(something)가 eTLD+1이다.
이 경우 “SLD”가 뭔가?
SLD 같은 개념 자체가 의미가 없어진다.
그래서 SLD 기반 규칙은 글로벌 웹 전체에서 적용 불가능
반면,
“eTLD 바로 왼쪽 레이블 하나까지 포함하자”
라는 규칙은 전 세계 모든 도메인 체계에서 적용 가능하다.
그래서 항상 정확하게 정의하려고:
- eTLD
- eTLD+1
이라는 표현을 사용하는 것이다.
🔥 요약 (최종 정리)
✔ TLD
공식 최상위 도메인 (.com, .kr, .uk)
✔ eTLD
사이트 경계를 정의하는 “실질적 최상위 도메인”
(Public Suffix List에서 정의)
- .co.uk
- .go.kr
- .github.io
✔ eTLD+1
등록 가능한 사이트 단위 도메인
= eTLD 바로 왼쪽 레이블 포함
= SLD.eTLD처럼 보이지만, SLD라는 개념은 국가·기관 도메인 체계마다 달라 일관되지 않음
그래서 “eTLD+1”이라는 표현이 정확하고 범용적이다.
원하면 더 설명할 수도 있어:
- PSL이 실제로 어떻게 생겼는지
- 브라우저가 eTLD+1을 어떻게 계산하는지
- SameSite 쿠키에서 사이트 판정이 어떻게 이루어지는지
어떤 부분 더 궁금해?
예:
- <img> → no-cors
- fetch(API) → 기본은 cors
3) Sec-Fetch-Site
요청을 보낸 사이트의 출처(origin) 가 서버 도메인과 어떤 관계인지 나타냅니다.
📌 주요 값들
| 값 | 의미 |
| same-origin | 동일 origin |
| same-site | 다른 origin이지만 같은 사이트(eTLD+1) |
| cross-site | 완전히 다른 사이트 |
| none | 브라우저 주소창에 직접 입력 또는 북마크 등 |
예시:
A.com → A.com 요청 → same-origin
A.com → api.A.com → cross-origin & same-site
A.com → B.com → cross-site
🔐 왜 중요한가? (보안)
서버는 이 헤더를 이용해 다음과 같은 보안 규칙을 만들 수 있습니다.
예: CSRF 방지 (Cross-Site Request Forgery)
if (Sec-Fetch-Site !== 'same-origin' && Sec-Fetch-Site !== 'same-site') {
return 403;
}
Sec-Fetch-Site: same-origin 이 아니고 + Sec-Fetch-Site: same-site 가 아닌 경우
Sec-Fetch-Site: cross-origin (scheme://host:port 가 다를 경우) + Sec-Fetch-Site: cross-site 인 경우 (eTLD+1 이 다를 경우)
→ 403 에러 반환 (Forbidden, 접근 권한 없어서 요청 거부)
예: 리소스 오용 방지
if (Sec-Fetch-Dest === 'script' && Sec-Fetch-Site === 'cross-site') {
return 403;
}
📌 실제 브라우저 요청 예시
GET /api/data HTTP/1.1
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
- 리소스: 유형 특정할 수 없음 (<a>, <form>)
- 요청 모드: cors (cors 규칙에 따라 요청)
- 요청 출처 & 서버 관계: origin이 같음
필요하면 더 알려줄게요!
- 전체 Fetch Metadata 헤더 목록(Sec-Fetch-User, Sec-Fetch-Integrity 등)
- 각 헤더별 서버 방어 전략(Nginx/Express/Spring 설정 예제)
- 브라우저별 지원 정보
원하는 방향으로 더 설명해줄까요?
'개발자도구' 카테고리의 다른 글
| data-* 속성 (0) | 2025.12.24 |
|---|---|
| 요청 헤더 Accept-Encoding & 응답 헤더 Vary: Accept-Encoding 헤더 (0) | 2025.12.15 |
| melonweb_cmtpgn_tunnel2.html & melonlib.min.js (0) | 2025.12.02 |
| document.domain mutation is ignored because the surrounding agent cluster is origin-keyed (0) | 2025.12.01 |
| 403 vs 401 에러 코드 (0) | 2025.12.01 |
| URL path가 폴더명처럼 보일 때, 폴더 전체를 불러오는 것일까? & md(markdown) 파일 렌더링 방식 (0) | 2025.12.01 |
| https://global.apis.naver.com 은 어떤 도메인? 엔드포인트 & 게이트웨이 & CORS (0) | 2025.11.24 |
| https://pagead2.googlesyndication.com 는 무슨 도메인? (0) | 2025.11.23 |