Скачать CV

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

Auth-токен остаётся в cookie

Логин, регистрация, logout и текущий пользователь живут под /api. Токен это httpOnly auth_token. Он не попадает в localStorage и не едет в теле JSON.

Публичный API авторизации это четыре маршрута: /api/login, /api/register, /api/logout и /api/user. Sanctum пишет сессию в httpOnly cookie auth_token. Логин больше не возвращает поле token. На клиенте никто не пишет токен в localStorage.

Если скрипт на origin читает сессию, XSS её унесёт. httpOnly cookie из JavaScript не достать. Та же инъекция не скопирует auth_token. Logout удаляет токен на сервере и cookie, поэтому скопированная cookie перестаёт работать сразу.

Браузер держит auth_token. Скрипты страницы его не видят. В теле JSON поля token нет.
Браузер держит auth_token. Скрипты страницы его не видят. В теле JSON поля token нет.

CSRF на каждую запись

Небезопасные методы требуют CSRF-cookie и парный заголовок. Фронтенд один раз получает cookie, затем шлёт заголовок на каждую запись. Отсутствующий или протухший заголовок даёт 419, а не ошибку валидации, похожую на неверный пароль.

Админ-маршруты сидят за той же cookie-сессией. Истёкшая сессия ведёт на логин, а не на сломанную страницу. Маршрут логина ротирует id сессии.

Записи шлют CSRF-заголовок. Нет заголовка это 419, а не фальшивая ошибка валидации.
Записи шлют CSRF-заголовок. Нет заголовка это 419, а не фальшивая ошибка валидации.

Что фиксируют тесты

Четыре случая раньше регрессировали. В JSON логина нет токена. Флаг httpOnly на auth_token на месте. Запись без CSRF-заголовка отклонена. /api/user отдаёт 401 после logout.

Правило достаточно короткое, чтобы его держать. Токены живут в cookie. Тела JSON несут поля пользователя, не секреты. Если новому экрану нужен текущий пользователь, он зовёт /api/user с credentials. Второй склад он не заводит.

К новостям