Как заблокировать изменения куки
Что проверяют
Понимаете ли вы, что куки живут у пользователя и он может изменить их всегда, хотя бы через DevTools. Вопрос с подвохом: «заблокировать» на клиенте нельзя, можно только не доверять значению и распознать подмену. Следом спрашивают, что делает HttpOnly на самом деле.
Как отвечать
Разведите две задачи: защита от чужого скрипта и защита от самого пользователя.
От скрипта защищают атрибуты, которые ставит сервер в заголовке Set-Cookie:
HttpOnly: кука не видна вdocument.cookie, скрипт не может её прочитать или перезаписать. Это главная защита сессии при XSS. Поставить её из JavaScript нельзя: браузер проигнорирует куку с таким атрибутом, созданную черезdocument.cookie;Secure: только по HTTPS, недоступна для перезаписи с незащищённых страниц;- префикс
__Host-: кука обязана бытьSecure, сPath=/и безDomain. Так её не перезапишет поддомен, что закрывает атаку подброса куки; SameSite: про отправку с чужих сайтов и CSRF, к изменению значения отношения не имеет.
От пользователя защищает только сервер:
- подпись: к значению добавляется HMAC на серверном секрете, при чтении подпись сверяется. Так работает
cookie-parserс секретом и подписанные сессионные куки фреймворков; - непрозрачный идентификатор: в куке лежит только случайный id сессии, а роль, тариф и права хранятся на сервере;
- JWT: подписан, поэтому подмена видна, но полезная нагрузка читается кем угодно, секреты туда не кладут.
Шифрование само по себе целостность не гарантирует, если это не аутентифицированный режим вроде AES-GCM.
Где спотыкаются
Считают, что HttpOnly запрещает пользователю менять куку. Он запрещает доступ скриптам, а в DevTools такая кука редактируется свободно.
Пишут document.cookie = "a=1; HttpOnly" как пример защиты. Браузер такую куку просто не сохранит.
Хранят в куке role=admin или цену и доверяют значению на сервере без подписи. Это прямой путь к повышению прав одной правкой в браузере.