인터넷 엔지니어링 태스크 포스 (IETF) A. Barth
의견 요청: 6265 U.C. Berkeley
대체함: 2965 2011년 4월
카테고리: 표준 트랙
ISSN: 2070-1721

HTTP 상태 관리 메커니즘


요약

이 문서는 HTTP Cookie 및 Set-Cookie 헤더 필드를 정의합니다. 이러한 헤더 필드는 HTTP 서버가 HTTP 사용자 에이전트에 상태(쿠키라 부름)를 저장하도록 사용될 수 있으며, 이를 통해 서버는 주로 무상태인 HTTP 프로토콜 위에서 상태 유지 세션을 관리할 수 있습니다. 쿠키는 보안과 개인정보 보호를 저해하는 여러 역사적 문제를 안고 있지만, Cookie 및 Set-Cookie 헤더 필드는 인터넷에서 널리 사용되고 있습니다. 이 문서는 RFC 2965를 대체합니다.

이 메모의 상태

이 문서는 인터넷 표준 트랙 문서입니다.

이 문서는 인터넷 엔지니어링 태스크 포스(IETF)의 산출물입니다. 이는 IETF 커뮤니티의 합의를 반영합니다. 공개 검토를 거쳤으며 인터넷 엔지니어링 스티어링 그룹(IESG)에 의해 발행 승인을 받았습니다. 인터넷 표준에 관한 추가 정보는 RFC 5741의 2절을 참조하십시오.

이 문서의 현재 상태, 정오표, 피드백 제공 방법에 관한 정보는 http://www.rfc-editor.org/info/rfc6265에서 확인할 수 있습니다.

Copyright Notice

Copyright (c) 2011 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 (http://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 Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified 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.

1. 소개

이 문서는 HTTP Cookie 및 Set-Cookie 헤더 필드를 정의합니다. Set-Cookie 헤더 필드를 사용하여, HTTP 서버는 이름/값 쌍과 연관된 메타데이터(쿠키라고 부름)를 사용자 에이전트에게 전달할 수 있습니다. 사용자 에이전트가 이후에 서버에 요청을 보낼 때, 사용자 에이전트는 해당 메타데이터와 기타 정보를 사용하여 Cookie 헤더에 이름/값 쌍을 포함할지 여부를 결정합니다.

표면적으로는 단순하지만, 쿠키에는 여러 복잡한 요소가 있습니다. 예를 들어 서버는 쿠키를 전송할 때 각 쿠키의 범위(scope)를 지정합니다. 범위는 사용자 에이전트가 쿠키를 반환해야 하는 최대 기간, 쿠키를 반환해야 하는 서버들, 그리고 쿠키가 적용되는 URI 스킴을 나타냅니다.

역사적 이유로 인해 쿠키에는 보안 및 개인정보 보호 관점에서 여러 불완전한 점들이 존재합니다. 예를 들어 서버는 특정 쿠키가 "Secure" 연결을 위한 것임을 지정할 수 있지만, Secure 속성은 능동적인 네트워크 공격자가 있을 경우 무결성을 보장하지 않습니다. 마찬가지로 주어진 호스트의 쿠키는 그 호스트의 모든 포트에서 공유되며, 웹 브라우저가 일반적으로 사용하는 동일 출처 정책(same-origin policy)은 서로 다른 포트에서 가져온 콘텐츠를 분리합니다.

이 명세서의 대상은 두 그룹입니다: 쿠키를 생성하는 서버의 개발자와 쿠키를 소비하는 사용자 에이전트의 개발자입니다.

사용자 에이전트와의 상호운용성을 극대화하기 위해, 서버는 쿠키를 생성할 때 섹션 4에 정의된 바람직한(정상 동작) 프로필을 따르는 것이 권장됩니다.

사용자 에이전트는 기존의 바람직한 프로필을 따르지 않는 서버들과의 상호운용성을 극대화하기 위해 섹션 5에 정의된 더 관대한 처리 규칙을 반드시 구현해야 합니다.

이 문서는 인터넷에서 실제로 사용되는 방식으로 이 헤더들의 구문과 의미를 규정합니다. 특히, 이 문서는 오늘날 사용되는 것 이상의 새로운 구문이나 의미를 창출하지 않습니다. 섹션 4의 쿠키 생성 권고는 현재 서버 동작의 바람직한 하위 집합을 나타내며, 섹션 5의 더 관대한 쿠키 처리 알고리즘도 오늘날 사용되는 모든 구문적·의미적 변형을 권장하지는 않습니다. 일부 기존 소프트웨어가 권장 프로토콜과 유의미하게 다른 경우, 문서에 차이를 설명하는 주석이 포함되어 있습니다.

이 문서 이전에는 적어도 세 가지의 쿠키 기술 설명이 있었습니다: 이른바 "Netscape 쿠키 명세" [Netscape], RFC 2109 [RFC2109], 및 RFC 2965 [RFC2965]. 그러나 이러한 문서들은 Cookie 및 Set-Cookie 헤더가 인터넷에서 실제로 어떻게 사용되는지를 설명하지 않았습니다(역사적 맥락은 [Kri2001] 참조). 이전 IETF의 HTTP 상태 관리 명세와 관련하여, 이 문서는 다음 조치를 요청합니다:

  1. RFC 2109의 상태를 Historic으로 변경(해당 문서는 이미 RFC2965로 대체됨).
  2. RFC 2965의 상태를 Historic으로 변경.
  3. RFC 2965가 이 문서에 의해 대체되었음을 명시.

특히 RFC 2965를 Historic으로 이동하고 폐기함으로써, 이 문서는 Cookie2 및 Set-Cookie2 헤더 필드의 사용을 더 이상 권장하지 않습니다.

2. 규약

2.1. 준수 기준

이 문서에서 사용된 핵심 용어 "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", 그리고 "OPTIONAL"은 [RFC2119]에 설명된 방식으로 해석됩니다.

알고리즘의 일부로 서술된 명령형 문구(예: "선행 공백 문자를 제거하라" 또는 "false를 반환하고 이 단계들을 중단하라")는 도입부에서 사용된 핵심 용어("MUST", "SHOULD", "MAY" 등)의 의미로 해석됩니다.

알고리즘이나 특정 단계로 표현된 준수 요구사항은 최종 결과가 동등한 한 어떤 방식으로든 구현될 수 있습니다. 특히, 이 명세에 정의된 알고리즘은 이해하기 쉽게 제공되며 고성능을 목표로 하지는 않습니다.

2.2. 구문 표기

이 명세는 [RFC5234]의 확장된 Backus-Naur Form(ABNF) 표기법을 사용합니다.

다음 핵심 규칙들은 [RFC5234] 부록 B.1에 정의된 대로 참조로 포함됩니다: ALPHA(문자), CR(캐리지 리턴), CRLF(CR LF), CTLs(제어 문자), DIGIT(십진수 0-9), DQUOTE(따옴표), HEXDIG(16진수), LF(라인 피드), NUL(널 옥텟), OCTET(널 제외 모든 8비트 시퀀스), SP(스페이스), HTAB(수평 탭), CHAR(모든 US-ASCII 문자), VCHAR(가시적 US-ASCII 문자), 및 WSP(공백).

OWS(선택적 공백) 규칙은 0개 이상의 선형 공백 문자가 나타날 수 있는 경우에 사용됩니다:

OWS            = *( [ obs-fold ] WSP )
                 ; "optional" whitespace
obs-fold       = CRLF
          

OWS는 생성되지 않거나 단일 SP 문자로 생성되는 것이 권장됩니다.

2.3. 용어

user agent, client, server, proxy, origin server 등의 용어는 HTTP/1.1 명세([RFC2616], 섹션 1.3)와 동일한 의미를 가집니다.

request-host는 사용자 에이전트가 HTTP 요청을 전송하거나 HTTP 응답을 수신할 때 사용자 에이전트가 알고 있는 호스트의 이름입니다(즉, 해당 HTTP 요청을 보낸 호스트의 이름).

request-uri 용어는 RFC2616 섹션 5.1.2에 정의되어 있습니다.

두 옥텟 시퀀스가 대소문자 구분 없이 일치한다고 말하려면, 그것들이 [RFC4790]에 정의된 i;ascii-casemap 정렬 규칙에 따라 동등해야 합니다.

문자열(string) 용어는 NUL이 아닌 옥텟의 시퀀스를 의미합니다.

3. 개요

이 섹션은 오리진 서버가 사용자 에이전트에게 상태 정보를 전송하고, 사용자 에이전트가 그 상태 정보를 오리진 서버에 반환하는 방법의 개요를 제시합니다.

상태를 저장하기 위해 오리진 서버는 HTTP 응답에 Set-Cookie 헤더를 포함합니다. 이후 요청에서 사용자 에이전트는 이전에 받은 Set-Cookie 헤더에 있는 쿠키들을 Cookie 요청 헤더에 포함하여 오리진 서버에 반환합니다. 오리진 서버는 Cookie 헤더를 무시하거나 그 내용을 애플리케이션 정의 용도로 사용할 수 있습니다.

오리진 서버는 모든 응답에 Set-Cookie 응답 헤더를 전송할 수 있습니다(MAY). 사용자 에이전트는 100번대 상태 코드 응답에 포함된 Set-Cookie 헤더를 무시할 수 있지만(MAY), 100번대가 아닌 다른 응답(400·500번대 응답 포함)에 포함된 Set-Cookie 헤더는 반드시(MUST) 처리해야 합니다. 오리진 서버는 단일 응답에 여러 Set-Cookie 헤더 필드를 포함할 수 있습니다. Cookie 또는 Set-Cookie 헤더 필드가 존재한다고 해서 HTTP 캐시가 응답을 저장하고 재사용하는 것을 배제하지 않습니다.

오리진 서버는 여러 Set-Cookie 헤더 필드를 하나의 필드로 접어(fold) 보내지 않는 것이 권장됩니다. HTTP 헤더 필드 접기(예: [RFC2616]에 정의된 방식)는 Set-Cookie 헤더에서 %x2C(",") 문자가 사용되는 방식과 충돌하여 의미를 변경할 수 있습니다.

3.1. 예시

Set-Cookie 헤더를 사용하여 서버는 사용자 에이전트에게 향후 해당 쿠키의 범위 내에 있는 요청에서 반환될 짧은 문자열을 보낼 수 있습니다. 예를 들어, 서버는 값이 31d4d96e407aad42인 SID라는 이름의 "세션 식별자"를 보낼 수 있습니다. 사용자 에이전트는 이후 요청에서 세션 식별자를 반환합니다.

== 서버 -> 사용자 에이전트 ==

Set-Cookie: SID=31d4d96e407aad42
          

== 사용자 에이전트 -> 서버 ==

Cookie: SID=31d4d96e407aad42
          

서버는 Path 및 Domain 속성을 사용하여 쿠키의 기본 범위를 변경할 수 있습니다. 예를 들어 서버는 사용자 에이전트에게 example.com의 모든 경로 및 모든 서브도메인에 대해 쿠키를 반환하도록 지시할 수 있습니다.

== 서버 -> 사용자 에이전트 ==

Set-Cookie: SID=31d4d96e407aad42; Path=/; Domain=example.com
          

== 사용자 에이전트 -> 서버 ==

Cookie: SID=31d4d96e407aad42
          

다음 예시에서 보듯이, 서버는 사용자 에이전트에 여러 쿠키를 저장할 수 있습니다. 예를 들어, 서버는 세션 식별자와 사용자가 선호하는 언어를 두 개의 Set-Cookie 헤더 필드로 저장할 수 있습니다. 민감한 세션 식별자에 대해 서버가 Secure 및 HttpOnly 속성을 사용하여 추가 보안 보호를 제공하는 점에 유의하십시오(비규범 의미는 섹션 4.1.2 참조).

== 서버 -> 사용자 에이전트 ==

Set-Cookie: SID=31d4d96e407aad42; Path=/; Secure; HttpOnly
Set-Cookie: lang=en-US; Path=/; Domain=example.com
          

== 사용자 에이전트 -> 서버 ==

Cookie: SID=31d4d96e407aad42; lang=en-US
          

위의 Cookie 헤더에는 SID라는 이름의 쿠키와 lang이라는 이름의 쿠키, 두 개의 쿠키가 포함되어 있음을 알 수 있습니다. 서버가 사용자 에이전트가 여러 "세션"(예: 사용자 에이전트 재시작)에 걸쳐 쿠키를 지속하도록 원한다면, Expires 속성에 만료 날짜를 지정할 수 있습니다. 단, 사용자 에이전트는 쿠키 저장소가 용량을 초과하거나 사용자가 수동으로 쿠키를 삭제한 경우 만료일 이전에 쿠키를 삭제할 수 있습니다.

== 서버 -> 사용자 에이전트 ==

Set-Cookie: lang=en-US; Expires=Wed, 09 Jun 2021 10:18:14 GMT
          

== 사용자 에이전트 -> 서버 ==

Cookie: SID=31d4d96e407aad42; lang=en-US
          

마지막으로 쿠키를 제거하려면, 서버는 과거의 만료 날짜를 가진 Set-Cookie 헤더를 반환합니다. 서버가 쿠키를 성공적으로 제거하려면 Set-Cookie 헤더의 Path 및 Domain 속성이 쿠키 생성 시 사용된 값과 일치해야 합니다.

== 서버 -> 사용자 에이전트 ==

Set-Cookie: lang=; Expires=Sun, 06 Nov 1994 08:49:37 GMT
          

== 사용자 에이전트 -> 서버 ==

Cookie: SID=31d4d96e407aad42
          

4. 서버 요구사항

이 절에서는 Cookie 및 Set-Cookie 헤더의 올바르게 동작하는 프로필의 구문과 의미를 설명합니다.

5. 사용자 에이전트 요구사항

이 절은 Cookie 및 Set-Cookie 헤더를 충분히 상세히 규정하여, 이 요구사항을 정확히 구현하는 사용자 에이전트가 기존의 서버(섹션 4의 정상 동작 프로필을 따르지 않는 서버 포함)와 상호운용할 수 있게 합니다.

사용자 에이전트는 본 문서에서 지정한 것보다 더 많은 제한을 적용할 수 있습니다(예: 보안 향상을 위해). 그러나 실험 결과, 이러한 엄격성은 기존 서버와의 상호운용성을 감소시킵니다.

5.1. 하위 구성요소 알고리즘

이 절은 사용자 에이전트가 Cookie 및 Set-Cookie 헤더의 특정 하위 구성요소를 처리하는 데 사용하는 몇 가지 알고리즘을 정의합니다.

5.3. 저장 모델

사용자 에이전트는 각 쿠키에 대해 다음 필드를 저장합니다: name, value, expiry-time, domain, path, creation-time, last-access-time, persistent-flag, host-only-flag, secure-only-flag, 및 http-only-flag.

사용자 에이전트가 request-uri로부터 cookie-name, cookie-value 및 cookie-attribute-list와 함께 "쿠키를 수신"하면 사용자 에이전트는 다음과 같이 쿠키를 처리해야 합니다:

  1. 사용자 에이전트는 수신된 쿠키를 전체적으로 무시할 수 있습니다. 예: 서드파티 응답으로부터의 쿠키 수신 차단이나, 저장 크기 초과 쿠키를 거부할 수 있습니다.
  2. 새 쿠키를 생성하고 이름을 cookie-name, 값을 cookie-value로 설정합니다. creation-time과 last-access-time을 현재 시각으로 설정합니다.
  3. cookie-attribute-list에 "Max-Age" 속성이 있으면:
    • 쿠키의 persistent-flag를 true로 설정합니다.
    • cookie-attribute-list에서 마지막으로 나타나는 "Max-Age" 속성의 attribute-value를 쿠키의 expiry-time으로 설정합니다.
    그렇지 않고 cookie-attribute-list에 "Expires" 속성이 있으면(그리고 "Max-Age"가 없으면):
    • 쿠키의 persistent-flag를 true로 설정합니다.
    • cookie-attribute-list에서 마지막으로 나타나는 "Expires" 속성의 attribute-value를 쿠키의 expiry-time으로 설정합니다.
    그렇지 않으면:
    • 쿠키의 persistent-flag를 false로 설정합니다.
    • 쿠키의 expiry-time을 표현 가능한 가장 늦은 날짜로 설정합니다.
  4. cookie-attribute-list에 "Domain" 속성이 있으면:
    • domain-attribute를 cookie-attribute-list에서 마지막으로 나타나는 "Domain" 속성의 attribute-value로 정합니다.
    그렇지 않으면:
    • domain-attribute를 빈 문자열로 정합니다.
  5. 사용자 에이전트가 "public suffix"를 거부하도록 구성되어 있고 domain-attribute가 public suffix이면:
    • domain-attribute가 정규화된 request-host와 동일하면: domain-attribute를 빈 문자열로 설정합니다.
    • 그렇지 않으면 쿠키를 전체적으로 무시하고 이 절차를 중단합니다.
    • 참고: "public suffix"는 "com", "co.uk" 등과 같이 공용 레지스트리에 의해 제어되는 도메인입니다. 가능한 경우 사용자 에이전트는 최신 public suffix 목록(예: Mozilla의 목록)을 사용하는 것이 권장됩니다.
  6. domain-attribute가 비어 있지 않으면:
    • 정규화된 request-host가 domain-attribute와 domain-match하지 않으면 쿠키를 무시하고 절차를 중단합니다.
    • 그렇지 않으면 cookie의 host-only-flag를 false로 설정하고 cookie의 domain을 domain-attribute로 설정합니다.
    그렇지 않으면:
    • cookie의 host-only-flag를 true로 설정하고 cookie의 domain을 정규화된 request-host로 설정합니다.
  7. cookie-attribute-list에 "Path" 속성이 있으면 쿠키의 path를 해당 속성의 attribute-value(마지막 것)로 설정합니다. 그렇지 않으면 cookie의 path를 request-uri의 default-path로 설정합니다.
  8. cookie-attribute-list에 "Secure" 속성이 있으면 cookie의 secure-only-flag를 true로 설정합니다. 그렇지 않으면 false로 설정합니다.
  9. cookie-attribute-list에 "HttpOnly" 속성이 있으면 cookie의 http-only-flag를 true로 설정합니다. 그렇지 않으면 false로 설정합니다.
  10. 쿠키가 "non-HTTP" API에서 수신되었고 쿠키의 http-only-flag가 설정되어 있으면 이 절차를 중단하고 쿠키를 무시합니다.
  11. 쿠키 저장소에 새로 생성된 쿠키와 동일한 이름, 도메인 및 경로를 가진 쿠키가 있으면:
    1. old-cookie를 기존 쿠키로 정합니다. (이 알고리즘은 그러한 쿠키가 최대 하나만 존재한다는 불변성을 유지합니다.)
    2. 새 쿠키가 "non-HTTP" API에서 수신되었고 old-cookie의 http-only-flag가 설정되어 있으면 이 절차를 중단하고 새 쿠키를 무시합니다.
    3. 새로 생성된 쿠키의 creation-time을 old-cookie의 creation-time으로 갱신합니다.
    4. old-cookie를 쿠키 저장소에서 제거합니다.
  12. 새로 생성된 쿠키를 쿠키 저장소에 삽입합니다.

쿠키는 만료 날짜가 과거이면 "만료(expired)"입니다.

사용자 에이전트는 쿠키 저장소에 만료된 쿠키가 존재하는 경우 즉시 모든 만료된 쿠키를 제거해야 합니다.

언제든지 사용자 에이전트는 도메인 필드를 공유하는 쿠키의 수가 구현 정의 상한(예: 50개)을 초과하면 "초과 쿠키 제거(remove excess cookies)"를 수행할 수 있습니다.

언제든지 사용자 에이전트는 쿠키 저장소가 미리 정해진 상한(예: 3000 쿠키)을 초과하면 "초과 쿠키 제거"를 수행할 수 있습니다.

사용자 에이전트가 초과 쿠키를 제거할 때는 다음 우선순위 순서로 쿠키를 제거해야 합니다:

  1. 만료된 쿠키.
  2. 다른 많은 쿠키와 도메인 필드를 공유하는 쿠키.
  3. 모든 쿠키.

두 쿠키가 동일한 제거 우선순위를 가지면, 사용자 에이전트는 last-access 날짜가 가장 이른 쿠키를 먼저 제거해야 합니다.

"현재 세션이 끝날 때"(사용자 에이전트 정의) 사용자 에이전트는 persistent-flag가 false로 설정된 모든 쿠키를 쿠키 저장소에서 제거해야 합니다.

6. 구현 고려사항

6.1. 한계

실제 사용자 에이전트 구현에는 저장할 수 있는 쿠키의 개수와 크기에 대한 제한이 있습니다. 일반적인 용도의 사용자 에이전트는 다음 최소 기능들을 제공하는 것이 권장됩니다:

  • 쿠키당 최소 4096 바이트(쿠키 이름, 값 및 속성 길이의 합으로 측정).
  • 도메인당 최소 50개의 쿠키.
  • 총합 최소 3000개의 쿠키.

서버는 이러한 구현 한계에 도달하지 않도록, 그리고 모든 요청에 Cookie 헤더가 포함되어 네트워크 대역폭이 증가하는 것을 최소화하기 위해 가능한 한 적고 작은 쿠키를 사용해야 합니다(권장).

사용자 에이전트가 사용자 명령에 따라 언제든지 어떤 쿠키든 제거할 수 있으므로, 서버는 사용자 에이전트가 Cookie 헤더에 하나 이상의 쿠키를 반환하지 못하는 상황에서 우아하게 동작을 저하시키도록 설계해야 합니다(권장).

6.2. 응용 프로그래밍 인터페이스

Cookie 및 Set-Cookie 헤더가 이렇게 난해한 문법을 사용하는 한 가지 이유는 많은 플랫폼(서버와 사용자 에이전트 양쪽)이 쿠키에 대해 문자열 기반의 API를 제공하기 때문입니다. 이로 인해 애플리케이션 개발자들이 Cookie 및 Set-Cookie 헤더에 사용되는 문법을 생성하고 파싱해야 하며, 많은 개발자가 이를 잘못 구현하여 상호운용성 문제가 발생했습니다.

플랫폼이 문자열 기반 API 대신 더 의미론적인(semantic) API를 제공한다면 더 바람직합니다. 이 문서에서는 특정 API 설계를 권장하는 범위를 벗어나지만, 직렬화된 날짜 문자열 대신 추상적인 "Date" 객체를 받아들이는 것이 명확한 이점을 제공한다는 점은 분명합니다.

6.3. IDNA 의존성 및 전환

IDNA2008 [RFC5890] 는 IDNA2003 [RFC3490] 를 대체합니다. 그러나 두 명세 간에는 차이가 있어, 서로 다른 규약으로 등록된 도메인 레이블을 처리(예: 변환)할 때 차이가 발생할 수 있습니다. IDNA2003 기반 도메인 레이블이 그대로 존재하는 전환 기간이 일정 기간 있을 것입니다. 사용자 에이전트는 IDNA2008([RFC5890])을 구현하는 것이 권장되며, 전환을 원활히 하기 위해 [UTS46] 또는 [RFC5895]를 구현할 수 있습니다. 만약 사용자 에이전트가 IDNA2008을 구현하지 않는다면, 사용자 에이전트는 IDNA2003([RFC3490])을 반드시 구현해야 합니다.

7. 개인정보 보호 고려사항

쿠키는 서버가 사용자를 추적할 수 있게 한다는 이유로 종종 비판받습니다. 예를 들어 여러 "웹 분석" 회사는 사용자가 웹 사이트를 재방문했거나 다른 사이트를 방문했는지를 인식하기 위해 쿠키를 사용합니다. 쿠키가 HTTP 요청 전반에서 사용자를 추적하는 유일한 수단은 아니지만, 쿠키는 사용자 에이전트 세션을 넘나들며 지속되고 호스트 간에 공유될 수 있기 때문에 추적을 용이하게 합니다.

7.1. 서드파티 쿠키

특히 우려되는 것은 이른바 "서드파티" 쿠키입니다. HTML 문서를 렌더링할 때 사용자 에이전트는 종종 광고 네트워크와 같은 다른 서버로부터 리소스를 요청합니다. 이러한 서드파티 서버는 사용자가 해당 서버를 직접 방문하지 않더라도 쿠키를 사용해 사용자를 추적할 수 있습니다. 예를 들어 사용자가 어떤 사이트에서 특정 서드파티의 콘텐츠를 보고, 이후 다른 사이트에서도 동일한 서드파티의 콘텐츠를 본다면 그 서드파티는 두 사이트 간에 사용자를 추적할 수 있습니다.

일부 사용자 에이전트는 서드파티 쿠키의 동작을 제한합니다. 예를 들어 일부는 서드파티 요청에서 Cookie 헤더를 전송하지 않거나, 서드파티 요청에 대한 응답에서 Set-Cookie 헤더를 처리하지 않습니다. 사용자 에이전트마다 서드파티 쿠키 정책은 매우 다양합니다. 이 문서는 사용자 에이전트가 사용자의 개인정보 보호와 호환성 필요를 조율하는 다양한 서드파티 쿠키 정책을 실험할 수 있는 폭넓은 재량을 부여합니다. 다만, 특정 정책을 본 문서가 지지하는 것은 아닙니다.

서드파티 쿠키 차단 정책은 서버가 제한을 우회하려 시도할 경우 개인정보 목표를 달성하는 데 종종 효과적이지 못합니다. 특히 두 협력 서버는 동적 URL에 식별 정보를 주입함으로써 쿠키를 전혀 사용하지 않고도 종종 사용자를 추적할 수 있습니다.

7.2. 사용자 제어

사용자 에이전트는 쿠키 저장소에 저장된 쿠키를 관리할 수 있는 메커니즘을 사용자에게 제공하는 것이 권장됩니다. 예를 들어, 사용자 에이전트는 사용자가 지정한 기간 동안 수신된 모든 쿠키를 삭제하거나 특정 도메인과 관련된 모든 쿠키를 삭제하도록 허용할 수 있습니다. 또한 많은 사용자 에이전트는 사용자에게 저장된 쿠키를 검사할 수 있는 UI 요소를 제공합니다.

사용자 에이전트는 쿠키를 비활성화하는 메커니즘을 사용자에게 제공하는 것이 권장됩니다. 쿠키가 비활성화된 경우, 사용자 에이전트는 발신 HTTP 요청에 Cookie 헤더를 포함해서는 안되며, 수신 HTTP 응답의 Set-Cookie 헤더를 처리해서는 안됩니다.

일부 사용자 에이전트는 세션 간의 영구적 저장을 방지하는 옵션을 제공합니다. 이러한 구성 시 사용자 에이전트는 수신된 모든 쿠키를 persistent-flag가 false로 설정된 것처럼 취급해야 합니다. 일부 인기 있는 사용자 에이전트는 이 기능을 "프라이빗 브라우징" 모드로 노출합니다([Aggarwal2010] 참조).

일부 사용자 에이전트는 쿠키 저장소에 대한 개별 쓰기를 승인하도록 사용자가 선택할 수 있게 합니다. 많은 일반적인 사용 시나리오에서 이러한 제어는 많은 프롬프트를 생성하지만, 개인정보에 민감한 일부 사용자는 이러한 제어를 유용하게 여길 수 있습니다.

7.3. 만료 기간

서버는 쿠키의 만료 날짜를 먼 미래로 설정할 수 있지만, 대부분의 사용자 에이전트는 실제로 수십 년 동안 쿠키를 보관하지 않습니다. 무작정 긴 만료 기간을 선택하기보다는, 서버는 쿠키의 목적에 따라 합리적인 만료 기간을 선택하여 사용자 개인정보를 보호하는 것이 권장됩니다. 예를 들어 일반적인 세션 식별자는 2주 내에 만료되도록 설정하는 것이 합리적일 수 있습니다.

8. 보안 고려사항

8.1. 개요

쿠키에는 여러 보안상의 함정이 있습니다. 이 절은 몇 가지 주요 이슈를 개관합니다.

특히, 쿠키는 개발자가 인증에 대해 주변 권한(ambient authority)에 의존하도록 만들기 쉬우며, 그 결과 교차 사이트 요청 위조(CSRF)와 같은 공격에 취약해지는 경우가 많습니다([CSRF]). 또한 세션 식별자를 쿠키에 저장할 때 세션 고정(session fixation) 취약점이 발생하기도 합니다.

전송 계층 암호화(예: HTTPS)가 사용되더라도 네트워크 공격자로부터 피해자의 쿠키를 획득하거나 변경하는 것을 완전히 방지할 수는 없습니다. 쿠키 프로토콜 자체에 다양한 취약점이 있기 때문입니다(아래의 "약한 기밀성" 및 "약한 무결성" 참조). 기본적으로 쿠키는 HTTPS와 결합해서도 네트워크 공격자로부터의 기밀성이나 무결성을 보장하지 않습니다.

8.2. 주변 권한 (Ambient Authority)

쿠키를 사용해 사용자를 인증하는 서버는 일부 사용자 에이전트가 원격 당사자가 사용자 에이전트로부터 HTTP 요청을 발생시킬 수 있도록 허용할 때 보안 취약점을 겪을 수 있습니다(예: HTTP 리디렉션 또는 HTML 폼을 통한 요청). 이러한 요청을 보낼 때 사용자 에이전트는 원격 당사자가 쿠키 내용을 알지 못하더라도 쿠키를 첨부하므로, 원격 당사자가 의도하지 않은 권한을 행사할 수 있습니다.

이 보안 문제는 여러 명칭(예: 교차 사이트 요청 위조, confused deputy)으로 불리지만, 근본 원인은 쿠키가 주변 권한의 한 형태라는 점입니다. 쿠키는 서버 운영자가 지정(예: URL)과 인가(예: 쿠키)를 분리하도록 장려합니다. 결과적으로 사용자 에이전트는 공격자가 지정한 자원에 대해 인가를 제공할 수 있으며, 서버나 클라이언트가 공격자가 지시한 작업을 마치 사용자가 허가한 것처럼 수행할 수 있습니다.

서버 운영자는 인가를 위해 쿠키를 사용하는 대신, URL을 권한(capability)으로 다루는 방식으로 지정과 인가를 엮는(entangle) 것을 고려할 수 있습니다. 즉, 비밀을 쿠키에 저장하는 대신 URL에 비밀을 포함시키는 방식으로 원격 엔터티가 직접 비밀을 제공하게 하는 것입니다. 이 접근이 만능은 아니지만, 신중하게 적용하면 보다 강건한 보안을 구현할 수 있습니다.

8.3. 평문 전송

Secure 채널(TLS 등)을 통해 전송되지 않는 한, Cookie 및 Set-Cookie 헤더의 정보는 평문으로 전송됩니다.

  1. 이 헤더들에 담긴 모든 민감한 정보는 도청자에게 노출됩니다.
  2. 악의적인 중개자는 양방향 전송 중 헤더를 변경할 수 있으며, 이는 예측 불가능한 결과를 초래할 수 있습니다.
  3. 악의적인 클라이언트는 전송 전에 Cookie 헤더를 변경할 수 있으며, 이 또한 예측 불가능한 결과를 초래할 수 있습니다.

서버는 쿠키 내용을 전송할 때(보안 채널을 사용하더라도) 쿠키 내용을 암호화하고 서명하는 것이 권장됩니다(서버가 원하는 어떤 형식이든 사용 가능). 다만 쿠키 내용을 암호화하고 서명하더라도 공격자가 한 사용자 에이전트에서 다른 사용자 에이전트로 쿠키를 이식하거나 나중에 재사용(replay)하는 것을 막지는 못합니다.

모든 쿠키 내용을 암호화하고 서명하는 것 외에도, 높은 수준의 보안을 요구하는 서버는 Cookie 및 Set-Cookie 헤더를 반드시 보안 채널에서만 사용해야 합니다. 보안 채널을 통해 쿠키를 사용할 때 서버는 모든 쿠키에 대해 Secure 속성을 설정하는 것이 권장됩니다(섹션 4.1.2.5 참조). 서버가 Secure 속성을 설정하지 않으면, 보안 채널이 제공하는 보호는 거의 무의미해질 것입니다.

예를 들어, 세션 식별자를 쿠키에 저장하고 주로 HTTPS로 접근되는 웹메일 서버를 생각해 보십시오. 서버가 쿠키에 Secure 속성을 설정하지 않으면, 능동적인 네트워크 공격자는 사용자 에이전트의 발신 HTTP 요청을 가로채어 웹메일 서버로 HTTP로 리다이렉트할 수 있습니다. 웹메일 서버가 HTTP 연결을 수신하지 않더라도 사용자 에이전트는 요청에 쿠키를 포함할 것입니다. 공격자는 이 쿠키를 가로채어 서버에 재전송(replay)하고 사용자의 이메일 내용을 알 수 있습니다. 반대로 서버가 쿠키에 Secure 속성을 설정했다면 사용자 에이전트는 평문 요청에 쿠키를 포함하지 않았을 것입니다.

8.4. 세션 식별자

쿠키에 세션 정보를 직접 저장하는 대신(이는 공격자에게 노출되거나 재사용될 수 있음) 서버는 흔히 쿠키에 nonce(또는 "세션 식별자")를 저장합니다. 서버는 요청에서 nonce를 받으면 그 nonce를 키로 사용해 서버 쪽 상태 정보를 조회할 수 있습니다.

세션 식별자 쿠키를 사용하면 공격자가 쿠키 내용을 알아내더라도 서버와 상호작용하는 데 그 nonce만 유효하므로 공격자가 초래할 수 있는 피해를 제한할 수 있습니다(민감한 내용을 직접 담고 있는 쿠키 내용과 달리). 또한 단일 nonce를 사용하면 공격자가 서버와의 두 상호작용에서 얻은 쿠키 내용을 "이어붙여" 서버가 예기치 않게 동작하게 만드는 것을 방지할 수 있습니다.

그러나 세션 식별자 사용도 위험이 전혀 없는 것은 아닙니다. 예를 들어 서버는 "세션 고정(session fixation)" 취약점을 피하도록 주의해야 합니다. 세션 고정 공격은 세 단계로 진행됩니다. 첫째, 공격자는 자신의 사용자 에이전트에서 세션 식별자를 피해자의 사용자 에이전트로 이식합니다. 둘째, 피해자가 그 세션 식별자를 사용하여 서버와 상호작용하고, 세션 식별자에 사용자 자격증명이나 기밀 정보를 부여할 수 있습니다. 셋째, 공격자는 그 세션 식별자를 사용해 서버와 직접 상호작용하여 사용자의 권한이나 기밀 정보를 얻을 수 있습니다.

8.5. 약한 기밀성

쿠키는 포트별 격리를 제공하지 않습니다. 한 포트에서 동작하는 서비스가 읽을 수 있는 쿠키는 동일 호스트의 다른 포트에서 동작하는 서비스도 읽을 수 있습니다. 한 포트에서 쓰기 가능한 쿠키는 다른 포트의 서비스에서도 쓰기 가능합니다. 따라서 서버는 동일 호스트의 서로 신뢰하지 않는 서비스를 서로 다른 포트에서 운용하면서 쿠키에 보안 민감 정보를 저장해서는 안됩니다.

쿠키는 스킴(scheme)별 격리를 제공하지 않습니다. 일반적으로 http 및 https 스킴에서 주로 사용되지만, 주어진 호스트의 쿠키는 ftp나 gopher 같은 다른 스킴에서도 접근 가능할 수 있습니다. 이러한 스킴별 격리 부족은 HTML의 document.cookie API와 같은 비-HTTP API에서 쿠키에 접근할 때 가장 명백하게 드러나지만, 스킴별 격리 부족은 쿠키 처리 요구사항 자체에도 존재합니다(예: gopher 스킴의 URI를 HTTP로 가져오는 경우를 고려해 보십시오).

쿠키는 경로별 격리를 항상 제공하지 않습니다. 네트워크 수준 프로토콜은 한 경로에 저장된 쿠키를 다른 경로로 전송하지 않지만, 일부 사용자 에이전트는 document.cookie 같은 비-HTTP API를 통해 쿠키를 노출합니다. 이러한 사용자 에이전트(예: 웹 브라우저)는 서로 다른 경로에서 가져온 리소스를 격리하지 않을 수 있으므로, 한 경로에서 가져온 리소스가 다른 경로의 쿠키에 접근할 수 있습니다.

8.6. 약한 무결성

쿠키는 형제 도메인(및 그 서브도메인)에 대한 무결성 보장을 제공하지 않습니다. 예를 들어 foo.example.com과 bar.example.com을 고려해 보십시오. foo.example.com 서버는 Domain 속성이 "example.com"인 쿠키를 설정할 수 있으며(때로는 bar.example.com이 설정한 기존 "example.com" 쿠키를 덮어쓸 수 있음), 사용자 에이전트는 그 쿠키를 bar.example.com에 대한 HTTP 요청에 포함할 것입니다. 최악의 경우 bar.example.com은 이 쿠키가 자체적으로 설정한 것인지 구별할 수 없습니다. foo.example.com 서버는 이 능력을 이용해 bar.example.com에 대한 공격을 시도할 수 있습니다.

Set-Cookie 헤더는 Path 속성을 지원하지만, Path 속성은 Set-Cookie 헤더에서 임의의 Path 속성을 사용자 에이전트가 수용하기 때문에 무결성 보호를 제공하지 않습니다. 예를 들어 http://example.com/foo/bar에 대한 응답이 "/qux" 경로의 Path 속성을 가진 쿠키를 설정할 수 있습니다. 따라서 서버는 동일 호스트의 서로 신뢰하지 않는 서비스들을 서로 다른 경로에서 운영하면서 쿠키를 보안 민감 정보 저장에 사용하는 일을 해선 안됩니다.

능동적인 네트워크 공격자는 또한 http://example.com/로부터의 응답을 가장하여 Set-Cookie 헤더를 주입함으로써 https://example.com/에 전송되는 Cookie 헤더에 쿠키를 주입할 수 있습니다. https 서버는 이러한 쿠키를 자사 HTTPS 응답에서 설정한 쿠키와 구별할 수 없습니다. 능동적 네트워크 공격자는 example.com이 HTTPS만 사용하더라도 이 능력을 이용해 공격을 시도할 수 있습니다.

서버는 쿠키 내용을 암호화하고 서명함으로써 이러한 공격을 부분적으로 완화할 수 있습니다. 그러나 암호화를 사용하더라도 공격자가 정품 example.com 서버로부터 받은 쿠키를 사용자의 세션에서 재전송(replay)할 수 있으므로 문제가 완전히 해결되지는 않습니다.

마지막으로, 공격자는 많은 수의 쿠키를 저장하여 사용자 에이전트가 쿠키를 삭제하도록 강제할 수 있습니다. 사용자 에이전트가 저장 한도에 도달하면 일부 쿠키를 제거해야 합니다. 서버는 사용자 에이전트가 쿠키를 보존할 것이라고 의존해서는 안됩니다.

8.7. DNS 의존

쿠키는 보안을 위해 도메인 네임 시스템(DNS)에 의존합니다. DNS가 부분적이거나 완전히 손상되면 쿠키 프로토콜은 애플리케이션이 요구하는 보안 속성을 제공하지 못할 수 있습니다.

9. IANA 고려사항

영구 메시지 헤더 필드 레지스트리(참조 [RFC3864])가 다음 등록으로 업데이트되었습니다.

9.3. Cookie2

헤더 필드 이름: Cookie2

적용 프로토콜: http

상태: obsoleted

저자/변경 관리자: IETF

명세 문서: [RFC2965]

9.4. Set-Cookie2

헤더 필드 이름: Set-Cookie2

적용 프로토콜: http

상태: obsoleted

저자/변경 관리자: IETF

명세 문서: [RFC2965]

10. 참고문헌

10.1. 규범적 참고문헌

[RFC1034]
Mockapetris, P., “Domain names - concepts and facilities”, STD 13, RFC 1034, November 1987.
[RFC1123]
Braden, R., “Requirements for Internet Hosts - Application and Support”, STD 3, RFC 1123, October 1989.
[RFC2119]
Bradner, S., “Key words for use in RFCs to Indicate Requirement Levels”, BCP 14, RFC 2119, March 1997.
[RFC2616]
Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, “Hypertext Transfer Protocol -- HTTP/1.1”, RFC 2616, June 1999.
[RFC3490]
Faltstrom, P., Hoffman, P., and A. Costello, “Internationalizing Domain Names in Applications (IDNA)”, RFC 3490, March 2003.
섹션 6.3에서 왜 폐기된 명세에 대한 규범적 참조가 필요한지 설명합니다.
[RFC4790]
Newman, C., Duerst, M., and A. Gulbrandsen, “Internet Application Protocol Collation Registry”, RFC 4790, March 2007.
[RFC5234]
Crocker, D., Ed. and P. Overell, “Augmented BNF for Syntax Specifications: ABNF”, STD 68, RFC 5234, January 2008.
[RFC5890]
Klensin, J., “Internationalized Domain Names for Applications (IDNA): Definitions and Document Framework”, RFC 5890, August 2010.
[USASCII]
American National Standards Institute, “Coded Character Set -- 7-bit American Standard Code for Information Interchange”, ANSI X3.4, 1986.

10.2. 참고/비규범적 참고문헌

[RFC2109]
Kristol, D. and L. Montulli, “HTTP State Management Mechanism”, RFC 2109, February 1997.
[RFC2965]
Kristol, D. and L. Montulli, “HTTP State Management Mechanism”, RFC 2965, October 2000.
[RFC2818]
Rescorla, E., “HTTP Over TLS”, RFC 2818, May 2000.
[Netscape]
Netscape Communications Corp., “Persistent Client State -- HTTP Cookies”, 1999, <http://web.archive.org/web/20020803110822/http://wp.netscape.com/newsref/std/cookie_spec.html>.
[Kri2001]
Kristol, D., “HTTP Cookies: Standards, Privacy, and Politics”, ACM Transactions on Internet Technology Vol. 1, #2, November 2001, <http://arxiv.org/abs/cs.SE/0105018>.
[RFC3629]
Yergeau, F., “UTF-8, a transformation format of ISO 10646”, STD 63, RFC 3629, November 2003.
[RFC4648]
Josefsson, S., “The Base16, Base32, and Base64 Data Encodings”, RFC 4648, October 2006.
[RFC3864]
Klyne, G., Nottingham, M., and J. Mogul, “Registration Procedures for Message Header Fields”, BCP 90, RFC 3864, September 2004.
[RFC5895]
Resnick, P. and P. Hoffman, “Mapping Characters for Internationalized Domain Names in Applications (IDNA) 2008”, RFC 5895, September 2010.
[UTS46]
Davis, M. and M. Suignard, “Unicode IDNA Compatibility Processing”, Unicode Technical Standards #46, 2010, <http://unicode.org/reports/tr46/>.
[CSRF]
Barth, A., Jackson, C., and J. Mitchell, “Robust Defenses for Cross-Site Request Forgery”, 2008, <http://portal.acm.org/citation.cfm?id=1455770.1455782>.
[Aggarwal2010]
Aggarwal, G., Burzstein, E., Jackson, C., and D. Boneh, “An Analysis of Private Browsing Modes in Modern Browsers”, 2010, <http://www.usenix.org/events/sec10/tech/full_papers/Aggarwal.pdf>.

부록 A. 감사의 글

이 문서는 RFC 2109([RFC2109])에서 많은 부분을 차용했습니다. 우리는 쿠키 사양화에 힘쓴 David M. Kristol과 Lou Montulli에게 큰 빚을 지고 있습니다. 특히 David M. Kristol은 IETF 절차를 헤쳐나가는 데 있어 귀중한 조언을 제공했습니다. 또한 Thomas Broyer, Tyler Close, Alissa Cooper, Bil Corry, corvid, Lisa Dusseault, Roy T. Fielding, Blake Frantz, Anne van Kesteren, Eran Hammer-Lahav, Jeff Hodges, Bjoern Hoehrmann, Achim Hoffmann, Georg Koppen, Dean McNamee, Alexey Melnikov, Mark Miller, Mark Pauley, Yngve N. Pettersen, Julian Reschke, Peter Saint-Andre, Mark Seaborn, Maciej Stachowiak, Daniel Stenberg, Tatsuhiro Tsujikawa, David Wagner, Dan Winship, Dan Witte에게 이 문서에 대한 귀중한 피드백을 주셔서 감사드립니다.

저자 주소

Adam Barth
University of California, Berkeley
Email: abarth@eecs.berkeley.edu
URI: http://www.adambarth.com/