Делаем куки безопасными. 3 главных и 4 дополнительных аттрибута

Безопасность

CSRF, CORS и HTTPS мы обсудили какое-то время назад. Но есть одна часть паззла, которая связывает всё это воедино — куки. Они хранят сессии, токены и другую чувствительную информацию. И все вышеперечисленное призвано уберечь их от рук злоумышленников. Сегодня разберем, как правильно настраивать куки, чтобы их не могли украсть или подделать.

Атрибуты кук. Три кита безопасности

1. Secure — «Передавай только по защищенному каналу»

Что делает: Кука передается только по HTTPS. По HTTP — никогда.

Set-Cookie: session=abc123; Secure

Какую атаку предотвращает: Перехват кук в открытой Wi-Fi сети (сниффинг).

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

Исключение: Для локальной разработки на localhost можно использовать без Secure, но в продакшене — обязательно.

2. HttpOnly — «Не показывай JavaScript»

Что делает: Кука недоступна для JavaScript (не видна через document.cookie).

Set-Cookie: session=abc123; HttpOnly

Какую атаку предотвращает: XSS (Cross-Site Scripting).

Почему это важно: Если у вас есть XSS-уязвимость, хакер может выполнить document.cookie и украсть все куки без атрибута HttpOnly. С HttpOnly он увидит пустую строку.

Исключение: Если вы храните в куках несекретные данные (например, тему оформления), HttpOnly не нужен. Но сессионные куки и токены — обязательно с HttpOnly.

3. SameSite — «Не отдавай на чужие сайты»

Что делает: Контролирует, отправлять ли куки при запросах с других сайтов.

Set-Cookie: session=abc123; SameSite=Lax

Какую атаку предотвращает: CSRF (Cross-Site Request Forgery).

Три режима:

РежимЧто разрешаетКогда использовать
SameSite=NoneКуки уходят на все запросы, включая чужие сайтыТолько если есть Secure и нужно встраивание в iframe
SameSite=LaxКуки уходят при переходе по ссылке, но не при фоновых запросах (fetch, форма)По умолчанию и рекомендуется
SameSite=StrictКуки не уходят ни на какие запросы с чужих сайтовМаксимальная безопасность, но часто очень неудобно

Важно: Современные браузеры по умолчанию ставят SameSite=Lax, если вы ничего не указали. Но лучше указывать явно.

Второстепенные атрибуты (тоже важные)

Domain — «Для какого домена работают куки»

Set-Cookie: session=abc123; Domain=.mysite.com

Что делает: Указывает, на каких поддоменах действуют куки.

  • Domain=.mysite.com — только на mysite.com и его поддоменах (api.mysite.comapp.mysite.com).
  • Без Domain — только на текущем домене (не распространяется на поддомены).

Опасность: Если поставить Domain=.com, куки будут отправляться на все .com-сайты. Никогда так не делайте.

Рекомендация: Используйте Domain если у вас несколько поддоменов, и вам нужно шарить сессию между ними.

Path — «Для каких URL работают куки»

Set-Cookie: session=abc123; Path=/api

Что делает: Кука отправляется только на запросы к /api/*. Не отправляется на /admin/* или /.

Используйте: Чтобы разделить куки для разных частей приложения.

Max-Age и Expires — «Срок годности»

Set-Cookie: session=abc123; Max-Age=3600; Expires=Wed, 01 Jan 2025 12:00:00 GMT
  • Max-Age — сколько секунд живет кука (с момента установки).
  • Expires — конкретная дата истечения.

Рекомендация: Выбирайте разумный срок жизни. Для сессий — 1-24 часа. Для авторизаций с активным чекбоксом «запомнить меня» — до 30 дней.

Priority — «Приоритет при удалении»

Set-Cookie: session=abc123; Priority=High

Что делает: Если браузеру не хватает памяти и он удаляет старые куки, куки с Priority=High будут удалены в последнюю очередь.

Как выглядят все атрибуты вместе

Set-Cookie: session=abc123; Secure; HttpOnly; SameSite=Lax; Path=/; Max-Age=3600; Domain=.mysite.com

Можно скзаать, что это промышленный стандарт для сессионной куки.

Чего делать НЕЛЬЗЯ

Хранить пароли в куках

Set-Cookie: password=12345

Это как написать пароль на лбу. Даже с Secure и HttpOnly — не делайте так.

Хранить секретные данные без шифрования

Set-Cookie: credit_card=1234-5678-9012-3456

Если хакер все-таки украдет куку, он получит всё.

Хранить слишком много данных

Куки имеют ограничение в 4 КБ. Не пытайтесь запихнуть туда весь профиль пользователя.

Итого

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

Желаю успехов!

Симо Мофин
Симо Мофин

Senior Frontend Developer
Главный по блогу