Как работают куки?
Что проверяют
Понимаете ли вы, что кука это пара HTTP-заголовков с набором правил, а не «файл на компьютере», и умеете ли настроить её безопасно в своём фреймворке. Следом почти всегда спрашивают про сессии и защиту от CSRF.
Как отвечать
Механика укладывается в два заголовка. Сервер отвечает Set-Cookie: sessionid=abc; Path=/; HttpOnly; Secure; SameSite=Lax, браузер сохраняет пару и сам прикладывает Cookie: sessionid=abc к каждому следующему запросу, который подходит под правила. Правила задают атрибуты:
DomainиPath: к каким адресам куку отправлять. БезDomainона привязана только к точному хосту;ExpiresилиMax-Age: без них кука сессионная и живёт до закрытия браузера, с ними постоянная;HttpOnly: JavaScript не видит куку черезdocument.cookie;Secure: кука уходит только по HTTPS;SameSite: отправлять ли куку в запросах с чужого сайта.Laxпропускает только переходы по ссылке,Strictне пропускает ничего,NoneтребуетSecure. Chrome без атрибута ведёт себя как приLax.
На одну куку около 4 КБ, и все подходящие куки едут в каждом запросе, поэтому хранить там данные дорого.
В Django это response.set_cookie(...) и request.COOKIES, для подписанных значений set_signed_cookie. Сессионную куку настраивают через SESSION_COOKIE_SECURE, SESSION_COOKIE_HTTPONLY и SESSION_COOKIE_SAMESITE (по умолчанию Lax). Во Flask и FastAPI это response.set_cookie(key, value, httponly=True, secure=True, samesite="lax").
Где спотыкаются
Считают, что HttpOnly защищает от XSS. Он лишь не даёт прочитать куку скриптом, а вредоносный код на странице всё равно отправит запросы от имени пользователя.
Не знают, что стандартная сессия Flask хранится в самой куке: она подписана, но не зашифрована, и её содержимое легко декодируется. Секреты туда класть нельзя.
Путают куки и localStorage. Хранилище не уходит на сервер само, доступно любому скрипту на странице и не имеет срока жизни, поэтому токен в нём беззащитен перед XSS.