쿠키
쿠키는 서버가 브라우저에 맡겨 두는 짧은 이름과 값입니다. 브라우저는 다음 요청부터 그 값을 다시 실어 보냅니다. 서버는 그 값을 보고 앞선 요청과 이어진 요청이라는 것을 압니다. 무엇을 담고 어떻게 읽을지는 서버가 정합니다.
쉽고 빠른 이해
쿠키는 서버가 브라우저에 값을 하나 맡겨 두고, 브라우저가 다음 요청마다 그 값을 다시 실어 보내게 하는 장치입니다. 예를 들어 서버가 로그인 세션 식별자를 값으로 내려주면, 브라우저는 이후 요청마다 그 식별자를 함께 보냅니다.
요청은 원래 서로 이어지지 않습니다. 지금 온 요청이 방금 전 요청과 같은 사람인지 서버가 알 방법이 없으면 로그인 상태를 유지할 수 없습니다. 쿠키는 그 이음매를 브라우저 쪽에 맡겨 해결합니다.
작동 방식은 대략 이렇습니다.
- 서버가 응답에 이름과 값을 실어 보냅니다.
- 브라우저가 그 값을 저장해 둡니다.
- 다음 요청부터 브라우저가 저장해 둔 값을 다시 실어 보냅니다.
대가도 있습니다. 브라우저는 저장소가 꽉 차거나 사용자가 지우라고 하면 쿠키를 언제든 밀어낼 수 있고, 받은 쿠키를 통째로 무시할 수도 있습니다. 그래서 서버는 쿠키가 안 돌아와도 동작이 망가지지 않게 만드는 것이 좋습니다.
상세
RFC(Request for Comments) 6265 는 HTTP(HyperText Transfer Protocol) 의 Cookie 헤더 필드와 Set-Cookie 헤더 필드를 정의합니다. 이 두 필드로 HTTP 서버는 HTTP 사용자 에이전트에 상태를 저장할 수 있습니다. 웹 브라우저가 사용자 에이전트의 대표적인 예입니다 — 앞서 개요가 쓴 "브라우저"와 같은 것을 가리키며, 이 문서는 이제부터 명세 표기인 "사용자 에이전트"를 씁니다. 그렇게 저장되는 것을 쿠키라고 부릅니다. 대체로 상태가 없는 HTTP 위에서 서버가 상태 있는 세션을 유지하게 해 주는 장치입니다. 로그인한 사용자를 요청마다 알아보는 로그인 상태 유지가 흔한 예입니다.
방향이 둘로 갈립니다. 서버는 Set-Cookie 응답 헤더로 이름과 값의 쌍, 그리고 거기 딸린 메타데이터를 사용자 에이전트에 건넵니다. 사용자 에이전트는 이후 요청을 만들 때 그 메타데이터와 다른 정보를 써서 그 쌍을 Cookie 헤더에 돌려줄지 판단합니다.
쿠키 하나는 이름과 값의 쌍으로 시작합니다. 그 뒤에 속성과 값의 쌍이 0개 이상 붙습니다. 서버는
§4.1.1 의 문법에 맞지 않는 Set-Cookie 헤더를 보내지 않는 것이 좋습니다(SHOULD NOT). 앞서 말한
이름·값 뒤에 속성이 붙는 Set-Cookie 문법과 달리, 돌아오는 쪽 문법은 더 짧습니다. 아래는 그
문법을 ABNF(Augmented Backus-Naur Form, 확장 배커스-나우어 표기법)로 적은 것입니다.
OWS(Optional White Space, 있어도 되고 없어도 되는 공백)·SP(Space, 공백 문자 하나)·*( )(그
안의 조각이 0번 이상 반복될 수 있다는 표시)가 그 안에 나옵니다. cookie-pair 는 앞서 말한
이름과 값의 쌍을 가리키는 이 문법의 이름입니다.
cookie-header = "Cookie:" OWS cookie-string OWS
cookie-string = cookie-pair *( ";" SP cookie-pair )
flowchart TD
H["cookie-header"] --> T["Cookie: 리터럴 + OWS"]
H --> S["cookie-string"]
S --> P1["cookie-pair"]
S --> P2["세미콜론과 SP 로 구분해 0개 이상 더 붙는 cookie-pair"]
cookie-header 는 "Cookie:" 리터럴과 앞뒤 OWS 사이에 cookie-string 하나를 끼운 것이고, cookie-string 은 cookie-pair 가 세미콜론과 공백으로 구분되며 0개 이상 이어지는 것입니다.
돌아올 때 속성은 딸려 오지 않습니다. §4.2.2 는 서버가 Cookie 헤더만 보고는 쿠키가 언제 만료되는지, 어느 호스트와 어느 경로에서 유효한지, Secure 나 HttpOnly 로 설정됐는지를 알 수 없다고 적습니다(Secure 와 HttpOnly 가 무엇을 하는 속성인지는 뒤 "갈래"에서 다룹니다). 개별 쿠키의 뜻도 이 문서가 정하지 않습니다. 서버가 애플리케이션마다 의미를 불어넣을 것으로 기대합니다. 실린 순서에도 기대면 안 됩니다. 같은 이름의 쿠키가 둘 실릴 수 있어서, 서버는 Cookie 헤더에 나타나는 순서에 기대지 않는 것이 좋습니다(SHOULD NOT).
저장하는 쪽은 사용자 에이전트입니다. §5.3 저장 모델은 쿠키마다 아래 항목을 보관한다고 적습니다.
name · value · expiry-time · domain · path · creation-time · last-access-time
persistent-flag · host-only-flag · secure-only-flag · http-only-flag
name·value 는 앞서 말한 이름과 값이고, domain·path 는 범위를 정하는 두 속성의 값입니다. expiry-time 은 쿠키가 만료되는 시각이고, creation-time 과 last-access-time 은 사용자 에이전트가 그 쿠키를 만든 시각과 마지막으로 쓴 시각입니다 — 셋 다 서버가 정하는 것이 아니라 사용자 에이전트가 기록합니다. persistent-flag·host-only-flag·secure-only-flag·http-only-flag 넷은 각각 뒤 "갈래"에서 다루는 지속 쿠키·호스트 전용 쿠키·Secure·HttpOnly 를 적용한 결과입니다.
받은 쿠키를 통째로 무시해도 됩니다(MAY). 문서는 "서드파티" 응답에서 오는 쿠키를 막고 싶은 경우와 어떤 크기를 넘는 쿠키를 저장하고 싶지 않은 경우를 예로 듭니다 — "서드파티"가 정확히 무엇을 가리키는지는 이 문서도 따옴표만 치고 더 정하지 않습니다.
같은 이름·도메인·경로의 쿠키를 새로 받으면 기존 쿠키는 쫓겨나고 새 쿠키가 그 자리에 들어갑니다. 속성이 달리 지시하지 않으면 쿠키는 오리진 서버(요청받은 자원을 실제로 가진 서버입니다. 중간의 프록시나 캐시가 아닙니다)에만 돌아가고 현재 세션이 끝날 때 만료됩니다. 여기서 세션은 사용자 에이전트가 떠 있는 동안, 이를테면 브라우저 창이 열려 있는 동안을 뜻합니다 — 앞서 말한, 서버가 유지하는 로그인 상태 같은 세션과는 다른 뜻입니다. 현재 세션이 언제 끝나는지는 사용자 에이전트가 정합니다. 알아보지 못한 속성은 무시합니다. 그렇다고 쿠키 전체를 버리지는 않습니다. 이 문단의 근거인 §4.1.2 는 제목이 "Semantics (Non-Normative)" 입니다. 규범이 아니라 흔한 쓰임을 이해하기 좋게 간추린 절이고, 온전한 의미론은 §5 에 있습니다.
출처 문서
정본은 RFC 6265 입니다. 제목은 HTTP State Management Mechanism 이고 2011년 4월에 나왔습니다. 지은이는 A. Barth 이고 소속은 U.C. Berkeley 로 적혀 있습니다. Category 는 Standards Track 이고 ISSN(International Standard Serial Number, 국제 표준 연속 간행물 번호)은 2070-1721 입니다. RFC 2965 를 폐기했습니다. IETF(Internet Engineering Task Force) 가 낸 문서이고 IETF 커뮤니티의 합의를 나타냅니다. 공개 검토를 거쳐 Internet Engineering Steering Group 의 발행 승인을 받았습니다. RFC Editor 의 정보 페이지는 상태를 Proposed Standard 로 적습니다. 그 페이지에 이 문서를 갱신한 다른 RFC 는 적혀 있지 않습니다.
요구 강도는 서버 쪽과 사용자 에이전트 쪽이 갈립니다. §1 은 이 명세의 독자가 둘이라고 적습니다. 쿠키를 만들어 내보내는 서버 개발자, 그리고 쿠키를 받아 쓰는 사용자 에이전트 개발자입니다. 서버는 §4 의 잘 처신하는 프로파일(§4 가 통째로 정하는, Cookie·Set-Cookie 의 문법과 의미론 규칙을 말합니다) 안에 머무는 쪽이고, 사용자 에이전트는 §5 의 더 너그러운 처리 규칙을 구현하는 쪽입니다. 후자가 요구가 셉니다. §4 를 안 지키는 기존 서버들과 상호운용해야 하기 때문입니다.
절 번호와 요구 강도
| 자리 | 절 | 문서가 쓴 요구 강도 |
|---|---|---|
| 서버의 프로파일 | 1 | 사용자 에이전트와의 상호운용을 최대로 하려면 서버는 §4 의 잘 처신하는 프로파일로 스스로를 한정하는 것이 좋습니다(SHOULD) |
| 사용자 에이전트의 처리 규칙 | 1 | 사용자 에이전트는 §5 의 더 너그러운 처리 규칙을 구현해야 합니다(MUST) |
| Set-Cookie 문법 | 4.1.1 | 서버는 문법에 맞지 않는 Set-Cookie 헤더를 보내지 않는 것이 좋습니다(SHOULD NOT) |
| Set-Cookie 를 실을 응답 | 3 | 오리진 서버는 어떤 응답에든 Set-Cookie 응답 헤더를 실어도 됩니다(MAY) |
| 100 번대 응답 | 3 | 사용자 에이전트는 100 번대 상태 코드 응답에 실린 Set-Cookie 를 무시해도 됩니다(MAY) |
| 그 밖의 응답 | 3 | 400 번대·500 번대를 포함한 다른 응답의 Set-Cookie 는 처리해야 합니다(MUST) |
| 헤더 접기 | 3 | 오리진 서버는 여러 Set-Cookie 필드를 한 필드로 접지 않는 것이 좋습니다(SHOULD NOT) |
| Cookie 헤더의 순서 | 4.2.2 | 서버는 직렬화 순서에 기대지 않는 것이 좋습니다(SHOULD NOT) |
| 받은 쿠키 | 5.3 | 사용자 에이전트는 받은 쿠키를 통째로 무시해도 됩니다(MAY) |
| 저장 능력의 최소치 | 6.1 | 일반 용도의 사용자 에이전트는 쿠키당 최소 4096바이트 · 도메인당 최소 50개 · 총 최소 3000개를 제공하는 것이 좋습니다(SHOULD) |
| 쿠키의 개수와 크기 | 6.1 | 서버는 되도록 적고 되도록 작은 쿠키를 쓰는 것이 좋습니다(SHOULD) |
| 쿠키가 안 돌아올 때 | 6.1 | 서버는 사용자 에이전트가 쿠키를 돌려주지 못해도 우아하게 저하하는 것이 좋습니다(SHOULD) — 쿠키 없이도 동작이 깨지지 않아야 한다는 뜻입니다 |
저장 용량의 최소치는 §6.1 이 적습니다. 실제 사용자 에이전트 구현에는 저장할 수 있는 쿠키의 개수와 크기에 한계가 있다는 것이 출발점입니다. 그래서 일반 용도의 사용자 에이전트가 갖출 최소 능력 셋을 겁니다. 쿠키 하나에 4096바이트, 도메인 하나에 50개, 전부 합쳐 3000개입니다. 4096바이트는 이름과 값과 속성의 길이를 더해서 잽니다. 상한이 아니라 하한입니다.
서버 쪽에도 같은 강도의 권고가 둘 붙습니다. 하나는 쿠키를 되도록 적게 그리고 작게 쓰라는 것입니다. 이유가 둘 적혀 있습니다. 이 구현 한계에 닿지 않기 위해서입니다. 그리고 Cookie 헤더가 모든 요청에 실리는 데서 오는 네트워크 대역폭을 줄이기 위해서입니다. 다른 하나는 사용자 에이전트가 Cookie 헤더에 쿠키를 하나 이상 돌려주지 못해도 우아하게 저하하라는 것입니다 — 쿠키가 없어도 서버 동작이 깨지지 않고 이어져야 한다는 뜻입니다. 사용자의 지시에 따라 사용자 에이전트가 언제든 어떤 쿠키든 축출(앞서 말한, 쿠키가 쫓겨나는 것과 같은 일입니다)할 수 있기 때문입니다.
§3 은 두 가지를 더 분명히 합니다. 하나는 Cookie 나 Set-Cookie 헤더 필드가 있다고 해서 HTTP
캐시가 그 응답을 저장하고 재사용하는 것이 막히지는 않는다는 것입니다. 다른 하나는 헤더 접기를
말리는 이유입니다. RFC 2616 이 정의한 통상의 헤더 접기 방식은 여러 Set-Cookie 필드를 쉼표로
이어붙입니다. 그런데 쿠키 속성 값에도 쉼표가 들어갈 수 있습니다 — 만료 날짜를 적는 Expires
속성은 Wed, 09 Jun 2021 10:18:14 GMT 처럼 쉼표가 든 날짜 형식을 씁니다. ABNF 가
%x2C(",") 로 적는 이 쉼표와 헤더를 접는 쉼표가 뒤섞이면서 Set-Cookie 필드의 의미가 바뀔 수
있습니다.
폐기 관계
머리말이 Obsoletes: 2965 로 적습니다. §1 은 IETF 에 세 가지 조치를 요청합니다. RFC 2109 의 상태를 Historic 으로 바꿀 것, RFC 2965 의 상태를 Historic 으로 바꿀 것, 그리고 RFC 2965 가 이 문서로 폐기됐음을 표시할 것입니다. RFC 2109 는 이미 RFC 2965 가 폐기한 상태였습니다. RFC 2965 를 Historic 으로 옮기고 폐기하면서 이 문서는 Cookie2 와 Set-Cookie2 헤더 필드의 사용도 폐기했습니다.
§9 의 IANA(Internet Assigned Numbers Authority) 등록 상태가 그 결과를 그대로 보여 줍니다.
| 헤더 필드 이름 | 상태 | 명세 문서 |
|---|---|---|
| Cookie | standard | 이 명세의 §5.4 |
| Set-Cookie | standard | 이 명세의 §5.2 |
| Cookie2 | obsoleted | RFC 2965 |
| Set-Cookie2 | obsoleted | RFC 2965 |
넷 다 적용 프로토콜은 http 이고 변경 관리자는 IETF 입니다.
명세가 안 정하고 남긴 자리
개별 쿠키의 뜻은 이 문서가 정하지 않습니다. 서버가 애플리케이션마다 의미를 붙일 몫입니다(§4.2.2). Secure 속성이 말하는 "secure" 채널이 무엇인지도 사용자 에이전트가 정합니다(§4.1.2.5). Expires 도 Max-Age 도 없을 때 "현재 세션" 이 언제 끝나는지 역시 사용자 에이전트가 정합니다(§4.1.2.2). 그리고 사용자 에이전트가 지정한 기한까지 쿠키를 들고 있을 의무는 없습니다(§4.1.2.1 · §4.1.2.2).
갱신 중인 판
draft-ietf-httpbis-rfc6265bis 입니다. 지금 판은 22 이고 제목은 Cookies: HTTP State Management Mechanism 입니다. 문서 종류는 httpbis 워킹 그룹의 Active Internet-Draft 입니다. 판은 00 부터 22 까지 나와 있습니다. 계보 그래프에는 이 초안의 전신으로 draft-ietf-httpbis-cookie-alone · draft-ietf-httpbis-cookie-same-site · draft-ietf-httpbis-cookie-prefixes 와 RFC 6265 가 함께 표시됩니다. SameSite 속성과 이름 접두사는 이 초안이 정의합니다. 아직 발행된 RFC 가 아닙니다.
정리하면 문서 사슬은 이렇습니다. RFC 2109 를 RFC 2965 가 폐기했고, RFC 2965 를 RFC 6265 가 폐기했습니다. 그리고 RFC 6265 와 초안 셋(cookie-alone · cookie-same-site · cookie-prefixes)이 함께 지금의 rfc6265bis 초안으로 합류하는 중입니다.
flowchart TD
R2109["RFC 2109"] -- 폐기 --> R2965["RFC 2965"]
R2965 -- 폐기 --> R6265["RFC 6265"]
R6265 -- 합류 --> BIS["draft-ietf-httpbis-rfc6265bis"]
ALONE["draft-ietf-httpbis-cookie-alone"] -- 합류 --> BIS
SAMESITE["draft-ietf-httpbis-cookie-same-site"] -- 합류 --> BIS
PREFIX["draft-ietf-httpbis-cookie-prefixes"] -- 합류 --> BIS
예시
RFC 6265 §3.1 이 든 실제 헤더 줄입니다.
세션 식별자 한 벌
Set-Cookie: SID=31d4d96e407aad42
Cookie: SID=31d4d96e407aad42
서버가 SID(Session ID, 세션 식별자)라는 이름에 31d4d96e407aad42 라는 값을 담아 보냅니다. 문서는 이것을 세션 식별자의 예로 듭니다. 사용자 에이전트는 이후 요청에서 그 식별자를 돌려줍니다.
범위를 넓힌 값
Set-Cookie: SID=31d4d96e407aad42; Path=/; Domain=example.com
Cookie: SID=31d4d96e407aad42
Path 와 Domain 으로 쿠키의 기본 범위를 바꿉니다. example.com 의 모든 경로와 모든 서브도메인으로 가는 요청에 쿠키를 돌려주라는 지시입니다. 돌아오는 Cookie 헤더는 앞의 예와 똑같습니다. 속성은 실리지 않습니다.
두 쿠키와 보호 속성
Set-Cookie: SID=31d4d96e407aad42; Path=/; Secure; HttpOnly
Set-Cookie: lang=en-US; Path=/; Domain=example.com
Cookie: SID=31d4d96e407aad42; lang=en-US
Set-Cookie 필드를 두 개 실어 쿠키 두 개를 저장시킵니다. 세션 식별자와 사용자가 고른 언어입니다. 문서는 더 민감한 세션 식별자 쪽에만 Secure 와 HttpOnly 를 붙여 보안 보호를 더했다고 적습니다. 돌아오는 Cookie 헤더 하나에 SID 와 lang 두 쿠키가 함께 실립니다.
지속시키는 값과 지우는 값
Set-Cookie: lang=en-US; Expires=Wed, 09 Jun 2021 10:18:14 GMT
Cookie: SID=31d4d96e407aad42; lang=en-US
Set-Cookie: lang=; Expires=Sun, 06 Nov 1994 08:49:37 GMT
Cookie: SID=31d4d96e407aad42
위는 여러 세션에 걸쳐 쿠키를 남기려고 Expires 속성에 만료 날짜를 적은 값입니다. 사용자 에이전트가 그 날짜 전에 쿠키를 지울 수도 있습니다. 쿠키 저장소가 할당량을 넘거나 사용자가 직접 지우는 경우입니다. 아래는 쿠키를 없애는 값입니다. 과거의 만료 날짜를 적어 보냅니다. 지우기는 Set-Cookie 헤더의 Path 와 Domain 속성이 쿠키를 만들 때 쓴 값과 맞을 때만 성공합니다.
배경
HTTP 는 대체로 상태가 없습니다. 그 위에서 서버가 상태 있는 세션을 유지하려면 앞선 요청과 지금 요청을 잇는 표시가 있어야 합니다. Set-Cookie 와 Cookie 는 그 표시를 사용자 에이전트에 맡겨 두는 방식입니다. 겉보기에 단순하지만 복잡한 구석이 여럿입니다. 서버는 쿠키를 보낼 때 쿠키마다 범위를 지정합니다. 그 범위는 사용자 에이전트가 쿠키를 얼마나 오래 돌려줘야 하는지, 어느 서버에 돌려줘야 하는지, 어느 URI(Uniform Resource Identifier) 스킴에 적용되는지를 가리킵니다.
RFC 6265 이전에도 쿠키를 적은 문서가 적어도 셋 있었습니다. 이른바 Netscape 쿠키 명세, RFC 2109, RFC 2965 입니다. 그런데 이 문서들 가운데 어느 것도 Cookie 와 Set-Cookie 헤더가 인터넷에서 실제로 어떻게 쓰이는지를 기술하지 않았습니다. 실제 쓰임을 적은 문서 하나로 다시 굳힌 것이 RFC 6265 입니다.
역사적 이유로 쿠키에는 보안과 프라이버시상의 결함이 여럿 남았습니다. 서버는 어떤 쿠키를 "secure" 연결용이라고 표시할 수 있습니다. 그런데 Secure 속성은 능동적인 네트워크 공격자 앞에서 무결성을 주지 않습니다. 한 호스트의 쿠키가 그 호스트의 모든 포트에서 공유되기도 합니다. 웹 브라우저가 쓰는 통상의 동일 출처 정책은 포트가 다르면 가져온 콘텐츠를 격리하는데도 그렇습니다. 초록은 이런 결함들이 쿠키의 보안과 프라이버시를 떨어뜨린다고 적습니다. 그러면서도 두 헤더 필드가 인터넷에서 널리 쓰인다고 적습니다.
갈래
축은 속성입니다. 이름과 값 뒤에 어떤 속성을 붙였느냐가 쿠키의 수명과 범위를 가릅니다. §5.3 저장 모델은 그 결과를 쿠키마다 플래그로 들고 있습니다. persistent-flag · host-only-flag · secure-only-flag · http-only-flag 넷입니다. 아래 소절 가운데 SameSite 와 이름 접두사는 RFC 6265 에 없습니다. draft-ietf-httpbis-rfc6265bis 가 정의합니다.
세션 쿠키와 지속 쿠키
Expires 는 쿠키가 만료되는 날짜와 시각으로 최대 수명을 적습니다. Max-Age 는 만료까지 남은 초로 적습니다. 저장 모델은 둘 중 하나라도 있으면 persistent-flag 를 참으로 둡니다. 둘 다 없으면 거짓이 되고 만료 시각은 표현 가능한 가장 나중 날짜가 됩니다. 사용자 에이전트는 "현재 세션이 끝날" 때까지 그 쿠키를 들고 있습니다. 둘 다 있으면 Max-Age 가 우선하고 만료 시각을 결정합니다.
지정한 기한까지 들고 있을 의무는 없습니다. 문서는 사용자 에이전트가 메모리 압박이나 프라이버시 우려로 쿠키를 자주 축출한다고 적습니다. Max-Age 를 지원하지 않는 기존 사용자 에이전트도 있습니다. 그런 사용자 에이전트는 이 속성을 무시합니다.
호스트 전용 쿠키와 도메인 쿠키
Domain 은 쿠키를 보낼 호스트들을 지정합니다. 값이 example.com 이면 사용자 에이전트는 example.com · www.example.com · www.corp.example.com 으로 가는 요청의 Cookie 헤더에 쿠키를 싣습니다. 서버가 Domain 을 빼면 host-only-flag 가 참이 되고 쿠키는 오리진 서버에만 돌아갑니다.
아무 값이나 되지는 않습니다. Domain 이 오리진 서버를 포함하는 범위를 지정하지 않으면 사용자 에이전트는 쿠키를 거절합니다. foo.example.com 이 보낸 쿠키라면 example.com 이나 foo.example.com 은 받아들이고 bar.example.com 이나 baz.foo.example.com 은 받아들이지 않습니다. 경고도 붙어 있습니다. 기존 사용자 에이전트 가운데는 Domain 이 없는 것을 현재 호스트 이름이 적힌 것처럼 다루는 것들이 있습니다.
경로로 좁힌 쿠키
Path 는 쿠키의 범위를 경로 집합으로 제한합니다. 서버가 Path 를 빼면 사용자 에이전트는 요청 URI 경로 성분의 "디렉토리" 를 기본값으로 씁니다. 요청 URI 의 경로 부분이 쿠키의 Path 와 맞거나 그 하위 디렉토리일 때만 쿠키를 싣습니다. %x2F("/") 문자를 디렉토리 구분자로 해석합니다.
한 호스트 안에서 경로별로 쿠키를 격리하는 데 쓸모 있어 보입니다. 그런데 Path 는 보안 목적으로 기댈 수 있는 것이 아닙니다. 문서가 이 대목에서 보안을 다루는 §8 을 함께 가리킵니다.
Secure 와 HttpOnly
Secure 는 쿠키의 범위를 "secure" 채널로 제한합니다. 무엇이 secure 인지는 사용자 에이전트가 정합니다. 대개 TLS(Transport Layer Security) 위의 HTTP 입니다. 능동적 네트워크 공격자에게서 쿠키를 지키는 데 쓸모 있어 보입니다. 그런데 Secure 가 지키는 것은 쿠키의 기밀성뿐입니다. 능동적인 네트워크 공격자는 안전하지 않은 채널에서 Secure 쿠키를 덮어써서 무결성을 흔들 수 있습니다.
HttpOnly 는 쿠키의 범위를 HTTP 요청으로 제한합니다. "비HTTP" API(Application Programming Interface, 응용 프로그램 프로그래밍 인터페이스)로 쿠키에 접근을 열어 줄 때 그 쿠키를 빼라고 사용자 에이전트에게 지시하는 것입니다. 스크립트에 쿠키를 노출하는 웹 브라우저 API 가 그런 자리입니다. 두 속성은 서로 독립입니다. 한 쿠키가 HttpOnly 와 Secure 를 함께 가질 수 있습니다.
SameSite
rfc6265bis §4.1.2.7 이 정의합니다. 요청이 같은 사이트에서 온 것일 때만 쿠키가 붙도록 범위를 제한합니다. 사이트는 스킴과 등록 가능한 도메인의 짝입니다 — 앞서 다룬 호스트나 도메인보다 성긴 단위로, 서브도메인이 달라도 스킴과 등록 가능한 도메인이 같으면 같은 사이트로 봅니다. 값은 Strict · Lax · None 셋입니다. Strict 는 같은 사이트 요청에만 쿠키를 보냅니다. Lax 는 같은 사이트 요청에 더해, 기준 둘을 함께 채우는 교차 사이트 요청에도 보냅니다 — 최상위 내비게이션일 것, 그리고 안전한 메서드를 쓸 것입니다. 최상위 내비게이션은 주소창에 뜬 URL(Uniform Resource Locator, 통합 자원 위치자) 자체가 바뀌는 이동입니다. 링크를 누르거나 주소를 입력하거나 폼을 제출하는 것은 이 기준을 채우고, fetch 요청이나 이미지·스크립트 태그가 부르는 요청, 프레임 안에서 일어나는 이동은 이 기준을 못 채웁니다. 안전한 메서드는 POST · PUT · DELETE 를 뺀 나머지입니다. 앞서 말한 폼 제출도 이 둘을 함께 채워야 합니다 — GET 으로 제출하면 두 기준을 다 채우지만, POST 로 제출하면 최상위 내비게이션이라는 첫 기준은 채워도 안전한 메서드라는 둘째 기준에서 빠집니다. None 은 양쪽 모두에 보냅니다. 아는 세 낱말이 아닌 값은 Lax 로 다룬 것과 같게 처리됩니다. 다만 사용자 에이전트가 "Lax-allowing-unsafe" 시행 방식을 쓴다면 이 기본값은 Lax 대신 "Lax-allowing-unsafe" 로 다룬 것과 같게 처리됩니다 — 그 시행 방식이 정확히 무엇인지는 §5.6.7.2 가 따로 정합니다.
전달만 가리는 것이 아니라 생성도 가립니다. SameSite=Lax 나 SameSite=Strict 를 주장하는 쿠키는 교차 사이트 하위 리소스 요청(이미지·스크립트 태그가 부르는, 페이지에 딸려 오는 요청입니다)이나 교차 사이트 중첩 내비게이션(프레임 안에서 일어나는 이동입니다)의 응답에서는 설정될 수 없습니다. 어떤 최상위 내비게이션의 응답에서든 설정될 수 있습니다. 같은 사이트든 교차 사이트든 가리지 않습니다. MDN(Mozilla Developer Network) 은 이 속성이 CSRF(Cross-Site Request Forgery, 교차 사이트 요청 위조)를 포함한 일부 교차 사이트 공격에 어느 정도 보호를 준다고 적습니다.
이름 접두사
rfc6265bis §4.1.3 이 정의합니다. 어떤 쿠키가 특정 속성들과 함께 설정됐다는 것을 서버가 확신할 방법이 없다는 것이 출발점입니다. 그 확신을 뒤로 호환되게 주려고 이름 앞 몇 글자에서 요구사항 두 묶음을 읽어 내기로 한 것입니다. 서버는 사용자 에이전트와의 호환을 최대로 하려면 이 접두사들을 쓰는 것이 좋습니다(SHOULD).
__Secure- 로 시작하는 이름의 쿠키는 Secure 속성과 함께 설정된 것입니다. __Host- 로 시작하면 Secure 속성, 값이 / 인 Path 속성, 그리고 Domain 속성 없음까지 셋을 갖춘 것입니다. Domain 이 없으니 쿠키가 한 호스트에 묶입니다. Path 가 / 이니 호스트 전체에 걸칩니다. 포트만은 __Host- 쿠키도 여전히 무시합니다. 아래는 보안 오리진(앞서 나온 오리진 서버를 스킴까지 포함해 가리키는 말입니다. https 같은 안전한 스킴으로 접근했을 때를 뜻합니다. 예를 들어 https://site.example/) 에서 설정하면 받아들여지고 그렇지 않으면 거절되는 값입니다. Secure 를 빼거나 Domain 을 붙이면 언제나 거절됩니다.
Set-Cookie: __Host-SID=12345; Secure; Path=/
관련 항목
쿠키를 이루는 속성
Secure · HttpOnly · SameSite · Path · Domain · Expires · Max-Age
쿠키 교환에 관여하는 참여자
사용자 에이전트 · 브라우저 · 오리진 서버 · 애플리케이션
쿠키가 걸치는 프로토콜과 식별자
HTTP · TLS · 프로토콜 · URI · ISSN
Set-Cookie 처리에 영향을 주는 HTTP 규칙
상태 코드 · 헤더 접기
사용자 에이전트가 쿠키에 두는 제약
쿠키가 지키려는 성질과 막으려는 공격
무결성 · 기밀성 · CSRF · 동일 출처 정책 · 공격자 · 보안 · 프라이버시
쿠키 표준을 관리하는 기구
IETF · IANA · IESG(Internet Engineering Steering Group)
쿠키 표준의 계보와 인용 문서
RFC · RFC 2109 · RFC 2965 · Netscape · draft-ietf-httpbis-rfc6265bis · draft-ietf-httpbis-cookie-alone · draft-ietf-httpbis-cookie-same-site · draft-ietf-httpbis-cookie-prefixes · RFC 2616 · MDN
이름이 겹치는 이웃
세션 · 매직 쿠키(Magic Cookie)
다른 이름: cookie · Cookie · Set-Cookie · HTTP 쿠키