Понимание cookies
Cookies — небольшие текстовые файлы, сохраняемые браузером от имени веб-сайта. Это основной механизм поддержания состояния в stateless-протоколе HTTP.
Атрибуты cookies
| Атрибут | Назначение | Влияние на безопасность |
|---|---|---|
| Name=Value | Хранимые данные | Не должны содержать чувствительные данные в открытом виде |
| Domain | Какой домен может обращаться | Cookie для .example.com доступна sub.example.com |
| Path | Какой URL-путь может обращаться | Cookie /admin не отправляется для /public |
| Expires/Max-Age | Когда истекает | Сессионные cookies истекают при закрытии браузера |
| Secure | Только по HTTPS | Предотвращает передачу без шифрования |
| HttpOnly | Недоступна JavaScript | Защищает от кражи через XSS |
| SameSite | Управляет кросс-сайтовой отправкой | Strict, Lax или None — предотвращает CSRF |
Тестирование атрибутов cookies
Откройте DevTools > Application > Cookies и проверьте каждую cookie:
- Cookies аутентификации должны иметь флаги Secure, HttpOnly и SameSite
- Сессионные cookies не должны иметь длинный Expires/Max-Age
- Domain должен быть максимально ограничительным
- Path должен быть ограничен соответствующим разделом
Типы cookies
Сессионные cookies: Без даты истечения. Удаляются при закрытии браузера. Для временной аутентификации.
Постоянные cookies: С датой истечения. Переживают перезапуск браузера. Для «Запомнить меня» и настроек.
Сторонние cookies: От других доменов. Для отслеживания и рекламы. Всё чаще блокируются.
Механизмы клиентского хранения
localStorage
- Пары ключ-значение как строки
- Сохраняется до явной очистки
- Приблизительно 5-10 МБ на источник
- Доступен любому JavaScript на том же источнике
- НЕ защищён от XSS
sessionStorage
- Тот же API, что у localStorage
- Ограничен вкладкой — не делится между вкладками
- Очищается при закрытии вкладки
IndexedDB
- Полноценная база данных в браузере
- Структурированные данные, файлы и блобы
- Значительно больший объём (сотни МБ)
- Асинхронный API
- Используется PWA для офлайн-хранения
Тестирование механизмов хранения
Для каждого механизма проверьте:
- Данные корректно сохраняются после действий пользователя
- Данные корректно извлекаются при загрузке страницы
- Приложение обрабатывает отсутствующие или повреждённые данные
- Ограничения хранилища обрабатываются правильно
- Очистка данных браузера удаляет ожидаемые элементы
- Корректное поведение в режиме инкогнито
Жизненный цикл сессии
Вход → Сессия создана → Активное использование → Предупреждение о таймауте →
Сессия истекла → Повторная аутентификация → Сессия восстановлена/новая
Тестирование жизненного цикла
- Создание: После входа проверить cookie с правильными атрибутами
- Поддержание: Сессия должна обновляться при активности
- Предупреждение: Перед истечением показать предупреждение с возможностью продления
- Истечение: После таймаута перенаправить на вход
- Повторная аутентификация: После повторного входа восстановить контекст
- Уничтожение: После выхода сессия инвалидируется на сервере
Продвинутое тестирование cookies и сессий
Тестирование кросс-доменных cookies
Когда приложение охватывает несколько поддоменов:
- Корректно ли делятся cookies между поддоменами?
- Может ли cookie одного поддомена мешать другому?
- Корректно ли работают ограничения SameSite для кросс-доменных API-вызовов?
Ограничения размера cookies
Браузеры ограничивают cookies ~4 КБ на cookie и 20-50 на домен:
- Что происходит при достижении ограничения?
- Добавление новой cookie молча не удаётся или вызывает ошибку?
Тестирование квоты хранилища
- Заполните localStorage до предела через консоль
- Попробуйте добавить больше — обрабатывается ли QuotaExceededError?
- Показывается ли осмысленное сообщение?
Упражнение: Аудит безопасности хранилища
- Cookies: Список всех, проверка флагов безопасности
- Local Storage: Поиск чувствительных данных
- Session Storage: Проверка области видимости
- Удалите элементы вручную, проверьте восстановление
- Проверьте в режиме инкогнито
| Хранилище | Ключ | Содержит | Проблема? |
|---|---|---|---|
| Cookie | session_id | Токен сессии | Отсутствует HttpOnly |
| localStorage | auth_token | JWT-токен | Должен быть HttpOnly cookie |
Предотвращение session fixation
- Запишите значение cookie сессии до входа
- Войдите с валидными данными
- Проверьте — значение должно измениться
- Если тот же ID — уязвимость session fixation
Ключевые выводы
- Cookies — основной механизм состояния, всегда проверяйте флаги безопасности
- HttpOnly предотвращает кражу через XSS; Secure — передачу в открытом виде; SameSite — CSRF
- localStorage уязвим для XSS — никогда не храните там токены аутентификации
- Тестируйте полный жизненный цикл сессии
- Проверяйте ограничения и обработку квот хранилища
- ID сессии должны меняться после входа