| 인터넷 초안 | 쿠키: HTTP 상태 관리 메커니즘 | 2026년 7월 |
| Bingler 외 | 2027년 1월 2일 만료 | [페이지] |
이 문서는 HTTP Cookie 및 Set-Cookie 헤더 필드를 정의한다. 이러한 헤더 필드는 HTTP 서버가 HTTP 사용자 에이전트에 상태(쿠키라고 함)를 저장하여, 대체로 상태가 없는 HTTP 프로토콜 위에서 서버가 상태를 가진 세션을 유지할 수 있게 한다. 쿠키에는 보안과 개인정보 보호를 저해하는 많은 역사적 결함이 있지만, Cookie 및 Set-Cookie 헤더 필드는 인터넷에서 널리 사용된다. 이 문서는 RFC 6265를 폐기한다.¶
이 참고 사항은 RFC로 게시되기 전에 제거된다.¶
이 문서의 상태 정보는 https://datatracker.ietf.org/doc/draft-ietf-httpbis-rfc6265bis/에서 확인할 수 있다.¶
이 문서에 대한 논의는 HTTP 작업 그룹 메일링 리스트(mailto:ietf-http-wg@w3.org)에서 이루어지며, 그 보관 문서는 https://lists.w3.org/Archives/Public/ietf-http-wg/에 있다. 작업 그룹 정보는 https://httpwg.org/에서 확인할 수 있다.¶
이 초안의 소스와 이슈 추적기는 https://github.com/httpwg/http-extensions/labels/6265bis에서 확인할 수 있다.¶
이 인터넷 초안은 BCP 78 및 BCP 79의 조항을 완전히 준수하여 제출되었다.¶
인터넷 초안은 인터넷 엔지니어링 태스크 포스(IETF)의 작업 문서이다. 다른 그룹도 작업 문서를 인터넷 초안으로 배포할 수 있다는 점에 유의하라. 현재 인터넷 초안의 목록은 https://datatracker.ietf.org/drafts/current/에 있다.¶
인터넷 초안은 최대 6개월 동안 유효한 초안 문서이며, 언제든지 다른 문서에 의해 갱신, 대체 또는 폐기될 수 있다. 인터넷 초안을 참고 자료로 사용하거나 "진행 중인 작업" 이외의 방식으로 인용하는 것은 적절하지 않다.¶
이 인터넷 초안은 2027년 1월 2일에 만료된다.¶
Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
This document may contain material from IETF Documents or IETF Contributions published or made publicly available before November 10, 2008. The person(s) controlling the copyright in some of this material may not have granted the IETF Trust the right to allow modifications of such material outside the IETF Standards Process. Without obtaining an adequate license from the person(s) controlling the copyright in such materials, this document may not be modified outside the IETF Standards Process, and derivative works of it may not be created outside the IETF Standards Process, except to format it for publication as an RFC or to translate it into languages other than English.¶
이 문서는 HTTP Cookie 및 Set-Cookie 헤더 필드를 정의한다. Set-Cookie 헤더 필드를 사용하여 HTTP 서버는 이름/값 쌍과 관련 메타데이터(쿠키라고 함)를 사용자 에이전트에 전달할 수 있다. 사용자 에이전트가 서버에 후속 요청을 보낼 때, 사용자 에이전트는 메타데이터와 기타 정보를 사용하여 Cookie 헤더 필드에 이름/값 쌍을 반환할지 여부를 결정한다.¶
겉보기에는 단순하지만, 쿠키에는 여러 복잡성이 있다. 예를 들어, 서버는 각 쿠키를 사용자 에이전트에 보낼 때 범위를 표시한다. 이 범위는 사용자 에이전트가 쿠키를 반환해야 하는 최대 시간, 사용자 에이전트가 쿠키를 반환해야 하는 서버, 그리고 쿠키가 적용되는 연결 유형을 나타낸다.¶
역사적 이유로 쿠키에는 여러 보안 및 개인정보 보호 결함이 포함되어 있다. 예를 들어, 서버는 특정 쿠키가 "보안" 연결을 위한 것이라고 표시할 수 있지만, Secure 속성은 능동적 네트워크 공격자가 있는 경우 무결성을 제공하지 않는다. 마찬가지로, 특정 호스트의 쿠키는 해당 호스트의 모든 포트에서 공유되며, 웹 브라우저에서 일반적으로 사용하는 "same-origin policy"가 서로 다른 포트를 통해 가져온 콘텐츠를 격리하는 것과 대조된다.¶
이 명세는 쿠키를 생성하는 서버와 쿠키를 소비하는 사용자 에이전트의 개발자 모두에게 적용된다. 3.2절은 각 구현 유형의 의도된 대상 독자를 명확히 하는 데 도움을 준다.¶
사용자 에이전트와의 상호운용성을 최대화하기 위해, 서버는 쿠키를 생성할 때 4절에서 정의한 잘 동작하는 프로파일로 스스로를 제한하는 것이 좋다.¶
사용자 에이전트는 4절에서 정의한 잘 동작하는 프로파일을 따르지 않는 기존 서버와의 상호운용성을 최대화하기 위해, 5절에서 정의한 더 관대한 처리 규칙을 구현해야 한다.¶
이 문서는 인터넷에서 실제로 사용되는 이러한 헤더 필드의 구문과 의미론을 지정한다. 특히 이 문서는 오늘날 사용 중인 것 이상의 새로운 구문이나 의미론을 만들지 않는다. 4절에서 제공하는 쿠키 생성 권장사항은 현재 서버 동작 중 선호되는 하위 집합을 나타내며, 5절에서 제공하는 더 관대한 쿠키 처리 알고리즘조차도 오늘날 사용 중인 모든 구문적·의미적 변형을 권장하지는 않는다. 일부 기존 소프트웨어가 권장 프로토콜과 중요한 방식으로 다른 경우, 이 문서는 그 차이를 설명하는 주석을 포함한다.¶
이 문서에서 핵심 단어 "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", "OPTIONAL"은 여기 표시된 것처럼 모두 대문자로 나타날 때, 그리고 오직 그 경우에만 BCP 14 [RFC2119] [RFC8174]에 설명된 대로 해석된다.¶
알고리즘의 일부로 명령형으로 표현된 요구사항(예: "strip any leading space characters" 또는 "return false and abort this algorithm")은 해당 알고리즘을 도입할 때 사용된 핵심 단어("MUST", "SHOULD", "MAY" 등)의 의미로 해석된다.¶
알고리즘이나 특정 단계로 표현된 적합성 요구사항은 최종 결과가 동등하다면 어떤 방식으로든 구현할 수 있다. 특히 이 명세에서 정의하는 알고리즘은 이해하기 쉽도록 의도된 것이며, 성능이 뛰어나도록 의도된 것은 아니다.¶
이 명세는 [RFC5234]의 Augmented Backus-Naur Form(ABNF) 표기법을 사용한다.¶
다음 핵심 규칙은 [RFC5234] 부록 B.1에 정의된 대로 참조로 포함된다: ALPHA(문자), CR(캐리지 리턴), CRLF(CR LF), CTLs (제어 문자), DIGIT(10진수 0-9), DQUOTE(큰따옴표), HEXDIG (16진수 0-9/A-F/a-f), LF(라인 피드), NUL(null 옥텟), OCTET(NUL을 제외한 임의의 8비트 데이터 시퀀스), SP(공백), HTAB(수평 탭), CHAR(임의의 [USASCII] 문자), VCHAR(임의의 표시 가능한 [USASCII] 문자), WSP(공백류).¶
"user agent", "client", "server", "proxy", "origin server"라는 용어는 HTTP/1.1 명세([HTTP]의 3절)에서와 같은 의미를 가진다.¶
request-host는 사용자 에이전트가 알고 있는 호스트의 이름으로, 사용자 에이전트가 HTTP 요청을 보내고 있거나 HTTP 응답을 받고 있는 호스트 (즉, 대응하는 HTTP 요청을 보낸 호스트의 이름)를 말한다.¶
request-uri라는 용어는 [HTTP]의 7.1절에 정의된 "target URI"를 가리킨다.¶
두 옥텟 시퀀스가 대소문자를 구분하지 않고 서로 일치한다고 하는 것은 [RFC4790]에 정의된 i;ascii-casemap 정렬 기준 아래에서 두 시퀀스가 동등한 경우, 그리고 오직 그 경우뿐이다.¶
string이라는 용어는 NUL이 아닌 옥텟의 시퀀스를 의미한다.¶
"active browsing context", "active document", "ancestor navigables", "container document", "content navigable", "dedicated worker", "Document", "inclusive ancestor navigables", "navigable", "navigate", "opaque origin", "sandboxed origin browsing context flag", "shared worker", "the worker's Documents", "top-level traversable", "WorkerGlobalScope"라는 용어는 [HTML]에 정의되어 있다.¶
"Service Workers"는 Service Workers 명세 [SERVICE-WORKERS]에 정의되어 있다.¶
"origin"이라는 용어, URI에서 origin을 도출하는 메커니즘, 그리고 origin에 대한 "the same" 일치 알고리즘은 [RFC6454]에 정의되어 있다.¶
"안전한" HTTP 메서드에는
[HTTP]의 9.2.1절에 정의된
GET, HEAD,
OPTIONS, TRACE가 포함된다.¶
도메인의 "public suffix"는 "com", "co.uk", "pvt.k12.wy.us"와 같이
공개 레지스트리가 제어하는 도메인의 부분이다. 도메인의
"registrable domain"은 도메인의 public suffix와 그 왼쪽의 레이블을 합친 것이다.
즉, https://www.site.example의 경우 public suffix는 example이고,
registrable domain은 site.example이다. 보안
고려사항은 8.9절을 참조하라.¶
"request"라는 용어와 요청의 "client", "current url", "method", "target browsing context", "url list"는 [FETCH]에 정의되어 있다.¶
"non-HTTP APIs"라는 용어는 쿠키를 설정하고 검색하는 데 사용되는 비HTTP 메커니즘, 예를 들어 스크립트에 쿠키를 노출하는 웹 브라우저 API를 가리킨다.¶
"top-level navigation"이라는 용어는 top-level traversable의 탐색을 가리킨다.¶
이 절은 origin server가 사용자 에이전트에 상태 정보를 보내고, 사용자 에이전트가 그 상태 정보를 origin server에 반환하는 방식을 개략적으로 설명한다.¶
상태를 저장하기 위해 origin server는 HTTP 응답에 Set-Cookie 헤더 필드를 포함한다. 후속 요청에서 사용자 에이전트는 Cookie 요청 헤더 필드를 origin server에 반환한다. Cookie 헤더 필드에는 사용자가 이전 Set-Cookie 헤더 필드에서 받은 쿠키가 포함된다. origin server는 Cookie 헤더 필드를 무시하거나 그 내용을 애플리케이션 정의 목적에 사용할 수 있다.¶
Origin server는 어떤 응답에도 Set-Cookie 응답 헤더 필드를 보낼 수 있다(MAY). Origin server는 하나의 응답에 여러 Set-Cookie 헤더 필드를 포함할 수 있다. Cookie 또는 Set-Cookie 헤더 필드가 있다고 해서 HTTP 캐시가 응답을 저장하고 재사용하는 것이 배제되지는 않는다.¶
Origin server와 중개자는 여러 Set-Cookie 헤더 필드를 하나의 헤더 필드로 결합해서는 안 된다(MUST NOT). HTTP 헤더 필드를 결합하는 일반적인 메커니즘 (즉, [HTTP]의 5.3절에 정의된 것)은 Set-Cookie 헤더 필드의 의미론을 변경할 수 있다. 이는 %x2C(",") 문자가 Set-Cookie에서 그러한 결합과 충돌하는 방식으로 사용되기 때문이다.¶
예를 들어,¶
Set-Cookie: a=b;path=/c,d=e¶
는 모호하다. 이는 a=b와 d=e라는 두 개의 쿠키로 의도되었을 수도 있고, /c,d=e 경로를 가진 하나의 쿠키로 의도되었을 수도 있다.¶
사용자 에이전트는 응답 상태 코드 또는 사용자 에이전트의 쿠키 정책에 따라 Set-Cookie 헤더 필드를 무시할 수 있다(MAY)(5.3절 참조).¶
참고: 쿠키의 옥텟은 [USASCII] 문자로 처리되어야 한다(MUST). 비HTTP API가 하나 이상의 비[USASCII] 문자를 포함한 set-cookie-string을 전달할 수는 있지만, 이러한 옥텟을 [USASCII] 문자 이외의 것으로 해석하려고 시도해서는 안 된다.¶
Set-Cookie 헤더 필드를 사용하여 서버는 HTTP 응답에서 사용자 에이전트에 짧은 문자열을 보낼 수 있으며, 사용자 에이전트는 쿠키의 범위 안에 있는 향후 HTTP 요청에서 그 문자열을 반환한다. 예를 들어, 서버는 사용자 에이전트에 31d4d96e407aad42 값을 가진 SID라는 "session identifier"를 보낼 수 있다. 그러면 사용자 에이전트는 후속 요청에서 그 세션 식별자를 반환한다.¶
== Server -> User Agent == Set-Cookie: SID=31d4d96e407aad42 == User Agent -> Server == Cookie: SID=31d4d96e407aad42¶
서버는 Path 및 Domain 속성을 사용하여 쿠키의 기본 범위를 변경할 수 있다. 예를 들어, 서버는 사용자 에이전트에 site.example의 모든 경로와 모든 하위 도메인에 쿠키를 반환하도록 지시할 수 있다.¶
== Server -> User Agent == Set-Cookie: SID=31d4d96e407aad42; Path=/; Domain=site.example == User Agent -> Server == Cookie: SID=31d4d96e407aad42¶
다음 예시에서 보듯이, 서버는 사용자 에이전트에 여러 쿠키를 저장할 수 있다. 예를 들어, 서버는 두 개의 Set-Cookie 헤더 필드를 반환하여 세션 식별자와 사용자의 선호 언어를 저장할 수 있다. 더 민감한 세션 식별자에 추가 보안 보호를 제공하기 위해 서버가 Secure 및 HttpOnly 속성을 사용한다는 점에 유의하라 (4.1.2절 참조).¶
== Server -> User Agent == Set-Cookie: SID=31d4d96e407aad42; Path=/; Secure; HttpOnly Set-Cookie: lang=en-US; Path=/; Domain=site.example == User Agent -> Server == Cookie: SID=31d4d96e407aad42; lang=en-US¶
위 Cookie 헤더 필드에는 SID라는 이름의 쿠키 하나와 lang이라는 이름의 쿠키 하나, 총 두 개의 쿠키가 포함되어 있다는 점에 유의하라.¶
쿠키 이름은 대소문자를 구분한다. 즉, 서버가 이름의 대소문자만 다른 두 개의 Set-Cookie 헤더 필드를 사용자 에이전트에 보내면, 사용자 에이전트는 후속 요청에서 이 두 쿠키를 모두 저장하고 반환한다.¶
== Server -> User Agent == Set-Cookie: SID=31d4d96e407aad42 Set-Cookie: sid=31d4d96e407aad42 == User Agent -> Server == Cookie: SID=31d4d96e407aad42; sid=31d4d96e407aad42¶
서버가 사용자 에이전트가 여러 "세션"(예: 사용자 에이전트 재시작)에 걸쳐 쿠키를 지속하기를 원한다면, 서버는 Expires 속성에 만료 날짜를 지정할 수 있다. 사용자 에이전트의 쿠키 저장소가 할당량을 초과하거나 사용자가 서버의 쿠키를 수동으로 삭제하는 경우, 사용자 에이전트가 만료 날짜 전에 쿠키를 삭제할 수 있음에 유의하라.¶
== Server -> User Agent == Set-Cookie: lang=en-US; Expires=Wed, 09 Jun 2026 10:18:14 GMT == User Agent -> Server == Cookie: SID=31d4d96e407aad42; lang=en-US¶
마지막으로 쿠키를 제거하려면, 서버는 과거의 만료 날짜를 가진 Set-Cookie 헤더 필드를 반환한다. 서버는 Set-Cookie 헤더 필드의 Path 및 Domain 속성이 쿠키가 생성될 때 사용된 값과 일치하는 경우에만 쿠키 제거에 성공한다.¶
== Server -> User Agent == Set-Cookie: lang=; Expires=Sun, 06 Nov 1994 08:49:37 GMT == User Agent -> Server == Cookie: SID=31d4d96e407aad42¶
이어지는 두 절인 4절과 5절은 두 가지 서로 다른 구현 유형에 대한 요구사항 집합을 논의한다. 이 절은 구현자가 자신의 목표에 가장 적합한 요구사항 집합을 판단하는 데 도움을 주기 위한 것이다. 잘못된 요구사항 집합을 선택하면 다른 쿠키 구현과의 호환성이 부족해질 수 있다.¶
호환성이 있다는 것이 구현자의 목표에 따라 서로 다른 의미를 가진다는 점이 중요하다. 이러한 차이는 의도적·비의도적 명세 변경, 명세 해석, 역사적 구현 차이로 인해 시간이 지나며 축적되어 왔다.¶
이 절은 쿠키 명세의 구현자를 대략 두 유형, 즉 생산자와 소비자로 나눈다. 이는 공식 용어가 아니며, 독자가 사용 사례를 직관적으로 이해하도록 돕기 위해 여기에서만 사용된다.¶
이 절은 이러한 요구사항을 정확히 구현하는 사용자 에이전트가 기존 서버(4절에 설명된 잘 동작하는 프로파일을 따르지 않는 서버도 포함)와 상호운용할 수 있을 만큼 충분히 상세하게 Cookie 및 Set-Cookie 헤더 필드를 지정한다.¶
사용자 에이전트는 여기에 지정된 것보다 더 많은 제한을 적용할 수도 있다 (예: 7.2절에 설명된 쿠키 정책에 의해 지정되는 제한). 그러나 그러한 추가 제한은 사용자 에이전트가 기존 서버와 상호운용할 가능성을 줄일 수 있다.¶
이 절은 사용자 에이전트가 Cookie 및 Set-Cookie 헤더 필드의 특정 하위 구성요소를 처리하는 데 사용하는 몇 가지 알고리즘을 정의한다.¶
정규화된 호스트 이름은 다음 알고리즘에 의해 생성되는 문자열이다:¶
두 origin이 [SAMESITE]에 정의된 "same site" 기준을 만족하면 same-site이다. 다음 기준이 참이면 요청은 "same-site"이다:¶
요청이 사용자 인터페이스 요소를 통해 트리거된 새로고침 탐색의 결과가 아니다(사용자 에이전트가 정의한 대로; 예: 사용자가 툴바의 새로고침 버튼을 클릭해 트리거한 요청).¶
요청의 current url의 origin이 요청 클라이언트의 "site for cookies"(origin임)와 same-site이거나, 요청에 클라이언트가 없거나 요청의 클라이언트가 null이다.¶
사용자 인터페이스 요소를 통해 트리거된 새로고침 탐색의 결과인 요청은, 다시 로드된 문서가 원래 same-site 요청을 통해 탐색된 경우 same-site이다. "same-site"가 아닌 요청은 대신 "cross-site"이다.¶
요청 클라이언트의 "site for cookies"는 다음 하위 절에 설명된 대로 클라이언트 유형에 따라 계산된다:¶
사용자 에이전트의 주소 표시줄에 표시되는 URI는 사용자에게 직접 노출되는 유일한 보안 컨텍스트이며, 따라서 사용자가 특정 웹사이트를 신뢰할지 여부를 판단하기 위해 합리적으로 의존할 수 있는 유일한 신호이다. 그 URI의 origin은 사용자가 자신이 상호작용하고 있다고 가장 그럴듯하게 믿는 컨텍스트를 나타낸다. 이 origin, 즉 top-level traversable의 active document의 origin은 "top-level origin"으로 정의된다.¶
top-level traversable에 표시되는 문서의 경우, 문서의 "site for cookies"는 top-level origin이다.¶
container document의 경우, [RFC7034]의 4절에 설명된 "multiple-nested scenarios"를 고려하기 위해 문서의 각 ancestor navigable의 active document의 origin을 검사해야 한다. 문서의 "site for cookies"는 top-level origin이 문서의 origin 및 문서의 각 ancestor document의 origin과 same-site인 경우에만 top-level origin이다. 그렇지 않으면 그 "site for cookies"는 opaque origin으로 설정된 origin이다.¶
Document(document)가 주어지면, 다음 알고리즘은 그
"site for cookies"를 반환한다:¶
top-document를
document의 navigable의 top-level traversable에 있는
active document로 둔다.¶
top-document의
sandboxed origin browsing context flag가 설정되어 있으면
top-origin을 top-document의 URI의 origin으로 두고,
그렇지 않으면 top-document의 origin으로 둔다.¶
documents를
document의 inclusive ancestor navigables의 active documents로
구성된 목록으로 둔다.¶
documents 안의 각 item에 대해:¶
top-origin을 반환한다.¶
참고: 이 알고리즘은
top-document부터 document까지의 전체 문서 체인이
모두 active인 경우에만 적용된다.¶
워커 기반 요청은 문서 기반 요청만큼 명확하지 않다. top-level traversable과 워커 사이에 명확한 연결이 없기 때문이다. 이는 Service Workers [SERVICE-WORKERS]에서 특히 그렇다. Service Workers는 보이는 문서가 전혀 없어도 백그라운드에서 코드를 실행할 수 있다.¶
Service Workers는 더 복잡하다. Service Workers는 이를 등록한 Document와는 부차적인 관계만 있는 완전히 별개의 실행 컨텍스트로 동작하기 때문이다.¶
사용자 에이전트가 Service Workers를 처리하는 방식은 다를 수 있지만, 사용자 에이전트는 [SERVICE-WORKERS] 명세와 일치하는 것이 좋다(SHOULD).¶
쿠키 이름 접두사에 대한 사용자 에이전트의 요구사항은 서버의 요구사항(4.1.3절)과 약간 다르다. UA는 접두사 문자열을 대소문자를 구분하지 않고 일치시켜야 하기 때문이다(MUST).¶
접두사에 대한 규범 요구사항은 5.7절에 정의된 저장 모델 알고리즘에 자세히 설명되어 있다.¶
이는 일부 서버가 쿠키를 대소문자를 구분하지 않고 처리하여, 의도치 않게 대소문자가 잘못된 접두사를 잘못 대문자화하고 수락하는 결과를 낳기 때문이다.¶
예를 들어, 서버가 다음 Set-Cookie 헤더 필드를 보낸다면¶
Set-Cookie: __SECURE-SID=12345¶
접두사를 대소문자를 구분하여 검사하는 UA는 이 쿠키를 수락하며,
서버는 그 쿠키가 __Secure-로 철자된 쿠키와 동일한 보장의 대상이라고
잘못 믿게 된다.¶
또한 서버는 공격자가 접두사가 붙은 쿠키를 가장하기 위해
의도적으로 쿠키의 대소문자를 잘못 쓰는 공격에 취약하다. 예를 들어,
사이트에 이미 __Secure-SID=12345 쿠키가 있고, 어떤 수단으로든 공격자가
접두사를 대소문자를 구분하여 검사하는 UA에 대해 해당 사이트에 다음
Set-Cookie 헤더 필드를 보낸다고 하자.¶
Set-Cookie: __SeCuRe-SID=evil¶
다음에 사용자가 사이트를 방문하면 UA는 두 쿠키를 모두 보낸다:¶
Cookie: __Secure-SID=12345; __SeCuRe-SID=evil¶
대소문자를 구분하지 않는 서버는 두 쿠키를 구분할 수 없으므로, 공격자가 사이트를 침해할 수 있게 된다.¶
이러한 문제를 방지하기 위해 UA는 쿠키 이름 접두사를 대소문자를 구분하지 않고 일치시켜야 한다(MUST).¶
참고: 이름이 다른 쿠키는 여전히 UA에 의해 별개의 것으로 간주된다.
따라서 __Secure-foo=bar와 __secure-foo=baz는 서로 다른
쿠키로 동시에 존재할 수 있으며, 둘 다 __Secure- 접두사의 요구사항이
적용된다.¶
다음은 적합한 사용자 에이전트가 거부할
Set-Cookie 헤더 필드의 예이다.¶
Set-Cookie: __Secure-SID=12345; Domain=site.example Set-Cookie: __secure-SID=12345; Domain=site.example Set-Cookie: __SECURE-SID=12345; Domain=site.example Set-Cookie: __Host-SID=12345 Set-Cookie: __host-SID=12345; Secure Set-Cookie: __host-SID=12345; Domain=site.example Set-Cookie: __HOST-SID=12345; Domain=site.example; Path=/ Set-Cookie: __Host-SID=12345; Secure; Domain=site.example; Path=/ Set-Cookie: __host-SID=12345; Secure; Domain=site.example; Path=/ Set-Cookie: __HOST-SID=12345; Secure; Domain=site.example; Path=/¶
반면 다음 Set-Cookie 헤더 필드는
보안 origin에서 설정된 경우 수락된다.¶
Set-Cookie: __Secure-SID=12345; Domain=site.example; Secure Set-Cookie: __secure-SID=12345; Domain=site.example; Secure Set-Cookie: __SECURE-SID=12345; Domain=site.example; Secure Set-Cookie: __Host-SID=12345; Secure; Path=/ Set-Cookie: __host-SID=12345; Secure; Path=/ Set-Cookie: __HOST-SID=12345; Secure; Path=/¶
사용자 에이전트는 각 쿠키에 대해 다음 필드를 저장한다: name, value, expiry-time, domain, path, creation-time, last-access-time, persistent-flag, host-only-flag, secure-only-flag, http-only-flag, same-site-flag.¶
사용자 에이전트가 request-uri로부터 name이 cookie-name, value가 cookie-value, attributes가 cookie-attribute-list인 "쿠키를 수신"하면, 사용자 에이전트는 다음과 같이 쿠키를 처리해야 한다(MUST):¶
cookie-name이 비어 있고 cookie-value도 비어 있으면, 이 알고리즘을 중단하고 쿠키 전체를 무시한다.¶
cookie-name 또는 cookie-value가 %x00-08 / %x0A-1F / %x7F 문자(HTAB을 제외한 CTL 문자)를 포함하면, 이 알고리즘을 중단하고 쿠키 전체를 무시한다.¶
cookie-name과 cookie-value 길이의 합이 4096 옥텟보다 크면, 이 알고리즘을 중단하고 쿠키 전체를 무시한다.¶
name이 cookie-name이고 value가 cookie-value인 새 쿠키를 생성한다. creation-time과 last-access-time을 현재 날짜와 시간으로 설정한다.¶
cookie-attribute-list가 attribute-name이 "Max-Age"인 속성을 포함하면:¶
쿠키의 persistent-flag를 true로 설정한다.¶
쿠키의 expiry-time을 cookie-attribute-list에서 attribute-name이 "Max-Age"인 마지막 속성의 attribute-value로 설정한다.¶
그렇지 않고, cookie-attribute-list가 attribute-name이 "Expires"인 속성을 포함하며(attribute-name이 "Max-Age"인 속성은 포함하지 않으면):¶
쿠키의 persistent-flag를 true로 설정한다.¶
쿠키의 expiry-time을 cookie-attribute-list에서 attribute-name이 "Expires"인 마지막 속성의 attribute-value로 설정한다.¶
그렇지 않으면:¶
cookie-attribute-list가 attribute-name이 "Domain"인 속성을 포함하면:¶
domain-attribute를 cookie-attribute-list에서 attribute-name이 "Domain"이고 attribute-value 길이가 1024 옥텟 이하인 마지막 속성의 attribute-value로 둔다. (앞에 %x2E(".")가 있으면, 그 문자가 허용되지 않더라도 무시된다는 점에 유의하라.)¶
그렇지 않으면:¶
domain-attribute를 빈 문자열로 둔다.¶
domain-attribute가 CHAR에 속하지 않는 문자를 포함하면, 이 알고리즘을 중단하고 쿠키 전체를 무시한다.¶
사용자 에이전트가 "public suffixes"를 거부하도록 구성되어 있고 domain-attribute가 public suffix이면:¶
request-host-canonical을 정규화된 request-host로 둔다.¶
request-host 정규화에 실패하면 이 알고리즘을 중단하고 쿠키 전체를 무시한다.¶
domain-attribute가 request-host-canonical과 동일하면:¶
domain-attribute를 빈 문자열로 둔다.¶
그렇지 않으면:¶
이 알고리즘을 중단하고 쿠키 전체를 무시한다.¶
참고: 이 단계는 attacker.example이 Domain 속성이 "example"인
쿠키를 설정하여 site.example의 무결성을 방해하는 것을 방지한다.¶
domain-attribute가 비어 있지 않으면:¶
request-host-canonical이 domain-attribute와 domain-match하지 않으면(5.1.3절 참조):¶
이 알고리즘을 중단하고 쿠키 전체를 무시한다.¶
그렇지 않으면:¶
그렇지 않으면:¶
cookie-attribute-list가 attribute-name이 "Path"인 속성을 포함하면, 쿠키의 path를 cookie-attribute-list에서 attribute-name이 "Path"이고 attribute-value 길이가 1024 옥텟 이하인 마지막 속성의 attribute-value로 설정한다. 그렇지 않으면 쿠키의 path를 request-uri의 default-path로 설정한다.¶
cookie-attribute-list가 attribute-name이 "Secure"인 속성을 포함하면, 쿠키의 secure-only-flag를 true로 설정한다. 그렇지 않으면 쿠키의 secure-only-flag를 false로 설정한다.¶
request-uri가 (사용자 에이전트가 정의한) "secure" 연결을 나타내지 않고, 쿠키의 secure-only-flag가 true이면, 이 단계들을 중단하고 쿠키 전체를 무시한다.¶
cookie-attribute-list가 attribute-name이 "HttpOnly"인 속성을 포함하면, 쿠키의 http-only-flag를 true로 설정한다. 그렇지 않으면 쿠키의 http-only-flag를 false로 설정한다.¶
쿠키가 "non-HTTP" API에서 수신되었고 쿠키의 http-only-flag가 true이면, 이 알고리즘을 중단하고 쿠키 전체를 무시한다.¶
쿠키의 secure-only-flag가 false이고 request-uri가 "secure" 연결을 나타내지 않으면, 쿠키 저장소에 다음 기준을 모두 만족하는 쿠키가 하나 이상 있는 경우 이 알고리즘을 중단하고 쿠키 전체를 무시한다:¶
그 이름이 새로 생성된 쿠키의 이름과 일치한다.¶
그 secure-only-flag가 true이다.¶
그 domain이 새로 생성된 쿠키의 domain과 domain-match하거나(5.1.3절 참조), 그 반대이다.¶
새로 생성된 쿠키의 path가 기존 쿠키의 path와 path-match한다.¶
참고: 경로 비교는 대칭적이지 않다. 이는 새로 생성된 비보안 쿠키가 기존 보안 쿠키를 덮어쓰지 않도록 보장하여, cookie-fixing 공격에 대한 일부 완화를 제공한다. 즉, 이름이 'a'이고 경로가 '/login'인 기존 보안 쿠키가 있을 때, 이름이 'a'인 비보안 쿠키는 '/' 또는 '/foo' 경로에 대해 설정될 수 있지만, '/login' 또는 '/login/en' 경로에 대해서는 설정될 수 없다.¶
cookie-attribute-list가 attribute-name이 "SameSite"이고 attribute-value가 "Strict", "Lax" 또는 "None"인 속성을 포함하면, 쿠키의 same-site-flag를 cookie-attribute-list에서 attribute-name이 "SameSite"인 마지막 속성의 attribute-value로 설정한다. 그렇지 않으면 쿠키의 same-site-flag를 "Default"로 설정한다.¶
쿠키의 same-site-flag가 "None"이 아니면:¶
쿠키가 "non-HTTP" API에서 수신되었고, 그 API가 navigable의 active document에서 호출되었으며 해당 "site for cookies"가 top-level origin과 same-site가 아니면, 이 알고리즘을 중단하고 새로 생성된 쿠키 전체를 무시한다.¶
쿠키가 "same-site" 요청에서 수신되었으면 (5.2절에 정의됨), 나머지 하위 단계를 건너뛰고 쿠키 처리를 계속한다.¶
쿠키가 top-level traversable [HTML]을
탐색하는 요청에서 수신되었으면
(예: 요청의 "reserved
client"가 null이거나, 그 "target browsing
context"의 navigable이 top-level traversable인 환경인 경우),
나머지 하위 단계를 건너뛰고 쿠키 처리를 계속한다.¶
참고: 최상위 탐색은 새 쿠키가 탐색 전에 이미 존재했다면
요청과 함께 전송되지 않았을 경우라도, 어떤 SameSite
값이든 가진 쿠키를 생성할 수 있다.¶
이 알고리즘을 중단하고 새로 생성된 쿠키 전체를 무시한다.¶
쿠키의 "same-site-flag"가 "None"이면, 쿠키의 secure-only-flag가 true가 아닌 한 이 알고리즘을 중단하고 쿠키 전체를 무시한다.¶
cookie-name이 대소문자를 구분하지 않고 문자열 "__Secure-"와 일치하는 것으로 시작하면, 쿠키의 secure-only-flag가 true가 아닌 한 이 알고리즘을 중단하고 쿠키 전체를 무시한다.¶
cookie-name이 대소문자를 구분하지 않고 문자열 "__Host-"와 일치하는 것으로 시작하면, 쿠키가 다음 기준을 모두 만족하지 않는 한 이 알고리즘을 중단하고 쿠키 전체를 무시한다:¶
cookie-name이 비어 있고 다음 조건 중 하나가 true이면, 이 알고리즘을 중단하고 쿠키 전체를 무시한다:¶
쿠키 저장소가 새로 생성된 쿠키와 동일한 name, domain, host-only-flag, path를 가진 쿠키를 포함하면:¶
old-cookie를 새로 생성된 쿠키와 동일한 name, domain, host-only-flag, path를 가진 기존 쿠키로 둔다. (이 알고리즘은 그러한 쿠키가 최대 하나만 존재한다는 불변식을 유지한다는 점에 유의하라.)¶
새로 생성된 쿠키가 "non-HTTP" API에서 수신되었고 old-cookie의 http-only-flag가 true이면, 이 알고리즘을 중단하고 새로 생성된 쿠키 전체를 무시한다.¶
새로 생성된 쿠키의 creation-time을 old-cookie의 creation-time과 일치하도록 업데이트한다.¶
쿠키 저장소에서 old-cookie를 제거한다.¶
새로 생성된 쿠키를 쿠키 저장소에 삽입한다.¶
쿠키의 만료 날짜가 과거이면 그 쿠키는 "expired"이다.¶
쿠키 저장소에 만료된 쿠키가 언제든 존재하면, 사용자 에이전트는 쿠키 저장소에서 모든 만료된 쿠키를 제거해야 한다(MUST).¶
어떤 domain 필드를 공유하는 쿠키의 수가 구현에서 정의한 상한(예: 50개의 쿠키)을 초과하면, 사용자 에이전트는 언제든 쿠키 저장소에서 "초과 쿠키 제거"를 할 수 있다(MAY).¶
쿠키 저장소가 미리 정해진 상한(예: 총 3000개의 쿠키)을 초과하면, 사용자 에이전트는 언제든 쿠키 저장소에서 "초과 쿠키 제거"를 할 수 있다(MAY).¶
사용자 에이전트가 쿠키 저장소에서 초과 쿠키를 제거할 때, 사용자 에이전트는 다음 우선순위 순서로 쿠키를 제거해야 한다(MUST):¶
만료된 쿠키.¶
secure-only-flag가 false이고, 미리 정해진 수보다 많은 다른 쿠키와 domain 필드를 공유하는 쿠키.¶
미리 정해진 수보다 많은 다른 쿠키와 domain 필드를 공유하는 쿠키.¶
모든 쿠키.¶
두 쿠키의 제거 우선순위가 같으면, 사용자 에이전트는 last-access-time이 가장 이른 쿠키를 먼저 제거해야 한다(MUST).¶
"현재 세션이 끝나면"(사용자 에이전트가 정의한 대로), 사용자 에이전트는 persistent-flag가 false로 설정된 모든 쿠키를 쿠키 저장소에서 제거해야 한다(MUST).¶
이 절은 쿠키 저장소에서 cookie-string 형태로 쿠키를 검색하는 방식을 정의한다. "retrieval"은 cookie-string 생성이 필요한 모든 이벤트이다. 예를 들어, HTTP 요청을 위한 Cookie 헤더 필드를 만들기 위해 retrieval이 발생할 수 있고, 쿠키에 대한 접근을 제공하는 "non-HTTP" API 호출에서 cookie-string을 반환하기 위해 retrieval이 필요할 수도 있다. retrieval에는 관련 URI, same-site 상태, type이 있으며, 이들은 retrieval의 유형에 따라 아래에 정의된다.¶
사용자 에이전트는 저장된 쿠키에 접근하는 데 사용할 수 있는 "non-HTTP" API를 구현할 수 있다(MAY).¶
사용자 에이전트는 retrieval이 third-party 컨텍스트 안에서 발생하는 경우와 같은 특정 컨텍스트에서 빈 cookie-string을 반환할 수 있다(MAY) (7.1절 참조).¶
사용자 에이전트가 관련 Document가 있는 "non-HTTP" API의 특정 호출에 대해 쿠키를 반환하는 경우, 사용자 에이전트는 5.8.3절에 정의된 알고리즘에 따라 cookie-string을 계산해야 한다(MUST). 이때 retrieval의 URI는 호출자가 정의하며 ([DOM-DOCUMENT-COOKIE] 참조), retrieval의 same-site 상태는 Document의 "site for cookies"가 5.2.1절에 정의된 top-level origin과 same-site이면 "same-site"이고(그렇지 않으면 "cross-site"), retrieval의 type은 "non-HTTP"이다.¶
쿠키 저장소와 retrieval이 주어지면, 다음 알고리즘은 주어진 쿠키 저장소에서 cookie-string을 반환한다.¶
retrieval-host-canonical을 retrieval URI의 정규화된 host로 둔다.¶
retrieval URI의 host 정규화에 실패하면, 이 알고리즘을 중단한다.¶
cookie-list를 쿠키 저장소에서 다음 요구사항을 모두 만족하는 쿠키의 집합으로 둔다:¶
다음 중 하나:¶
쿠키의 host-only-flag가 true이고 retrieval-host-canonical이 쿠키의 domain과 동일하다.¶
또는:¶
쿠키의 host-only-flag가 false이고 retrieval-host-canonical이 쿠키의 domain과 domain-match한다(5.1.3절 참조).¶
"public suffixes"를 거부하도록 구성된 사용자 에이전트의 경우, 쿠키의 domain이 public suffix가 아니다.¶
참고: public suffix list가 쿠키 생성 이후 변경되었을 수 있다. 이 변경으로 인해 쿠키의 domain이 public suffix가 되었다면, 그 쿠키가 지금 생성되었다면 생성 중에 거부되었을 것이다 (5.7절 9단계 참조).¶
retrieval URI의 path가 쿠키의 path와 path-match한다.¶
쿠키의 secure-only-flag가 true이면, retrieval URI는 (사용자 에이전트가 정의한) "secure" 연결을 나타내야 한다.¶
참고: "secure" 연결의 개념은 이 문서에서 정의하지 않는다. 일반적으로 사용자 에이전트는 연결이 SSL 또는 TLS [TLS13]와 같은 전송 계층 보안을 사용하거나 host가 신뢰되는 경우 연결을 secure하다고 간주한다. 예를 들어 대부분의 사용자 에이전트는 "https"를 secure 프로토콜을 나타내는 scheme으로, "localhost"를 신뢰된 host로 간주한다.¶
쿠키의 http-only-flag가 true이면, retrieval의 type이 "non-HTTP"인 경우 쿠키를 제외한다.¶
쿠키의 same-site-flag가 "None"이 아니고 retrieval의 same-site 상태가 "cross-site"이면, 다음 조건을 모두 만족하지 않는 한 쿠키를 제외한다:¶
사용자 에이전트는 cookie-list를 다음 순서로 정렬하는 것이 좋다(SHOULD):¶
더 긴 path를 가진 쿠키가 더 짧은 path를 가진 쿠키보다 먼저 나열된다.¶
path 필드 길이가 같은 쿠키들 사이에서는, creation-time이 더 이른 쿠키가 creation-time이 더 늦은 쿠키보다 먼저 나열된다.¶
참고: 모든 사용자 에이전트가 cookie-list를 이 순서로 정렬하는 것은 아니지만, 이 순서는 이 문서가 작성될 당시의 일반적인 관행을 반영하며, 역사적으로 이 순서에 (잘못) 의존한 서버들이 있었다.¶
cookie-list 안의 각 쿠키의 last-access-time을 현재 날짜와 시간으로 업데이트한다.¶
cookie-list의 각 쿠키를 순서대로 처리하여 cookie-list를 cookie-string으로 직렬화한다:¶
실제 사용자 에이전트 구현에는 저장할 수 있는 쿠키의 수와 크기에 제한이 있다. 범용 사용자 에이전트는 다음 최소 기능을 각각 제공하는 것이 좋다(SHOULD):¶
사용자 에이전트는 저장하는 쿠키의 최대 수를 제한할 수 있으며, 언제든 어떤 쿠키든 제거할 수 있다(사용자의 요청에 의해서든 구현 제한 때문이든).¶
쿠키 최대 수에 대한 제한은 저장된 쿠키의 총 크기도 제한한다는 점에 유의하라. 이는 5.6절에서 반드시 적용되어야 하는 길이 제한 때문이다.¶
서버는 이러한 구현 제한에 도달하는 것을 피하고, 모든 요청에 Cookie 헤더 필드가 포함됨으로 인한 네트워크 대역폭을 최소화하며, 서버 헤더 필드 제한에 도달하는 것을 피하기 위해 가능한 한 적고 작은 쿠키를 사용하는 것이 좋다(SHOULD)(4.2.1절 참조).¶
사용자 에이전트가 언제든 어떤 쿠키든 제거할 수 있으므로, 사용자 에이전트가 Cookie 헤더 필드에서 하나 이상의 쿠키를 반환하지 못하는 경우 서버는 우아하게 성능을 낮추는 것이 좋다(SHOULD).¶
Cookie 및 Set-Cookie 헤더 필드가 이처럼 난해한 처리를 사용하는 한 가지 이유는, 많은 플랫폼(서버와 사용자 에이전트 모두)이 쿠키에 대해 문자열 기반 응용 프로그래밍 인터페이스(API)를 제공하여, 애플리케이션 계층 프로그래머가 Cookie 및 Set-Cookie 헤더 필드에서 사용하는 구문을 생성하고 파싱해야 하기 때문이다. 많은 프로그래머가 이를 잘못 처리했고, 그 결과 상호운용성 문제가 발생했다.¶
쿠키에 문자열 기반 API를 제공하는 대신, 플랫폼은 더 의미론적인 API를 제공하는 것이 유리할 것이다. 특정 API 설계를 권장하는 것은 이 문서의 범위를 벗어나지만, 직렬화된 날짜 문자열 대신 추상적인 "Date" 객체를 수락하는 데는 분명한 이점이 있다.¶
쿠키의 주요 개인정보 보호 위험은 사용자 활동을 상관시킬 수 있는 능력이다. 이는 단일 사이트에서 발생할 수 있지만, 겉보기에 서로 연결되지 않은 여러 웹사이트에서 활동을 추적하여 사용자 프로파일을 만들 때 가장 문제가 된다.¶
시간이 지나면서, 이 능력([RFC2109] 및 그 모든 후속 문서에서 명시적으로 경고한 것)은 다음을 포함한 다양한 이유로 널리 사용되게 되었다:¶
사이트 간 사용자 인증,¶
사용자에 대한 정보 조합,¶
사기 및 기타 바람직하지 않은 트래픽 형태에 대한 보호,¶
특정 사용자 또는 지정된 속성을 가진 사용자에게 광고 타기팅,¶
광고가 사용자에게 표시되는 빈도 측정, 그리고¶
광고가 사용자 행동의 변화로 이어졌는지 인식.¶
쿠키의 모든 사용이 반드시 개인정보 보호에 문제가 되는 것은 아니지만, 남용 가능성은 인터넷 커뮤니티와 더 넓은 사회에서 광범위한 우려가 되었다. 이러한 우려에 대응하여 사용자 에이전트는 (이전 명세에서 허용하고 권장한 대로) 여러 방식으로 쿠키 기능을 적극적으로 제한해 왔으며, 동시에 웹의 건강에 바람직하다고 판단하는 기능의 중단은 피하고 있다.¶
쿠키의 개인정보 보호 영향을 완화하는 데 어떤 특정 메커니즘을 사용해야 하는지에 대한 합의를 선언하기에는 아직 이르다. 사용자 에이전트가 쿠키 처리 방식을 계속 변경하는 것은 최종 합의에 입력을 제공할 수 있는 실험으로 보는 것이 가장 적절하다.¶
대신 이 문서는 작성 시점에 널리 배포되어 있는, 쿠키와 관련된 개인정보 보호 위험에 대한 제한적이고 일반적인 완화책을 설명한다. 구현은 시간이 지나면서 쿠키에 대해 더 엄격하고 더 잘 정의된 제한을 계속 실험하고 부과할 것으로 예상된다. 이 문서의 향후 버전은 배포 경험을 바탕으로 그러한 메커니즘을 성문화할 수 있다. 현재 쿠키에 의존하는 기능을 별도의 대상화된 메커니즘으로 지원할 수 있다면, 별도의 명세에 문서화될 수 있고 쿠키에 대한 더 엄격한 제한이 가능해질 수 있다.¶
쿠키가 사이트 간 사용자를 추적하는 데 사용할 수 있는 유일한 메커니즘은 아니므로, 이러한 완화책은 웹 개인정보 보호를 개선하는 데 필요하지만 그 자체만으로는 충분하지 않다는 점에 유의하라.¶
사용자 에이전트는 쿠키 저장소에 저장된 쿠키를 관리하기 위한 메커니즘을 사용자에게 제공하는 것이 좋다(SHOULD). 예를 들어, 사용자 에이전트는 지정된 기간 동안 수신된 모든 쿠키 또는 특정 도메인과 관련된 모든 쿠키를 사용자가 삭제할 수 있게 할 수 있다. 또한 많은 사용자 에이전트는 사용자가 쿠키 저장소에 저장된 쿠키를 검사할 수 있게 하는 사용자 인터페이스 요소를 포함한다.¶
사용자 에이전트는 쿠키를 비활성화하기 위한 메커니즘을 사용자에게 제공하는 것이 좋다(SHOULD). 쿠키가 비활성화되면, 사용자 에이전트는 나가는 HTTP 요청에 Cookie 헤더 필드를 포함해서는 안 되며(MUST NOT), 들어오는 HTTP 응답의 Set-Cookie 헤더 필드를 처리해서는 안 된다(MUST NOT).¶
사용자 에이전트는 쿠키 정책을 변경할 수 있는 방법을 제공할 수 있다(MAY) (7.2절 참조).¶
사용자 에이전트는 세션 간 쿠키의 영구 저장을 방지하는 옵션을 사용자에게 제공할 수 있다(MAY). 이렇게 구성된 경우, 사용자 에이전트는 수신한 모든 쿠키를 persistent-flag가 false로 설정된 것처럼 취급해야 한다(MUST). 일부 인기 있는 사용자 에이전트는 이 기능을 "private browsing" 모드 [Aggarwal2010]를 통해 노출한다.¶
쿠키에는 여러 보안상 함정이 있다. 이 절은 그중 몇 가지 더 두드러진 문제를 개관한다.¶
특히 쿠키는 개발자가 인증을 위해 주변 권한에 의존하도록 장려하여, 종종 cross-site request forgery [CSRF]와 같은 공격에 취약해진다. 또한 개발자는 세션 식별자를 쿠키에 저장할 때 세션 고정 취약점을 만드는 경우가 많다.¶
HTTPS에서 사용되는 것과 같은 전송 계층 암호화는 쿠키에 대한 네트워크 공격에 대해 상당한 방어 계층을 제공한다. 그러나 쿠키 프로토콜 자체의 본질적인 취약점 때문에 네트워크 공격자가 피해자의 쿠키를 얻거나 변경하는 것을 완전히 방지하기에는 충분하지 않다(아래의 "약한 기밀성" 및 "약한 무결성" 참조). 또한 기본적으로 쿠키는 HTTPS와 함께 사용되더라도 네트워크 공격자로부터의 기밀성이나 무결성을 제공하지 않는다. 이는 쿠키가 보호 속성을 명시적으로 지정해야 함을 의미한다. 예를 들어, 다음 쿠키는:¶
Set-Cookie: a=b
¶
Secure 속성을 지정하지 않으므로, 생성된 원래 연결 유형과 관계없이 보안 연결과 비보안 연결 모두에서 접근 가능하다. 이러한 동작은 공격자가 쿠키를 읽거나 수정할 수 있게 할 수 있다.¶
보안 채널(예: TLS [TLS13])을 통해 전송되지 않는 한, Cookie 및 Set-Cookie 헤더 필드의 정보는 평문으로 전송된다.¶
이러한 헤더 필드로 전달되는 모든 민감한 정보는 도청자에게 노출된다.¶
악의적인 중개자가 어느 방향으로든 이동하는 동안 헤더 필드를 변경할 수 있으며, 그 결과는 예측할 수 없다.¶
서버는 쿠키를 사용자 에이전트로 전송할 때(보안 채널을 통해 쿠키를 보내는 경우에도) 쿠키의 내용을 암호화하고 서명하는 것이 좋다(SHOULD)(서버가 원하는 어떤 형식이든 사용). 그러나 쿠키 내용을 암호화하고 서명하더라도 공격자가 한 사용자 에이전트에서 다른 사용자 에이전트로 쿠키를 이식하거나 나중에 쿠키를 재생하는 것을 방지하지는 못한다.¶
모든 쿠키의 내용을 암호화하고 서명하는 것에 더하여, 더 높은 수준의 보안을 요구하는 서버는 보안 채널에서만 Cookie 및 Set-Cookie 헤더 필드를 사용하는 것이 좋다(SHOULD). 보안 채널에서 쿠키를 사용할 때, 서버는 모든 쿠키에 Secure 속성(4.1.2.5절 참조)을 설정하는 것이 좋다(SHOULD). 서버가 Secure 속성을 설정하지 않으면, 보안 채널이 제공하는 보호는 대체로 무의미해진다.¶
예를 들어, 세션 식별자를 쿠키에 저장하고 일반적으로 HTTPS를 통해 접근되는 웹메일 서버를 생각해 보자. 서버가 쿠키에 Secure 속성을 설정하지 않으면, 능동적 네트워크 공격자는 사용자 에이전트에서 나가는 모든 HTTP 요청을 가로채어 그 요청을 HTTP를 통해 웹메일 서버로 리다이렉트할 수 있다. 웹메일 서버가 HTTP 연결을 수신하지 않더라도, 사용자 에이전트는 여전히 요청에 쿠키를 포함한다. 능동적 네트워크 공격자는 이러한 쿠키를 가로채고 서버에 대해 재생하여 사용자의 이메일 내용을 알 수 있다. 반대로 서버가 쿠키에 Secure 속성을 설정했다면, 사용자 에이전트는 평문 요청에 쿠키를 포함하지 않았을 것이다.¶
세션 정보를 쿠키에 직접 저장하는 대신(그 정보가 공격자에게 노출되거나 재생될 수 있음), 서버는 일반적으로 nonce(또는 "session identifier")를 쿠키에 저장한다. 서버가 nonce가 포함된 HTTP 요청을 받으면, 서버는 nonce를 키로 사용하여 쿠키와 관련된 상태 정보를 조회할 수 있다.¶
세션 식별자 쿠키를 사용하면, 공격자가 쿠키의 내용을 알게 되더라도 공격자가 초래할 수 있는 피해가 제한된다. nonce는 서버와 상호작용하는 데에만 유용하기 때문이다(nonce가 아닌 쿠키 내용은 그 자체로 민감할 수 있음). 더 나아가 단일 nonce를 사용하면, 공격자가 서버와의 두 상호작용에서 얻은 쿠키 내용을 "splicing"하여 서버가 예기치 않게 동작하게 하는 것을 방지한다.¶
세션 식별자를 사용하는 데 위험이 없는 것은 아니다. 예를 들어, 서버는 "session fixation" 취약점을 피하도록 주의하는 것이 좋다(SHOULD). 세션 고정 공격은 세 단계로 진행된다. 첫째, 공격자는 자신의 사용자 에이전트에서 피해자의 사용자 에이전트로 세션 식별자를 이식한다. 둘째, 피해자는 그 세션 식별자를 사용해 서버와 상호작용하며, 세션 식별자에 사용자의 자격 증명이나 기밀 정보를 부여할 수 있다. 셋째, 공격자는 그 세션 식별자를 사용해 서버와 직접 상호작용하여 사용자의 권한 또는 기밀 정보를 얻을 수 있다.¶
쿠키는 포트별 격리를 제공하지 않는다. 한 포트에서 실행되는 서비스가 쿠키를 읽을 수 있으면, 같은 서버의 다른 포트에서 실행되는 서비스도 그 쿠키를 읽을 수 있다. 한 포트의 서비스가 쿠키를 쓸 수 있으면, 같은 서버의 다른 포트에서 실행되는 서비스도 그 쿠키를 쓸 수 있다. 이러한 이유로 서버는 같은 호스트의 서로 다른 포트에서 서로 신뢰하지 않는 서비스를 동시에 실행하면서 보안에 민감한 정보를 저장하는 데 쿠키를 사용하지 않는 것이 좋다(SHOULD NOT).¶
쿠키는 scheme별 격리를 제공하지 않는다. 가장 흔히 http 및 https scheme과 함께 사용되지만, 주어진 호스트의 쿠키는 ftp 및 gopher와 같은 다른 scheme에서도 사용 가능할 수 있다. 이러한 scheme별 격리 부재는 쿠키 접근을 허용하는 비HTTP API(예: HTML의 document.cookie API)에서 가장 분명하지만, scheme별 격리 부재는 실제로 쿠키 자체를 처리하기 위한 요구사항에도 존재한다 (예: HTTP를 통해 gopher scheme의 URI를 검색하는 경우를 생각해 보라).¶
쿠키는 항상 path별 격리를 제공하지는 않는다. 네트워크 수준 프로토콜은 한 path에 저장된 쿠키를 다른 path로 보내지 않지만, 일부 사용자 에이전트는 HTML의 document.cookie API와 같은 비HTTP API를 통해 쿠키를 노출한다. 이러한 사용자 에이전트 중 일부(예: 웹 브라우저)는 서로 다른 path에서 받은 리소스를 격리하지 않기 때문에, 한 path에서 검색된 리소스가 다른 path에 저장된 쿠키에 접근할 수 있을 수 있다.¶
쿠키는 형제 도메인(및 그 하위 도메인)에 대한 무결성 보장을 제공하지 않는다. 예를 들어 foo.site.example과 bar.site.example을 생각해 보자. foo.site.example 서버는 Domain 속성이 "site.example"인 쿠키를 설정할 수 있으며 (bar.site.example이 설정한 기존 "site.example" 쿠키를 덮어쓸 수도 있음), 사용자 에이전트는 bar.site.example에 대한 HTTP 요청에 그 쿠키를 포함한다. 최악의 경우 bar.site.example은 이 쿠키를 자신이 직접 설정한 쿠키와 구별할 수 없다. foo.site.example 서버는 이 능력을 이용하여 bar.site.example에 대한 공격을 수행할 수 있을 수 있다.¶
Set-Cookie 헤더 필드가 Path 속성을 지원하더라도, Path 속성은 무결성 보호를 제공하지 않는다. 사용자 에이전트가 Set-Cookie 헤더 필드 안의 임의의 Path 속성을 수락하기 때문이다. 예를 들어 http://site.example/foo/bar에 대한 요청의 HTTP 응답은 Path 속성이 "/qux"인 쿠키를 설정할 수 있다. 따라서 서버는 같은 호스트의 서로 다른 path에서 서로 신뢰하지 않는 서비스를 동시에 실행하면서 보안에 민감한 정보를 저장하는 데 쿠키를 사용하지 않는 것이 좋다(SHOULD NOT).¶
능동적 네트워크 공격자는 http://site.example/의 응답을 가장하고 Set-Cookie 헤더 필드를 삽입함으로써 https://site.example/로 전송되는 Cookie 헤더 필드에 쿠키를 주입할 수도 있다. site.example의 HTTPS 서버는 이러한 쿠키를 자신이 HTTPS 응답에서 직접 설정한 쿠키와 구별할 수 없다. 능동적 네트워크 공격자는 site.example이 HTTPS만 사용하더라도 이 능력을 이용하여 site.example에 대한 공격을 수행할 수 있을 수 있다.¶
서버는 쿠키의 내용을 암호화하고 서명하거나 쿠키 이름에
__Secure- 접두사를 붙여 이러한 공격을 부분적으로 완화할 수 있다.
그러나 암호화를 사용하더라도 문제가 완전히 완화되지는 않는다. 공격자가 진짜
site.example 서버에서 받은 쿠키를 사용자의 세션에서 재생할 수 있으며,
그 결과는 예측할 수 없기 때문이다.¶
마지막으로, 공격자는 많은 수의 쿠키를 저장하여 사용자 에이전트가 쿠키를 삭제하도록 강제할 수 있을 수 있다. 사용자 에이전트가 저장 제한에 도달하면, 사용자 에이전트는 일부 쿠키를 제거할 수밖에 없다. 서버는 사용자 에이전트가 쿠키를 유지할 것이라고 의존해서는 안 된다(SHOULD NOT).¶
쿠키는 보안을 위해 Domain Name System(DNS)에 의존한다. DNS가 부분적으로 또는 완전히 손상되면, 쿠키 프로토콜은 애플리케이션이 요구하는 보안 속성을 제공하지 못할 수 있다.¶
쿠키 접두사를 도입하고, 이름 없는 쿠키가 쿠키 접두사를 모방하는 값을 설정하는 것을 금지한다. (4.1.3절 및 5.7절)¶
비보안 origin이 Secure 플래그가 있는 쿠키를 설정하거나
이 플래그가 있는 쿠키를 덮어쓰는 것을 금지한다. (5.7절)¶
쿠키 구문을 개선한다¶
public suffix list 변경으로 인해 유효하지 않은 쿠키를 보내는 것을 경계하도록 권고한다. (5.8.3절)¶
path-value 및 extension-av 문법을 업데이트하여 errata 3444를, day-of-month, year, time 문법을 업데이트하여 errata 4148을, 요청된 참고를 추가하여 errata 3663을 처리한다. (4.1절 및 5.1.4절)¶