RFC 6265 | Механизм управления состоянием HTTP

RFC 6265 | Механизм управления состоянием HTTP

Аннотация

Этот документ определяет поля заголовка «Cookie» и «Set-Cookie» в протоколе HTTP . Эти поля заголовков могут использоваться серверами HTTP для хранения состояния (называемых «cookies» куки-файлами) в пользовательских агентах HTTP, что позволяет серверам поддерживать сеанс с сохранением состояния по протоколу HTTP, который в основном не содержит состояний. Хотя файлы cookie имеют много исторических недостатков, которые ухудшают их безопасность и конфиденциальность, поля заголовков «Cookie» и «Set-Cookie» широко используются в Интернете. Этот документ сделал устаревшим RFC 2965.

Скачать оригинальную версию документа на английском языке RFC 6265 PDF

 

Оглавление

1. Введение
2. Соглашения
2.1. Критерии соответствия
2.2. Синтаксическая нотация
2.3. Терминология
3. Обзор
3.1. Примеры
4. Требования к серверу
4.1. Заголовок запроса «Set-Cookie»
4.1.1. Синтаксис
4.1.2. Семантика (ненормативная)
4.1.2.1. Атрибут Expires
4.1.2.2. Атрибут Max-Age
4.1.2.3. Атрибут Domain
4.1.2.4. Атрибут Path
4.1.2.5. Атрибут Secure
4.1.2.6. Атрибут HttpOnly
4.2. Заголовок «Cookie»
4.2.1. Синтаксис
4.2.2. Семантика
5. Требования к пользовательскому агенту
5.1. Субкомпонентные алгоритмы
5.1.1. Даты
5.1.2. Канонизированные имена хостов
5.1.3. Соответствие доменов
5.1.4. Пути и путь-совпадение (Paths and Path-Match)
5.2. Заголовок «Set-Cookie»
5.2.1. Атрибут Expires
5.2.2. Атрибут Max-Age
5.2.3. Атрибут Domain
5.2.4. Атрибут Path
5.2.5. Атрибут Secure
5.2.6. Атрибут HttpOnly
5.3. Модель хранения
5.4. Заголовок Cookie
6. Вопросы реализации
6.1. Ограничения
6.2. Интерфейсы прикладного программирования
6.3. Зависимость IDNA и миграция
7. Вопросы конфиденциальности
7.1. Сторонние файлы Cookies
7.2. Элементы управления пользователя
7.3. Срок годности
8. Вопросы безопасности
8.1. Обзор
8.2. Окружающая Основания
8.3. Очистить текст
8.4. Идентификаторы сеанса
8.5. Слабая конфиденциальность
8.6. Слабая целостность
8.7. Опора на DNS
9. Соображения IANA
9.1. Cookie
9.2. Set-Cookie
9.3. Cookie2
9.4. Set-Cookie2
10. Ссылки
10.1. Нормативные ссылки
10.2. Информационные ссылки
Приложение А. Благодарности
Адрес авторов

 

1. Введение

Этот документ определяет поля заголовка HTTP «Cookie» и «Set-Cookie». Используя поле заголовка «Set-Cookie», HTTP-сервер может передавать пары «имя / значение» и связанные метаданные (называемые куки-файлами) агенту пользователя. Когда пользовательский агент делает последующие запросы к серверу, пользовательский агент использует метаданные и другую информацию, чтобы определить, следует ли возвращать пары «имя / значение» в заголовке «Cookie».

Несмотря на свою простоту, куки-файлы (cookies) имеют ряд сложностей. Например, сервер указывает область действия для каждого файла cookie при отправке его агенту пользователя. Область действия указывает максимальное количество времени, в течение которого пользовательский агент должен возвращать cookie, серверы, на которые пользовательский агент должен возвращать cookie, и схемы URI, для которых применим cookie.

По историческим причинам куки-файлы содержат ряд нарушений безопасности и конфиденциальности. Например, сервер может указать, что данный файл cookie предназначен для «безопасных» подключений, но атрибут «Secure» не обеспечивает целостность в присутствии активного сетевого злоумышленника. Аналогично, файлы cookie для данного хоста совместно используются всеми портами на этом хосте, хотя обычная «политика одного и того же источника» (same-origin policy), используемая веб-браузерами, изолирует контент, извлекаемый через разные порты.

Для этой спецификации существует две аудитории:

  1. разработчики серверов, генерирующих файлы cookie
  2. разработчики пользовательских агентов, использующих файлы cookie

Чтобы максимизировать взаимодействие с пользовательскими агентами (браузерами), серверы ДОЛЖНЫ ограничивать себя хорошо управляемым профилем, определенным в разделе 4 при создании файлов cookie.

Пользовательские агенты ДОЛЖНЫ реализовывать более либеральные правила обработки, определенные в Разделе 5, чтобы максимизировать совместимость с существующими серверами, которые не соответствуют хорошо организованному профилю, определенному в Разделе 4.

Этот документ определяет синтаксис и семантику этих заголовков, поскольку они фактически используются в Интернете. В частности, этот документ не создает новый синтаксис или семантику помимо тех, которые используются сегодня. Рекомендации по созданию файлов cookie, представленные в Разделе 4, представляют собой предпочтительное подмножество текущего поведения сервера, и даже более либеральный алгоритм обработки файлов cookie, представленный в Разделе 5, не рекомендует все синтаксические и семантические варианты, используемые сегодня. Если существующее программное обеспечение существенно отличается от рекомендованного протокола, документ содержит примечание, объясняющее разницу.

До этого документа было как минимум три описания файлов cookie: так называемая «спецификация файлов cookie Netscape» [Netscape], RFC 2109 [RFC2109] и RFC 2965 [RFC2965]. Однако ни один из этих документов не описывает, как заголовки Cookie и Set-Cookie фактически используются в Интернете (исторический контекст см. В [Kri2001]). В отношении предыдущих спецификаций IETF механизмов управления состоянием HTTP этот документ запрашивает следующие действия:

  1. Измените статус [RFC2109] на Исторический (он уже был отменен [RFC2965])
  2. Измените статус [RFC2965] на Исторический
  3. Укажите, что [RFC2965] устарел в этом документе

В частности, при перемещении RFC 2965 в Historic и его устаревании в этом документе не рекомендуется использовать поля заголовков Cookie2 и Set-Cookie2.

 

2. Соглашения

2.1. Критерии соответствия

Ключевые слова «ОБЯЗАН — MUST», «НЕ ОБЯЗАН — MUST NOT», «ТРЕБУЕТСЯ — REQUIRED», «ДОЛЖЕН — SHALL», «НЕ ДОЛЖЕН — SHALL NOT», «СЛЕДУЕТ — SHOULD», «НЕ СЛЕДУЕТ — SHOULD NOT», «РЕКОМЕНДУЕТСЯ — RECOMMENDED», «НЕ РЕКОМЕНДУЕТСЯ — NOT RECOMMENDED», «ВОЗМОЖЕН — MAY» и «ДОПОЛНИТЕЛЬНО — OPTIONAL» в этом документе интерпретироваться как описано в [RFC2119 #] [RFC8174 #].

Требования, сформулированные в императиве как часть алгоритмов (такие как «убрать любые начальные пробелы» или «вернуть ложь и прервать эти шаги»), должны интерпретироваться со значением ключевого слова («ДОЛЖЕН», «СЛЕДУЕТ», « МОЖЕТ «и т. д.) Используется при внедрении алгоритма.

Требования соответствия, сформулированные как алгоритмы или конкретные шаги, могут быть реализованы любым способом, при условии, что конечный результат эквивалентен. В частности, алгоритмы, определенные в этой спецификации, предназначены для простоты понимания и не предназначены для обеспечения производительности.

2.2. Синтаксическая нотация

В этой спецификации используется расширенная нотация Бэкуса-Наура (ABNF) [RFC5234].

Следующие основные правила включены посредством ссылки, как определено в [RFC5234], Приложение B.1: ALPHA (буквы), CR (возврат каретки), CRLF (CR LF), CTLs (элементы управления), DIGIT (десятичное 0-9) , DQUOTE (двойная кавычка), HEXDIG (шестнадцатеричный 0-9 / AF / af), LF (перевод строки), NUL (нулевой октет), OCTET (любая 8-битная последовательность данных, кроме NUL), SP (пробел), HTAB (горизонтальная табуляция), CHAR (любой символ [USASCII]), VCHAR (любой видимый символ [USASCII]) и WSP (белый пробел).

Правило OWS (необязательный пробел) используется, когда МОЖЕТ появиться ноль или более линейных пробельных символов:

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 определен в разделе 5.1.2 [RFC2616].

Говорят, что две последовательности октетов нечувствительны к регистру и соответствуют друг другу тогда и только тогда, когда они эквивалентны в сопоставлении i; ascii-casemap, определенном в [RFC4790].

Термин строка (string) означает последовательность ненулевых октетов.

 

3. Обзор

В этом разделе описывается способ, с помощью которого исходный сервер отправляет информацию о состоянии пользовательскому агенту, а пользовательский агент возвращает информацию о состоянии исходному серверу.

Для сохранения состояния исходный сервер включает заголовок Set-Cookie в ответ HTTP. В последующих запросах пользовательский агент возвращает заголовок запроса Cookie на исходный сервер. Заголовок Cookie содержит файлы cookie, которые пользовательский агент получил в предыдущих заголовках Set-Cookie. Исходный сервер может игнорировать заголовок Cookie или использовать его содержимое для определенной прикладной цели.

Исходные серверы МОГУТ отправить заголовок ответа Set-Cookie с любым ответом. Пользовательские агенты МОГУТ игнорировать заголовки Set-Cookie, содержащиеся в ответах с кодами состояния на 100 уровней, но ДОЛЖНЫ обрабатывать заголовки Set-Cookie, содержащиеся в других ответах (включая ответы с кодами состояния на 400 и 500 уровнях). Исходный сервер может включать несколько полей заголовка Set-Cookie в одном ответе. Наличие поля заголовка Cookie или Set-Cookie не мешает HTTP-кешам хранить и повторно использовать ответ.

Исходным серверам НЕ СЛЕДУЕТ складывать несколько полей заголовка Set-Cookie в одно поле заголовка. Обычный механизм свертывания полей заголовков HTTP (т. е. как определено в [RFC2616]) может изменить семантику поля заголовка Set-Cookie, поскольку символ %x2C («,») используется Set-Cookie способом, который конфликтует с таким складыванием.

3.1. Примеры

Используя заголовок Set-Cookie, сервер может отправить пользовательскому агенту короткую строку в ответе HTTP, которую пользовательский агент будет возвращать в будущих HTTP-запросах, которые находятся в области действия cookie. Например, сервер может отправить агенту пользователя «идентификатор сеанса» (session identifier) с именем SID со значением 31d4d96e407aad42. Затем пользовательский агент возвращает идентификатор сеанса в последующих запросах.

== Server -> User Agent ==
Set-Cookie: SID=31d4d96e407aad42
== User Agent -> Server ==
Cookie: SID=31d4d96e407aad42

Сервер может изменить область cookie по умолчанию, используя атрибуты Path и Domain. Например, сервер может дать команду агенту пользователя вернуть cookie каждому пути и каждому поддомену example.com.

== Server -> User Agent ==
Set-Cookie: SID=31d4d96e407aad42; Path=/; Domain=example.com
== User Agent -> Server ==
Cookie: SID=31d4d96e407aad42

Как показано в следующем примере, сервер может хранить несколько файлов cookie в пользовательском агенте. Например, сервер может сохранить идентификатор сеанса, а также предпочтительный язык пользователя, возвращая два поля заголовка Set-Cookie. Обратите внимание, что сервер использует атрибуты Secure и HttpOnly для обеспечения дополнительной защиты для более чувствительного идентификатора сеанса (см. Раздел 4.1.2.)

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

Обратите внимание, что заголовок Cookie выше содержит два куки-файла, один с именем SID и один с именем lang. Если сервер желает, чтобы пользовательский агент сохранял cookie в течение нескольких «сеансов» (например, перезапуска агента пользователя), сервер может указать дату истечения срока действия в атрибуте Expires. Обратите внимание, что пользовательский агент может удалить cookie до истечения срока его действия, если хранилище файлов cookie пользовательского агента превышает его квоту или если пользователь вручную удаляет cookie сервера.

== Server -> User Agent ==
Set-Cookie: lang=en-US; Expires=Wed, 09 Jun 2021 10:18:14 GMT
== User Agent -> Server ==
Cookie: SID=31d4d96e407aad42; lang=en-US

Наконец, чтобы удалить куки-файлы, сервер возвращает заголовок Set-Cookie с датой истечения в прошлом. Сервер успешно удалит cookie, только если атрибут Path и Domain в заголовке Set-Cookie соответствуют значениям, использованным при создании cookie.

== Server -> User Agent ==
Set-Cookie: lang=; Expires=Sun, 06 Nov 1994 08:49:37 GMT
== User Agent -> Server ==
Cookie: SID=31d4d96e407aad42

 

4. Требования к серверу

В этом разделе описывается синтаксис и семантика корректного профиля заголовков Cookie и Set-Cookie.

HTTP-заголовок ответа Set-Cookie используется для отправки файлов cookie с сервера пользовательскому агенту.

4.1.1. Синтаксис

Неформально заголовок ответа Set-Cookie содержит имя заголовка «Set-Cookie», за которым следуют «:» и cookie. Каждый файл cookie начинается с пары имя-значение (name-value), за которой следует ноль или более пар атрибут-значение (attribute-value). Серверы НЕ ДОЛЖНЫ отправлять заголовки Set-Cookie, которые не соответствуют следующей грамматике:

set-cookie-header = "Set-Cookie:" SP set-cookie-string

set-cookie-string = cookie-pair *( ";" SP cookie-av )

cookie-pair = cookie-name "=" cookie-value

cookie-name = token

cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE )

cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E
; US-ASCII characters excluding CTLs,
; whitespace DQUOTE, comma, semicolon,
; and backslash

token = <token, defined in [RFC2616], Section 2.2>

cookie-av = expires-av / max-age-av / domain-av / path-av / secure-av / httponly-av / extension-av

expires-av = "Expires=" sane-cookie-date

sane-cookie-date = <rfc1123-date, defined in [RFC2616], Section 3.3.1>

max-age-av = "Max-Age=" non-zero-digit *DIGIT
; In practice, both expires-av and max-age-av
; are limited to dates representable by the
; user agent.

non-zero-digit = %x31-39
; digits 1 through 9

domain-av = "Domain=" domain-value

domain-value = <subdomain>
; defined in [RFC1034], Section 3.5, as
; enhanced by [RFC1123], Section 2.1

path-av = "Path=" path-value

path-value = <any CHAR except CTLs or ";">

secure-av = "Secure"

httponly-av = "HttpOnly"

extension-av = <any CHAR except CTLs or ";">

Обратите внимание, что некоторые из приведенных выше грамматических терминов ссылаются на документы, в которых используются грамматические обозначения, отличные от этого документа (в котором используется ABNF из [RFC5234]).

Семантика значения cookie не определяется этим документом.

Чтобы максимизировать совместимость с пользовательскими агентами, серверам, которые хотят хранить произвольные данные в значении cookie, СЛЕДУЕТ кодировать эти данные, например, с использованием Base64 [RFC4648].

Части set-cookie-string, созданные термином cookie-av, называются атрибутами. Чтобы обеспечить максимальную совместимость с пользовательскими агентами, серверам НЕ СЛЕДУЕТ создавать два атрибута с одинаковыми именами в одной и той же строке set-cookie. (См. Раздел 5.3 о том, как пользовательские агенты обрабатывают этот случай.)

Серверы НЕ ДОЛЖНЫ включать более одного поля заголовка Set-Cookie в один и тот же ответ с одним и тем же именем cookie. (См. Раздел 5.2 о том, как пользовательские агенты обрабатывают этот случай.)

Если сервер отправляет несколько ответов, содержащих заголовки Set-Cookie, одновременно агенту пользователя (например, при обмене данными с агентом пользователя по нескольким сокетам), эти ответы создают «состояние гонки» (race condition), которое может привести к непредсказуемому поведению.

ПРИМЕЧАНИЕ. Некоторые существующие пользовательские агенты различаются по интерпретации двухзначных лет. Чтобы избежать проблем совместимости, серверы ДОЛЖНЫ использовать формат даты RFC 1123, для которого требуется год из четырех цифр.

ПРИМЕЧАНИЕ. Некоторые пользовательские агенты хранят и обрабатывают даты в файлах cookie в виде 32-битных значений time_t UNIX. Ошибки реализации в библиотеках, поддерживающих обработку time_t в некоторых системах, могут привести к тому, что такие пользовательские агенты будут некорректно обрабатывать даты после 2038 года.

4.1.2. Семантика (не нормативный раздел)

В этом разделе описана упрощенная семантика заголовка Set-Cookie. Эта семантика достаточно подробна, чтобы быть полезной для понимания наиболее распространенного использования файлов cookie серверами. Полная семантика описана в разделе 5.

Когда пользовательский агент получает заголовок Set-Cookie, пользовательский агент сохраняет файл cookie вместе со своими атрибутами. Впоследствии, когда пользовательский агент делает HTTP-запрос, пользовательский агент включает в заголовок Cookie применимые файлы cookie с истекшим сроком действия.

Если пользовательский агент получает новый файл cookie с такими же именем файла cookie, значением домена и значением пути, что и файл cookie, который он уже сохранил, существующий файл cookie удаляется и заменяется новым файлом cookie. Обратите внимание, что серверы могут удалять файлы cookie, отправляя пользовательскому агенту новый файл cookie с атрибутом Expires со значением в прошлом.

Если атрибуты cookie не указывают на иное, cookie возвращается только исходному серверу (а не, например, каким-либо поддоменам), и срок его действия истекает в конце текущего сеанса (как определено агентом пользователя). Пользовательские агенты игнорируют нераспознанные атрибуты cookie (но не весь cookie).

4.1.2.1. Атрибут Expires

Атрибут Expires указывает максимальный срок действия куки, представленный в виде даты и времени истечения срока действия куки. Пользовательский агент не обязан сохранять cookie, пока не истечет указанная дата. Фактически, пользовательские агенты часто выгружают куки из-за нехватки памяти или проблем с конфиденциальностью.

4.1.2.2. Атрибут Max-Age

Атрибут Max-Age указывает максимальное время жизни куки-файла, представленное в виде количества секунд до истечения срока действия куки. Пользовательский агент не обязан сохранять cookie в течение указанного периода времени. Фактически, пользовательские агенты часто выгружают куки из-за нехватки памяти или проблем с конфиденциальностью.

ПРИМЕЧАНИЕ. Некоторые существующие пользовательские агенты не поддерживают атрибут Max-Age. Пользовательские агенты, которые не поддерживают атрибут Max-Age, игнорируют атрибут.

Если cookie имеет атрибуты Max-Age и Expires, атрибут Max-Age имеет приоритет и контролирует дату истечения срока действия cookie. Если cookie не имеет ни атрибута Max-Age, ни Expires, пользовательский агент будет сохранять cookie до тех пор, пока «текущий сеанс не закончится» (the current session is over) (как определено пользовательским агентом).

4.1.2.3. Атрибут Domain

Атрибут Domain указывает те хосты, на которые будет отправлен куки. Например, если значение атрибута «Domain» равно «example.com», пользовательский агент будет включать cookie-файл в заголовок «cookie» при отправке HTTP-запросов на example.com, www.example.com и www.corp.example. ком. (Обратите внимание, что ведущий %x2E («.»), Если он присутствует, игнорируется, даже если этот символ не разрешен, но завершающий %x2E («.»), Если он присутствует, заставит пользовательский агент игнорировать атрибут. ) Если на сервере не указан атрибут Domain, пользовательский агент вернет cookie только на исходный сервер.

ПРЕДУПРЕЖДЕНИЕ: Некоторые существующие пользовательские агенты обрабатывают отсутствующий атрибут Domain так, как если бы атрибут Domain присутствовал и содержал текущее имя хоста. Например, если example.com возвращает заголовок Set-Cookie без атрибута Domain, эти пользовательские агенты также будут ошибочно отправлять cookie на www.example.com.

Пользовательский агент будет отклонять куки, если атрибут Domain не указывает область для куки, которая будет включать исходный сервер. Например, пользовательский агент примет файл cookie с атрибутом домена «example.com» или «foo.example.com» от foo.example.com, но пользовательский агент не примет файл cookie с атрибутом домена «bar.example.com» или «baz.foo.example.com».

ПРИМЕЧАНИЕ. В целях безопасности многие пользовательские агенты настроены на отклонение атрибутов Domain, соответствующих «общедоступным суффиксам» (public suffixes). Например, некоторые пользовательские агенты будут отклонять атрибуты домена «com» или «co.uk». (См. Раздел 5.3 для получения дополнительной информации.)

4.1.2.4. Атрибут Path

Область действия каждого файла cookie ограничена набором путей, управляемых атрибутом Path. Если сервер пропускает атрибут Path, агент пользователя будет использовать «каталог» (directory) компонента пути request-uri в качестве значения по умолчанию. (Подробнее см. Раздел 5.1.4.)

Пользовательский агент будет включать куки в HTTP-запрос, только если часть пути request-uri совпадает (или является подкаталогом) атрибута Path куки, где символ %x2F («/») интерпретируется как разделитель каталогов.

Хотя это кажется полезным для изоляции файлов cookie между различными путями в пределах данного хоста, на атрибут Path нельзя полагаться в целях безопасности (см. Раздел 8).

4.1.2.5. Атрибут Secure

Атрибут Secure ограничивает область действия cookie «защищенными» (secure) каналами (где «secure» определяется агентом пользователя). Когда cookie имеет атрибут Secure, пользовательский агент будет включать cookie в запрос HTTP только в том случае, если запрос передается по безопасному каналу (обычно HTTP по протоколу безопасности транспортного уровня (TLS) [RFC2818]).

Хотя этот атрибут полезен для защиты файлов cookie от активных сетевых злоумышленников, он защищает только конфиденциальную информацию о файлах cookie. Активный сетевой злоумышленник может перезаписать безопасные куки-файлы из небезопасного канала, нарушив их целостность (более подробную информацию см. В разделе 8.6).

4.1.2.6. Атрибут HttpOnly

Атрибут HttpOnly ограничивает область применения cookie HTTP-запросами. В частности, атрибут инструктирует пользовательский агент пропускать куки при предоставлении доступа к куки через API «не HTTP»(non-HTTP) (например, API веб-браузера, который предоставляет куки для скриптов).

Обратите внимание, что атрибут HttpOnly не зависит от атрибута Secure: cookie может иметь атрибут HttpOnly и Secure.

4.2.1. Синтаксис

Пользовательский агент отправляет сохраненные куки на сервер происхождения в заголовке Cookie. Если сервер соответствует требованиям в Разделе 4.1 (а пользовательский агент соответствует требованиям в Разделе 5), пользовательский агент отправит заголовок Cookie, который соответствует следующей грамматике:

cookie-header = "Cookie:" OWS cookie-string OWS

cookie-string = cookie-pair *( ";" SP cookie-pair )

4.2.2. Семантика

Каждая пара cookie представляет собой cookie, сохраняемый агентом пользователя. Пара cookie содержит имя cookie (name) и значение cookie (value), которые пользовательский агент получил в заголовке Set-Cookie.

Обратите внимание, что атрибуты cookie не возвращаются. В частности, сервер не может определить только из заголовка Cookie, когда истечет срок действия файла cookie, для каких хостов файл cookie действителен, для каких путей файл cookie действителен, или был ли файл cookie установлен с атрибутами Secure или HttpOnly.

Семантика отдельных cookie-файлов в заголовке Cookie не определяется этим документом. Ожидается, что серверы будут наполнять эти файлы cookie семантикой для конкретного приложения.

Хотя cookie-файлы сериализуются линейно в заголовке Cookie, серверы НЕ ДОЛЖНЫ полагаться на порядок сериализации. В частности, если заголовок Cookie содержит два cookie с одним и тем же именем (например, которые были установлены с разными атрибутами Path или Domain), серверы НЕ ДОЛЖНЫ полагаться на порядок, в котором эти cookie появляются в заголовке.

 

5. Требования к пользовательскому агенту

В этом разделе указываются заголовки Cookie и Set-Cookie достаточно подробно, чтобы пользовательский агент, реализующий эти требования, мог точно взаимодействовать с существующими серверами (даже теми, которые не соответствуют хорошо организованному профилю, описанному в Разделе 4).

Пользовательский агент может применять больше ограничений, чем указано в данном документе (например, в целях повышения безопасности); однако эксперименты показали, что такая строгость снижает вероятность того, что пользовательский агент сможет взаимодействовать с существующими серверами.

5.1. Субкомпонентные алгоритмы

В этом разделе определяются некоторые алгоритмы, используемые пользовательскими агентами для обработки определенных подкомпонентов заголовков Cookie и Set-Cookie.

5.1.1. Даты

Пользовательский агент ДОЛЖЕН использовать алгоритм, эквивалентный следующему алгоритму, для анализа даты cookie. Обратите внимание, что различные логические флаги, определенные как часть алгоритма (то есть найденное время (found-time), найденный день месяца (foundday-of-month), найденный месяц (found-month), найденный год (found-year)) изначально «не установлены».

Пункт № 1

Используя приведенную ниже грамматику, разделите дату cookie на токены даты.

cookie-date = *delimiter date-token-list *delimiter
date-token-list = date-token *( 1*delimiter date-token )
date-token = 1*non-delimiter

delimiter = %x09 / %x20-2F / %x3B-40 / %x5B-60 / %x7B-7E
non-delimiter = %x00-08 / %x0A-1F / DIGIT / «:» / ALPHA / %x7F-FF
non-digit = %x00-2F / %x3A-FF

day-of-month = 1*2DIGIT ( non-digit *OCTET )
month = ( «jan» / «feb» / «mar» / «apr» / «may» / «jun» / «jul» / «aug» / «sep» / «oct» / «nov» / «dec» ) *OCTET

year = 2*4DIGIT ( non-digit *OCTET )
time = hms-time ( non-digit *OCTET )
hms-time = time-field «:» time-field «:» time-field
time-field = 1*2DIGIT

Пункт № 2

Обрабатывать каждый токен даты последовательно в порядке, указанном токенами появляются в cookie-дате:

  1. Если флаг найденного времени не установлен и токен совпадает с производством времени, установите флаг найденного времени и задайте значение часа, значение минуты и второе значение для чисел, обозначаемых цифрами в маркере даты соответственно. Пропустите оставшиеся подэтапы и перейдите к следующему токену даты.
  2. Если флаг найденного дня месяца не установлен и маркер даты совпадает с производством дня месяца, установите флаг найденного дня месяца и установите число дня месяца равным числу обозначается датой-токеном. Пропустите оставшиеся подэтапы и перейдите к следующему токену даты.
  3. Если флаг найденного месяца не установлен, а маркер даты совпадает с производительностью месяца, установите флаг найденного месяца и установите значение месяца, обозначенное маркером даты. Пропустите оставшиеся подэтапы и перейдите к следующему токену даты.
  4. Если флаг найденного года не установлен и маркер даты совпадает с производством года, установите флаг найденного года и установите значение года равным числу, обозначенному маркером даты. Пропустите оставшиеся подэтапы и перейдите к следующему токену даты.
Пункт № 3

Если значение года больше или равно 70 и меньше или равно 99, увеличьте значение года на 1900.

Пункт № 4

Если значение года больше или равно 0 и меньше или равный 69, увеличить значение года на 2000.

ПРИМЕЧАНИЕ. Некоторые существующие пользовательские агенты по-разному интерпретируют двузначные годы.

Пункт № 5

Прервите эти шаги и не сможете проанализировать дату cookie, если:

  • по крайней мере один из флагов «найденный день месяца», «найденный месяц», «найденный год» или «найденное время» не установлен
  • значение дня месяца меньше 1 или больше 31
  • значение года меньше 1601
  • значение часа больше 23
  • минутное значение больше 59
  • второе значение больше 59

(Обратите внимание, что дополнительные секунды не могут быть представлены в этом синтаксисе.)

Пункт № 6

Пусть parsed-cookie-date будет датой, чей день месяца, месяц, год, час, минута и секунда (в UTC) являются значением дня месяца, значением месяца, значением года, значение часа, значение минуты и второе значение соответственно. Если такой даты не существует, прервите эти шаги и не сможете проанализировать дату cookie.

Пункт № 7

Возвращает parsed-cookie-date как результат этого алгоритма.

5.1.2. Канонизированные имена хостов

Канонизированное имя хоста — это строка, сгенерированная следующим алгоритмом:

  1. Преобразуйте имя хоста в последовательность отдельных меток доменных имен.
  2. Преобразуйте каждую метку, которая не является меткой незарезервированного LDH (NR-LDH), в метку A (см. Раздел 2.3.2.1 [RFC5890] для первой и последней) или в «метку punycode» ( метка, полученная в результате преобразования «ToASCII» в Разделе 4 [RFC3490]), в зависимости от случая (см. Раздел 6.3 данной спецификации).
  3. Объедините получающиеся метки, разделенные символом %x2E («.»).

5.1.3. Соответствие доменов

Строка domain соответствует данной доменной строке, если выполняется хотя бы одно из следующих условий:

  • Строка домена и строка идентичны. (Обратите внимание, что и строка домена, и строка будут канонизированы в нижний регистр на этом этапе.)
  • Выполнены все следующие условия:
      1. Строка домена является суффиксом строки
      2. Последний символ строки, который не включен в строку домена, является символом %x2E («.»)
      3. Строка является именем хоста (то есть не IP-адресом)

5.1.4. Пути и путь-совпадение (Paths and Path-Match)

Пользовательский агент ДОЛЖЕН использовать алгоритм, эквивалентный следующему алгоритму, для вычисления пути cookie по умолчанию:

  1. Пусть uri-path будет частью пути request-uri, если такая часть существует (и пустым в противном случае). Например, если request-uri содержит только путь (и необязательную строку запроса), тогда uri-path является этим путем (без символа %x3F («?») Или строки запроса), и если request-uri содержит полный absoluteURI, uri-path является компонентом пути этого URI.
  2. Если uri-path пустой или если первый символ uri-path не является символом %x2F («/»), выведите %x2F («/») и пропустите оставшиеся шаги.
  3. Если uri-path содержит не более одного символа %x2F («/»), выведите %x2F («/») и пропустите оставшийся шаг.
  4. Выведите символы uri-path от первого символа до самого правого %x2F («/»), но не включая его.

Путь request-path совпадает с заданным путём cookie, если выполняется хотя бы одно из следующих условий:

  • o Путь cookie и путь запроса идентичны
  • o Путь cookie является префиксом пути запроса, а последний символ пути cookie %x2F («/»)
  • o Путь cookie является префиксом пути запроса, и первый символ пути запроса, который не включен в путь cookie, является символом %x2F («/»)

Когда пользовательский агент получает поле заголовка Set-Cookie в HTTP-ответе, пользовательский агент МОЖЕТ полностью игнорировать поле заголовка Set-Cookie. Например, пользовательский агент может захотеть заблокировать ответы на «сторонние» запросы от настройки файлов cookie (см. Раздел 7.1).

Если пользовательский агент не полностью игнорирует поле заголовка Set-Cookie, пользовательский агент ДОЛЖЕН проанализировать значение поля поля заголовка Set-Cookie как строку set-cookie (определенную ниже).

ПРИМЕЧАНИЕ. Алгоритм, приведенный ниже, является более разрешающим, чем грамматика в разделе 4.1. Например, алгоритм удаляет начальные и конечные пробелы из имени и значения файла cookie (но сохраняет внутренние пробелы), тогда как грамматика в разделе 4.1 запрещает пробелы в этих позициях. Пользовательские агенты используют этот алгоритм для взаимодействия с серверами, которые не следуют рекомендациям в Разделе 4.

Пользовательский агент ДОЛЖЕН использовать алгоритм, эквивалентный следующему алгоритму, для анализа «set-cookie-string«:

  1. Если set-cookie-string содержит символ %x3B («;»):
    1. Строка пары имя/значение (name-value-pair) состоит из символов до, но не включая, первого %x3B («;»), а атрибуты unparsed состоят из оставшейся части строки set-cookie (включая %x3B («; «) обсуждаемый).
      В противном случае:
      Строка name-value-pair состоит из всех символов, содержащихся в set-cookie-string, а unparsed-attributes — пустая строка.
  2. Если в строке name-value-pair отсутствует символ %x3D («=»), полностью игнорируйте строку set-cookie-string.
  3. Строка имени (возможно, пустая) состоит из символов до, но не включая первый символ %x3D («=»), а строка значения (возможно, пустая) состоит из символов после первого %x3D («=») ) символа.
  4. Удалите все начальные или конечные символы WSP из строки имени и строки значения.
  5. Если строка имени пуста, полностью игнорируйте set-cookie-string.
  6. Cookie-name — это строка имени, а cookie-value — строка значения.

Пользовательский агент ДОЛЖЕН использовать алгоритм, эквивалентный следующему алгоритму, для анализа unparsed-атрибутов:

  1. Если строка unparsed-attribute пуста, пропустите остальные шаги
  2. Откажитесь от первого символа unparsed-attribute (который будет символом %x3B («;»))
  3. Если оставшиеся непарсированные атрибуты содержат символ %x3B («;»):
      1. Использовать символы unparsed-атрибутов вплоть до, но не включая, первого символа %x3B («;»)
        В противном случае: Поглотить остаток от unparsed-атрибутов
        Пусть строка cookie-av будет символами, используемыми на этом шаге
  4. Если строка cookie-av содержит символ %x3D («=»):
      1. (Возможно пустая) строка имени атрибута состоит из символов до, но не включая первый символ %x3D («=»), а (возможно пустая) строка значения атрибута состоит из символов после первого %x3D («=») символ
        В противном случае: Строка имени атрибута состоит из всей строки cookie-av, а строка значения атрибута пуста
  5. Удалите все начальные или конечные символы WSP из строки имени атрибута и строки значения атрибута
  6. Обработайте имя-атрибута и значение-атрибута в соответствии с требованиями следующих подразделов. (Обратите внимание, что атрибуты с нераспознанными именами атрибутов игнорируются.)
  7. Вернитесь к шагу 1 этого алгоритма

Когда пользовательский агент заканчивает анализ строки set-cookie, говорят, что пользовательский агент «получает cookie» от request-uri с именем cookie-name, значением cookie-value и атрибутами cookie-attributete-list. (См. Раздел 5.3 для дополнительных требований, вызванных получением куки.)

5.2.1. Атрибут Expires

Если имя атрибута без учета регистра совпадает со строкой «Expires», пользовательский агент ДОЛЖЕН обработать cookie-av следующим образом.

Пусть время истечения будет результатом анализа значения атрибута как даты cookie (см. Раздел 5.1.1).

Если значение атрибута не удалось проанализировать как дату файла cookie, игнорируйте cookie-av.

Если время истечения больше, чем последняя дата, которую пользовательский агент может представлять, пользовательский агент МОЖЕТ заменить время истечения на последнюю представляемую дату.

Если время истечения раньше, чем самая ранняя дата, которую пользовательский агент может представлять, пользовательский агент МОЖЕТ заменить время истечения самой ранней представимой датой.

Добавьте атрибут в список cookie-attribute-list с атрибутом-именем Expires и значением-атрибутом expiry-time.

5.2.2. Атрибут Max-Age

Если имя атрибута без учета регистра совпадает со строкой «Max-Age», пользовательский агент ДОЛЖЕН обработать cookie-av следующим образом.

Если первый символ значения атрибута не DIGIT или символ «-», игнорируйте cookie-av.

Если остаток атрибута-значения содержит не-ЦИФРОВОЙ символ, игнорируйте cookie-av.

Пусть delta-seconds будет значением атрибута, преобразованным в целое число.

Если дельта-секунды меньше или равны нулю (0), пусть время истечения будет самой ранней представимой датой и временем. В противном случае пусть время истечения будет текущей датой и временем плюс дельта-секунды секунды.

Добавьте атрибут в список атрибутов cookie с именем-атрибута Max-Age и значением-атрибутом expiry-time.

5.2.3. Атрибут Domain

Если имя атрибута без учета регистра совпадает со строкой «Домен», пользовательский агент ДОЛЖЕН обработать cookie-av следующим образом.

Если значение атрибута пусто, поведение не определено. Однако пользовательский агент ДОЛЖЕН полностью игнорировать cookie-av.

Если первым символом строки значения атрибута является %x2E («.»):

  • Пусть cookie-домен будет значением атрибута без начального символа %x2E («.»).

В противном случае:

  • Пусть cookie-домен будет полным значением атрибута.

Конвертировать cookie-домен в нижний регистр.

Добавьте атрибут в список атрибутов cookie с именем атрибута Domain и значением атрибута cookie-domain.

5.2.4. Атрибут Path

Если имя атрибута без учета регистра совпадает со строкой «Путь», пользовательский агент ДОЛЖЕН обработать cookie-av следующим образом.

Если значение атрибута пусто или если первый символ значения атрибута не %x2F («/»):

  • Пусть cookie-путь будет путьом по умолчанию.

В противном случае:

  • Пусть cookie-путь будет значением атрибута.

Добавьте атрибут в список атрибутов cookie с именем атрибута Path и значением атрибута cookie-path.

5.2.5. Атрибут Secure

Если имя атрибута без учета регистра совпадает со строкой «Secure», пользовательский агент ДОЛЖЕН добавить атрибут в список cookie-attribute-list с атрибутом-именем Secure и пустым значением-атрибута.

5.2.6. Атрибут HttpOnly

Если имя атрибута без учета регистра совпадает со строкой «HttpOnly», пользовательский агент ДОЛЖЕН добавить атрибут в список атрибутов cookie с именем атрибута HttpOnly и пустым значением атрибута.

5.3. Модель хранения

Пользовательский агент хранит следующие поля для каждого куки: имя, значение, время истечения, домен, путь, время создания, время последнего доступа, постоянный флаг, флаг только для хоста, флаг только для безопасности и HTTP-only флаг.

Когда пользовательский агент «получает cookie» от request-uri с именем cookie-name, значением cookie-value и атрибутами cookie-attributete-list, пользовательский агент ДОЛЖЕН обрабатывать cookie следующим образом:

Пункт № 01

Пользовательский агент МОЖЕТ полностью игнорировать полученный файл cookie. Например, пользовательский агент может захотеть заблокировать получение файлов cookie от «сторонних» ответов, или пользовательский агент может не захотеть хранить файлы cookie, размер которых превышает некоторый.

Пункт № 02

Создайте новый cookie с именем cookie-name, значением cookie-value. Установите время создания и время последнего доступа к текущей дате и времени.

Пункт № 03

Если список атрибутов cookie содержит атрибут с именем-атрибута «Max-Age»:

  • Установите для постоянного файла cookie значение true
  • Установите время истечения срока действия файла cookie для значения атрибута последнего атрибута в списке атрибутов cookie с именем атрибута «Max-Age»

В противном случае, если список атрибутов cookie содержит атрибут с именем атрибута «Expires» (и не содержит атрибут с именем атрибута «Max-Age»):

  • Установите для постоянного файла cookie значение true
  • Установите время истечения срока действия файла cookie для значения атрибута последнего атрибута в списке атрибутов файла cookie с именем атрибута «Истекает»

В противном случае

  • Установите для постоянного файла cookie значение false
  • Установите время истечения срока действия cookie до самой последней представимой даты

Пункт № 04

Если список атрибутов cookie содержит атрибут с именем атрибута «Домен»:

  • Пусть domain-attribute будет значением атрибута последнего атрибута в списке cookie-attribute-list с именем атрибута «Domain»

В противном случае

  • Пусть domain-attribute будет пустой строкой

Пункт № 05

Если пользовательский агент настроен на отклонение «общедоступных суффиксов», а атрибут domain является общедоступным суффиксом:

  • Если атрибут домена идентичен канонизированному запросу-хосту: Пусть domain-attribute будет пустой строкой
  • Иначе: Полностью игнорируйте куки и прекратите эти шаги
  • ПРИМЕЧАНИЕ. «Публичный суффикс» (public suffix) — это домен, контролируемый общедоступным реестром, таким как «com», «co.uk» и «pvt.k12.wy.us». Этот шаг важен для предотвращения нарушения целостности сайта example.com с помощью атаки на server.com путем установки файла cookie с атрибутом домена «com». К сожалению, набор общедоступных суффиксов (также известных как «домены, управляемые реестром» (registry controlled domains)) со временем меняется. Если возможно, пользовательские агенты ДОЛЖНЫ использовать обновленный общедоступный список суффиксов, такой как список, поддерживаемый проектом Mozilla по адресу https://publicsuffix.org.

Пункт № 06

Если атрибут домена не пуст:

  • Если канонизированный хост-запрос не соответствует домену-атрибуту домена: Полностью игнорируйте куки и прекратите эти шаги.
  • В противном случае: Установите флаг cookie только для хоста в значение false. Установите домен cookie в атрибут domain.

В противном случае:

  • Установите для файла cookie только для хоста флаг true.
  • Установите домен cookie для канонизированного хоста запроса.

Пункт № 07

Если список атрибутов cookie содержит атрибут с именем атрибута «Path», задайте для пути cookie значение атрибута последнего атрибута в списке атрибутов cookie с именем атрибута «Path». В противном случае установите путь к файлу cookie к пути по умолчанию для request-uri.

Пункт № 08

Если список атрибутов cookie содержит атрибут с именем атрибута «Secure», установите для флага «только для cookie» значение true. В противном случае установите для cookie-only-only-flag значение false.

Пункт № 09

Если список атрибутов cookie содержит атрибут с именем атрибута «HttpOnly», установите для http-only-flag cookie значение true. В противном случае установите для http-only-flag файла cookie значение false.

Пункт № 10

Если файл cookie был получен от API «не HTTP» и установлен флаг cookie «только для HTTP», прервите эти шаги и полностью проигнорируйте этот файл.

Пункт № 11

Если хранилище куки-файлов содержит cookie с тем же именем, доменом и путём; как только что созданный файл cookie:

  1. Пусть old-cookie будет существующим cookie с тем же именем, доменом и путем, что и вновь созданный cookie. (Обратите внимание, что этот алгоритм поддерживает инвариант, что существует не более одного такого cookie.)
  2. Если вновь созданный файл cookie был получен из API «не HTTP» и установлен флаг «только для cookie» старого файла cookie, отмените эти шаги и полностью игнорируйте вновь созданный файл cookie.
  3. Обновите время создания вновь созданного файла cookie, чтобы оно соответствовало времени создания старого файла cookie.
  4. Удалите старый cookie из хранилища cookie.

Пункт № 12

Вставьте только что созданный файл cookie в хранилище


Срок действия файла cookie истек, если срок действия файла cookie истек в прошлом.

Пользовательский агент ДОЛЖЕН удалить все файлы cookie с истекшим сроком хранения из хранилища файлов cookie, если в любое время в хранилище файлов cookie существует файл с истекшим сроком действия.

В любое время пользовательский агент МОЖЕТ «удалить лишние куки» из хранилища куки-файлов, если количество куки, разделяющих поле домена, превышает некоторую верхнюю границу, определенную реализацией (например, 50 куки).

В любое время пользовательский агент МОЖЕТ «удалить лишние куки» из хранилища куки-файлов, если хранилище куки-файлов превышает некоторую заранее определенную верхнюю границу (например, 3000 куки-файлов).

Когда пользовательский агент удаляет лишние куки из хранилища куки, пользовательский агент ДОЛЖЕН удалять куки в следующем порядке приоритета:

  1. Истекшие куки
  2. Файлы cookie, которые совместно используют поле домена с более чем заранее определенным числом других файлов cookie
  3. Все куки

Если два файла cookie имеют одинаковый приоритет удаления, пользовательский агент ДОЛЖЕН удалить файл cookie с самой ранней датой последнего доступа.

Когда «текущий сеанс завершен» (the current session is over) (как определено пользовательским агентом), пользовательский агент ДОЛЖЕН удалить из хранилища файлов cookie все файлы cookie с постоянным флагом, установленным в false.

Пользовательский агент включает сохраненные куки в заголовок HTTP-запроса Cookie.

Когда пользовательский агент генерирует HTTP-запрос, пользовательский агент НЕ ДОЛЖЕН прикреплять более одного поля заголовка Cookie.

Пользовательский агент МОЖЕТ полностью пропустить заголовок Cookie. Например, пользовательский агент может пожелать заблокировать отправку файлов cookie во время «сторонних» запросов от настройки файлов cookie (см. Раздел 7.1).

Если пользовательский агент прикрепляет поле заголовка Cookie к HTTP-запросу, пользовательский агент ДОЛЖЕН отправить строку cookie (определенную ниже) в качестве значения поля заголовка.

Пользовательский агент ДОЛЖЕН использовать алгоритм, эквивалентный следующему алгоритму, чтобы вычислить «строку cookie» из хранилища cookie и request-uri:

Пункт № 1

Пусть cookie-list — это набор файлов cookie из магазина cookie, который отвечает всем следующим требованиям:

  • Либо: Флаг cookie-only host-only имеет значение true, и канонизированный запрос-host идентичен домену cookie.
    Или: Флаг cookie-only host-only имеет значение false, и канонизированный домен запроса-хоста совпадает с доменом cookie.
  • Путь request-uri совпадает с путем cookie.
  • Если cookie-only-only-flag cookie имеет значение true, тогда схема request-uri должна обозначать «безопасный» (secure) протокол (как определено агентом пользователя).
    ПРИМЕЧАНИЕ. Понятие «безопасный» протокол не определено в этом документе. Как правило, пользовательские агенты считают протокол безопасным, если протокол использует безопасность транспортного уровня, такую как SSL или TLS. Например, большинство пользовательских агентов считают «https» схемой, обозначающей безопасный протокол.
  • Если http-only-flag cookie имеет значение true, исключите cookie, если строка cookie генерируется для API «не HTTP» (как определено агентом пользователя).

Пункт № 2

Пользовательский агент ДОЛЖЕН сортировать список файлов cookie в следующем порядке:

  • Файлы cookie с более длинными путями перечислены перед файлами cookie с более короткими путями.
  • Среди файлов cookie, имеющих поля пути одинаковой длины, файлы cookie с более ранним временем создания перечислены перед файлами cookie с более поздним временем создания.

ПРИМЕЧАНИЕ. Не все пользовательские агенты сортируют список файлов cookie в этом порядке, но этот порядок отражает обычную практику, когда этот документ был написан, и исторически существовали серверы, которые (ошибочно) зависели от этого порядка.

Пункт № 3

Обновите время последнего доступа каждого файла cookie в списке файлов cookie к текущей дате и времени.

Пункт № 4

Сериализуйте список cookie в строку cookie, обработав каждый файл cookie в списке в следующем порядке:

  1. Выведите имя файла cookie, символ %x3D («=») и значение файла cookie
  2. Если в списке файлов cookie есть необработанный файл cookie, выведите символы %x3B и %x20 («;  «) (Точка с запятой и пробел)

ПРИМЕЧАНИЕ. Несмотря на свое название, строка cookie на самом деле представляет собой последовательность октетов, а не последовательность символов. Чтобы преобразовать строку cookie (или ее компоненты) в последовательность символов (например, для представления пользователю), пользовательский агент может попытаться использовать кодировку символов UTF-8 [RFC3629] для декодирования последовательности октетов. Однако это декодирование может завершиться сбоем, поскольку не каждая последовательность октетов является допустимой UTF-8.

 

6. Вопросы реализации

6.1. Ограничения

Практические реализации пользовательских агентов имеют ограничения на количество и размер файлов cookie, которые они могут хранить. Пользовательские агенты общего назначения ДОЛЖНЫ обеспечивать каждую из следующих минимальных возможностей:

  • Не менее 4096 байт на файл cookie (измеряется суммой длины имени, значения и атрибутов файла cookie)
  • Не менее 50 файлов cookie на домен
  • Не менее 3000 файлов cookie

Серверы ДОЛЖНЫ использовать как можно меньше и небольшие файлы cookie, чтобы избежать достижения этих пределов реализации и минимизировать пропускную способность сети, поскольку заголовок Cookie включается в каждый запрос.

Серверы ДОЛЖНЫ изящно ухудшаться, если пользовательский агент не может вернуть один или несколько файлов cookie в заголовке Cookie, потому что пользовательский агент может в любой момент удалить любой файл cookie по заказам пользователя.

6.2. Интерфейсы прикладного программирования

Одна из причин, по которой заголовки Cookie и Set-Cookie используют такой эзотерический синтаксис, заключается в том, что многие платформы (как в серверах, так и в пользовательских агентах) предоставляют строчный интерфейс прикладного программирования (API) для файлов cookie, что требует от программистов прикладного уровня генерировать и анализировать синтаксис используется заголовками Cookie и Set-Cookie, что многие программисты сделали неправильно, что приводит к проблемам взаимодействия.

Вместо предоставления строковых API для файлов cookie, платформы будут лучше обслуживаться, предоставляя больше семантических API. В этот документ не входит рекомендация конкретных конструкций API, но есть очевидные преимущества принятия абстрактного объекта «Date» вместо сериализованной строки даты.

6.3. Зависимость IDNA и миграция

IDNA2008 [RFC5890] заменяет IDNA2003 [RFC3490]. Однако между этими двумя спецификациями есть различия, и, таким образом, могут быть различия в обработке (например, преобразовании) меток доменных имен, которые были зарегистрированы под одной из тех, которые зарегистрированы под другой. Будет некоторый переходный период, в течение которого метки доменных имен на основе IDNA2003 будут существовать в свободном доступе. Пользовательские агенты ДОЛЖНЫ реализовывать IDNA2008 [RFC5890] и МОГУТ реализовывать [UTS46] или [RFC5895] для облегчения их перехода IDNA. Если пользовательский агент не реализует IDNA2008, пользовательский агент ДОЛЖЕН реализовывать IDNA2003 [RFC3490].

7. Вопросы конфиденциальности

Куки часто критикуют за то, что они позволяют серверам отслеживать пользователей. Например, ряд компаний «веб-аналитики» используют файлы cookie для распознавания того, когда пользователь возвращается на веб-сайт или посещает другой веб-сайт. Хотя файлы cookie не являются единственным механизмом, который серверы могут использовать для отслеживания пользователей по HTTP-запросам, файлы cookie облегчают отслеживание, поскольку они постоянны в сеансах пользовательского агента и могут использоваться несколькими хостами.

7.1. Сторонние файлы Cookies

Особенно беспокоят так называемые «сторонние» куки. При рендеринге HTML-документа пользовательский агент часто запрашивает ресурсы у других серверов (таких как рекламные сети). Эти сторонние серверы могут использовать куки для отслеживания пользователя, даже если пользователь никогда не посещает сервер напрямую. Например, если пользователь посещает сайт, содержащий контент от третьей стороны, а затем посещает другой сайт, содержащий контент от той же третьей стороны, третья сторона может отслеживать пользователя между двумя сайтами.

Некоторые пользовательские агенты ограничивают поведение сторонних файлов cookie. Например, некоторые из этих пользовательских агентов отказываются отправлять заголовок Cookie в сторонних запросах. Другие отказываются обрабатывать заголовок Set-Cookie в ответах на сторонние запросы. Пользовательские агенты сильно различаются в своих сторонних политиках cookie. Этот документ предоставляет агентам пользователей широкие возможности для экспериментов со сторонними политиками файлов cookie, которые обеспечивают баланс между потребностями пользователей в конфиденциальности и совместимости. Однако этот документ не поддерживает какую-либо конкретную стороннюю политику в отношении файлов cookie.

Сторонние политики блокировки файлов cookie часто оказываются неэффективными для достижения целей конфиденциальности, если серверы пытаются обойти свои ограничения для отслеживания пользователей. В частности, два сотрудничающих сервера могут часто отслеживать пользователей, вообще не используя файлы cookie, путем введения идентифицирующей информации в динамические URL-адреса.

7.2. Элементы управления пользователя

Пользовательские агенты ДОЛЖНЫ предоставлять пользователям механизм управления файлами cookie, хранящимися в хранилище файлов cookie. Например, пользовательский агент может разрешить пользователям удалять все файлы cookie, полученные в течение определенного периода времени, или все файлы cookie, связанные с конкретным доменом. Кроме того, многие пользовательские агенты включают элемент пользовательского интерфейса, который позволяет пользователям проверять файлы cookie, хранящиеся в их хранилище файлов cookie.

Пользовательские агенты ДОЛЖНЫ предоставлять пользователям механизм отключения куки. Когда куки отключены, пользовательский агент НЕ ДОЛЖЕН включать заголовок Cookie в исходящие HTTP-запросы, а пользовательский агент НЕ ДОЛЖЕН обрабатывать заголовки Set-Cookie во входящих HTTP-ответах.

Некоторые пользовательские агенты предоставляют пользователям возможность предотвратить постоянное хранение файлов cookie во время сеансов. При такой конфигурации пользовательские агенты ДОЛЖНЫ обрабатывать все полученные куки-файлы, как если бы для постоянного флага был установлен false. Некоторые популярные пользовательские агенты предоставляют эту функцию в режиме «приватного просмотра» [Aggarwal2010].

Некоторые пользовательские агенты предоставляют пользователям возможность утверждать отдельные записи в хранилище cookie. Во многих распространенных сценариях использования эти элементы управления генерируют большое количество запросов. Тем не менее, некоторые пользователи, находящиеся в сознании конфиденциальности, считают эти элементы управления полезными.

7.3. Срок годности

Хотя серверы могут устанавливать дату истечения срока действия файлов cookie для отдаленного будущего, большинство пользовательских агентов фактически не сохраняют файлы cookie в течение нескольких десятилетий. Вместо того, чтобы выбирать безвозмездно длительные периоды истечения срока действия, серверы ДОЛЖНЫ повышать конфиденциальность пользователей, выбирая разумные периоды истечения срока действия файлов cookie в зависимости от цели использования файлов cookie. Например, типичный идентификатор сеанса может быть разумно установлен, чтобы истечь через две недели.

8. Вопросы безопасности

8.1. Обзор

Куки-файлы имеют ряд проблем безопасности. В этом разделе рассматриваются некоторые из наиболее важных вопросов.

В частности, файлы cookie поощряют разработчиков полагаться на полномочия окружения для аутентификации, часто становясь уязвимыми для атак, таких как подделка межсайтовых запросов [CSRF]. Кроме того, при хранении идентификаторов сеансов в файлах cookie разработчики часто создают уязвимости фиксации сеансов.

Шифрование на транспортном уровне, такое как используемое в HTTPS, недостаточно, чтобы предотвратить получение или изменение злоумышленником куки-файлов жертвы, поскольку сам протокол куки-файлов имеет различные уязвимости (см. «Слабая конфиденциальность» Weak Confidentiality и «Слабая целостность» Weak Integrity ниже). Кроме того, по умолчанию файлы cookie не обеспечивают конфиденциальность или целостность от сетевых злоумышленников, даже если они используются в сочетании с HTTPS.

8.2. Окружающие Основания

Сервер, использующий файлы cookie для аутентификации пользователей, может страдать от уязвимостей безопасности, поскольку некоторые пользовательские агенты позволяют удаленным сторонам отправлять HTTP-запросы от пользовательского агента (например, через перенаправления HTTP или формы HTML). При отправке этих запросов пользовательские агенты прикрепляют файлы cookie, даже если удаленная сторона не знает содержимого файлов cookie, что потенциально позволяет удаленной стороне осуществлять полномочия на неосторожном сервере.

Хотя эта проблема безопасности связана с несколькими именами (например, подделка межсайтовых запросов, запутанный заместитель), проблема связана с тем, что файлы cookie являются формой окружающих оснований. Файлы cookie поощряют операторов серверов отделять обозначение (в форме URL-адресов) от авторизации (в форме файлов cookie). Следовательно, пользовательский агент может предоставить авторизацию для ресурса, указанного злоумышленником, что может привести к тому, что сервер или его клиенты предпримут действия, указанные злоумышленником, как если бы они были авторизованы пользователем.

Вместо того, чтобы использовать куки для авторизации, операторы серверов могли бы рассмотреть возможность запутывания назначения и авторизации, рассматривая URL как возможности. Вместо того чтобы хранить секреты в файлах cookie, этот подход хранит секреты в URL-адресах, требуя, чтобы удаленный объект предоставил сам секрет. Хотя этот подход не является панацеей, разумное применение этих принципов может привести к более надежной безопасности.

8.3. Очистить текст

Если информация не отправлена по безопасному каналу (например, TLS), информация в заголовках Cookie и Set-Cookie передается в открытом виде.

  1. Вся конфиденциальная информация, передаваемая в этих заголовках, подвергается перехватчику
  2. Злонамеренный посредник может изменять заголовки, когда они движутся в любом направлении, с непредсказуемыми результатами
  3. Вредоносный клиент может изменить заголовок Cookie перед передачей, что приведет к непредсказуемым результатам

Серверы ДОЛЖНЫ шифровать и подписывать содержимое файлов cookie (используя любой формат, который пожелает сервер) при передаче их агенту пользователя (даже при отправке файлов cookie по безопасному каналу). Однако шифрование и подпись содержимого файлов cookie не препятствуют тому, чтобы злоумышленник перенес файл cookie от одного пользовательского агента к другому или не воспроизвел файл cookie позднее.

В дополнение к шифрованию и подписанию содержимого каждого файла cookie серверы, которым требуется более высокий уровень безопасности, ДОЛЖНЫ использовать заголовки Cookie и Set-Cookie только по защищенному каналу. При использовании файлов cookie по безопасному каналу серверы ДОЛЖНЫ устанавливать атрибут Secure (см. Раздел 4.1.2.5) для каждого файла cookie. Если сервер не установлен атрибут Secure, защита, обеспечиваемая защищенный канал будет в значительной степени спорной.

Например, рассмотрим сервер веб-почты, который хранит идентификатор сеанса в файле cookie и обычно доступен через HTTPS. Если сервер не устанавливает атрибут Secure в своих файлах cookie, активный сетевой злоумышленник может перехватить любой исходящий HTTP-запрос от пользовательского агента и перенаправить этот запрос на сервер веб-почты по HTTP. Даже если сервер веб-почты не прослушивает HTTP-соединения, пользовательский агент все равно будет включать куки-файлы в запрос. Активный сетевой злоумышленник может перехватить эти файлы cookie, воспроизвести их на сервере и узнать содержимое электронной почты пользователя. Если бы вместо этого сервер установил атрибут Secure в своих файлах cookie, пользовательский агент не включил бы файлы cookie в запрос в виде открытого текста.

8.4. Идентификаторы сеанса

Вместо того, чтобы хранить информацию о сеансе непосредственно в куки (где она может подвергаться или воспроизводиться злоумышленником), серверы обычно сохраняют одноразовый номер (или «идентификатор сеанса») в куки. Когда сервер получает HTTP-запрос с одноразовым номером, сервер может искать информацию о состоянии, связанную с cookie, используя одноразовый номер в качестве ключа.

Использование cookie-файлов с идентификатором сеанса ограничивает ущерб, который может нанести злоумышленник, если злоумышленник узнает содержимое cookie-файла, поскольку одноразовый номер полезен только для взаимодействия с сервером (в отличие от одноразового содержимого cookie-файла, который сам по себе может быть чувствительным). Кроме того, использование единственного одноразового номера не позволяет злоумышленнику «объединить» содержимое файлов cookie из двух взаимодействий с сервером, что может привести к непредсказуемому поведению сервера.

Использование идентификаторов сеансов не без риска. Например, сервер ДОЛЖЕН позаботиться о том, чтобы избежать уязвимостей «фиксации сеанса». Атака фиксации сеанса проходит в три этапа. Сначала злоумышленник переносит идентификатор сеанса из своего пользовательского агента в пользовательский агент жертвы. Во-вторых, жертва использует этот идентификатор сеанса для взаимодействия с сервером, возможно, наполняя идентификатор сеанса учетными данными пользователя или конфиденциальной информацией. В-третьих, злоумышленник использует идентификатор сеанса для непосредственного взаимодействия с сервером, возможно, получая полномочия пользователя или конфиденциальную информацию.

8.5. Слабая конфиденциальность

Файлы cookie не обеспечивают изоляцию по порту. Если файл cookie доступен для чтения службой, работающей на одном порту, файл cookie также может быть прочитан службой, работающей на другом порту того же сервера. Если файл cookie доступен для записи службой на одном порту, файл cookie также доступен для записи службой, работающей на другом порту того же сервера. По этой причине серверам НЕ СЛЕДУЕТ запускать службы, не доверяющие друг другу, на разных портах одного и того же хоста и использовать файлы cookie для хранения информации, чувствительной к безопасности.

Файлы cookie не обеспечивают изоляцию по схеме. Хотя файлы cookie для данного хоста чаще всего используются со схемами http и https, они также могут быть доступны для других схем, таких как ftp и gopher. Хотя отсутствие изоляции по схеме наиболее очевидно в API, не поддерживающих HTTP, которые разрешают доступ к cookie-файлам (например, API document.cookie в HTML), отсутствие изоляции по схеме фактически присутствует в требованиях к обработке самих cookie-файлов (например, рассмотрите возможность получения файлов cookie). URI со схемой gopher (суслика) через HTTP).

Файлы cookie не всегда обеспечивают изоляцию по пути. Хотя протокол сетевого уровня не отправляет файлы cookie, сохраненные для одного пути, в другой, некоторые пользовательские агенты предоставляют файлы cookie через не-HTTP API, такие как HTML-документ document.cookie. Поскольку некоторые из этих пользовательских агентов (например, веб-браузеры) не изолируют ресурсы, полученные из разных путей, ресурс, извлеченный из одного пути, может иметь доступ к файлам cookie, сохраненным для другого пути.

8.6. Слабая целостность

Файлы cookie не предоставляют гарантии целостности для доменов одного уровня (и их поддоменов). Например, рассмотрим foo.example.com и bar.example.com. Сервер foo.example.com может установить файл cookie с атрибутом домена «example.com» (возможно, перезаписать существующий файл cookie «example.com», установленный bar.example.com), и пользовательский агент включит этот файл cookie в HTTP запросы к bar.example.com. В худшем случае bar.example.com не сможет отличить этот файл cookie от файла cookie, который он сам установил. Сервер foo.example.com может использовать эту возможность для атаки на bar.example.com.

Несмотря на то, что заголовок Set-Cookie поддерживает атрибут Path, атрибут Path не обеспечивает никакой защиты целостности, поскольку пользовательский агент примет произвольный атрибут Path в заголовке Set-Cookie. Например, ответ HTTP на запрос для http://example.com/foo/bar может установить cookie с атрибутом Path «/qux». Следовательно, серверам НЕ СЛЕДУЕТ запускать службы, не доверяющие друг другу, по разным путям одного и того же хоста и использовать файлы cookie для хранения конфиденциальной информации.

Активный сетевой злоумышленник также может внедрить файлы cookie в заголовок Cookie, отправленный на https://example.com/, выдав себя за ответ от http://example.com/ и вставив заголовок Set-Cookie. HTTPS-сервер на example.com не сможет отличить эти файлы cookie от файлов cookie, которые он установил в ответе HTTPS. Активный сетевой злоумышленник может использовать эту возможность для атаки на example.com, даже если example.com использует исключительно HTTPS.

Серверы могут частично смягчить эти атаки, шифруя и подписывая содержимое своих файлов cookie. Однако использование криптографии не решает проблему полностью, поскольку злоумышленник может воспроизвести cookie-файл, который он или она получил от аутентичного сервера example.com в сеансе пользователя, с непредсказуемыми результатами.

Наконец, злоумышленник может заставить агента пользователя удалить файлы cookie, сохранив большое количество файлов cookie. Как только пользовательский агент достигнет своего лимита хранения, пользовательский агент будет вынужден удалить некоторые куки. Серверы НЕ ДОЛЖНЫ полагаться на то, что пользовательские агенты удерживают куки.

8.7. Опора на DNS

Файлы cookie используют систему доменных имен (DNS) для обеспечения безопасности. Если DNS частично или полностью скомпрометирован, протокол cookie может не обеспечить свойства безопасности, требуемые приложениями.

9. Соображения IANA

В реестр полей постоянного заголовка сообщения (см. [RFC3864]) добавлены следующие регистрации.

Header field name: Cookie
Applicable protocol: http
Status: standard
Author/Change controller: IETF
Specification document: this specification (Section 5.4)

Header field name: Set-Cookie
Applicable protocol: http
Status: standard
Author/Change controller: IETF
Specification document: this specification (Section 5.2)

9.3. Cookie2

Header field name: Cookie2
Applicable protocol: http
Status: obsoleted
Author/Change controller: IETF
Specification document: [RFC2965]

9.4. Set-Cookie2

Header field name: Set-Cookie2
Applicable protocol: http
Status: obsoleted
Author/Change controller: IETF
Specification document: [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.

See Section 6.3 for an explanation why the normative reference to an obsoleted specification is needed.

[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>.

Приложение А. Благодарности

Этот документ заимствует из RFC 2109 [RFC2109]. Мы в долгу перед Дэвидом М. Кристолом и Лу Монтулли за их усилия по определению файлов cookie. Дэвид М. Кристол, в частности, дал бесценные советы по навигации в процессе IETF. Мы также хотели бы поблагодарить Томаса Бройера, Тайлер Клоуз, Алиссу Купер, Била Корри, Корвида, Лизу Дюссо, Роя Т. Филдинга, Блейка Франца, Анну ван Кестерена, Эрана Хаммера-Лахава, Джеффа Ходжеса, Бьорна Хёрмана, Ахима Хоффмана, Георга Коппен, Дин Макнейми, Алексей Мельников, Марк Миллер, Марк Поли, Ингве Н. Петтерсен, Джулиан Решке, Питер Сен-Андре, Марк Сиборн, Мачей Стаховяк, Даниэль Стенберг, Тацухиро Цудзикава, Дэвид Вагнер, Дэн Виншип и Дэн Витте за их ценные отзывы об этом документе.

Адрес авторов

Adam Barth,

University of California, Berkeley

EMail: abarth@eecs.berkeley.edu

URI: http://www.adambarth.com/