Перейти к содержанию

Web3: Cookie сессии и защита запросов

Оглавление курса «Web3: вход, смарт-аккаунты и индексатор» · Урок 7 из 30.

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

Предполагается успешный маршрут проверки SIWE и атомарное потребление challenge. Сервер, cookie и HTTP-программы не запускались. Домен library.example используется для объяснения; реальные настройки HTTPS и reverse proxy требуют отдельного процесса развертывания. Базовый CourseCatalog и его publisher не меняются.

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

Сервер создаёт непредсказуемый идентификатор и сохраняет связанную запись: проверенный адрес, сеть входа, время создания, срок и состояние отзыва. Браузер получает только идентификатор в cookie. Адрес в открытом JSON-объекте не заменяет эту запись и не может сам объявить authenticated = true.

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

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

Cookie и её границы

Ниже пример HTTP-заголовка для сервиса, работающего через HTTPS. Значение SESSION_ID является обозначением генерируемого идентификатора, а не настоящим токеном.

Set-Cookie: __Host-library_session=SESSION_ID; Path=/; Secure; HttpOnly; SameSite=Lax

Префикс __Host- требует соответствующих условий поддерживающего браузера: Secure, Path=/ и отсутствие Domain. Это помогает ограничить cookie конкретным host. Он не заменяет проверку сервера и не является универсальной защитой от всех атак. На локальном HTTP-окружении политика Secure требует отдельной настройки или локального HTTPS, а не молчаливого отключения production-флагов.

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

SameSite=Lax ограничивает часть межсайтовых отправок cookie. Но это не исчерпывающая защита изменяющих операций. Особенно нельзя реализовывать изменение прогресса через GET и ожидать, что один флаг всё решит. Серверная политика origin и CSRF рассматривается совместно с маршрутом запроса.

Защита изменения прогресса

Публичный курс17 доступен через GET без сессии. Сохранение персонального прогресса использует POST или другой подходящий изменяющий метод. Сервер проверяет сессию, допустимый Origin и CSRF-механизм выбранной архитектуры. Адрес аккаунта из тела запроса не выбирает пользователя: он определяется сессией.

CSRF-токен связывается с сессией и проверяется сервером по известному правилу. Его значение может быть доступно странице для отправки, но оно не размещается в URL и не подменяется простым hasWallet = true. Подпись SIWE защищает вход, а CSRF защищает использование веб-сессии в последующих запросах. Это разные этапы и разные угрозы.

Наивная проверка Origin.endsWith('library.example') неправильна. Она может принять незапланированное имя и не учитывает корректное представление origin. Сервер сопоставляет разобранный origin с известным списком, включая схему и порт. Политика proxy и публичного адреса сервиса сохраняется в конфигурации.

Срок и продление

Сессия имеет собственный срок, который не обязан совпадать с пятиминутным challenge. Короткий challenge ограничивает окно подписи, а срок кабинета относится к использованию уже созданной записи. Эти значения выбираются по задачам сервиса. Не следует считать любой удобный долгий срок универсальным правилом безопасности.

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

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

Ответ браузеру

После входа сервер возвращает минимум нужных данных кабинета: проверенный адрес и возможности интерфейса. Эти возможности удобны для отображения, но каждый защищённый endpoint повторно проверяет авторизацию. Скрытая кнопка не является серверной защитой, как и в случае прав publisher в контракте.

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

Ожидаемые случаи

Правильная сессия позволяет сохранить прогресс собственного читателя. Истёкшая или отозванная запись требует нового входа. Чужой адрес в теле запроса не переназначает владельца данных. Межсайтовый изменяющий запрос не проходит политику origin и CSRF. Это критерии будущей проверки, которая здесь не выполнялась.

Для упражнения разделите данные публичной статьи, cookie-идентификатор, серверную запись и CSRF-токен. Объясните, какой элемент проверяется на каком этапе. Ожидаемый итог — подпись кошелька встроена в обычную защищённую веб-сессию без превращения её в постоянный пароль. Cookie описаны в MDN Set-Cookie, рекомендации сессий — в OWASP Session Management.

Отдельная cookie потока

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

Оглавление серии