EN Прислать проект
Все статьи

Вход и сессии: где ошибается авторизация, написанная ИИ

Токен в localStorage или в cookie, сессии без срока, дырявый сброс пароля и проверки, которые живут только в интерфейсе.

· 4 минБезопасностьКод

Форма входа — первое, что ассистент собирает в любом приложении, и выглядит она всегда одинаково убедительно. Поле почты, поле пароля, кнопка, редирект в кабинет. Ошибки начинаются за этой формой: где хранится токен, сколько он живёт, что происходит при сбросе пароля и кто на сервере проверяет, что человек вообще имеет право на то, что просит.

Токен в localStorage или в cookie

Ассистенты почти всегда кладут токен в localStorage: это проще всего и работает сразу. Цена — любой скрипт на странице может его прочитать. Одна XSS-уязвимость, одна скомпрометированная библиотека аналитики — и токен уезжает к чужому человеку, который пользуется им со своего компьютера.

Cookie с флагами HttpOnly, Secure и SameSite=Lax недоступна из JavaScript, и украсть её через XSS нельзя. Зато появляется другая забота — CSRF: браузер отправляет cookie сам, и запросы, меняющие данные, нужно от этого защищать. SameSite закрывает большую часть случаев, для остального есть CSRF-токен.

Однозначного «правильно» нет, но для обычного веб-приложения с собственным бэкендом cookie обычно безопаснее. Если остаёшься на localStorage, хотя бы сделай токен короткоживущим и серьёзно отнесись к XSS.

Сессии без срока

Частая находка: JWT без поля exp или со сроком в год. Такой токен — бессрочный пропуск. Выход из аккаунта удаляет его из браузера, но сервер продолжает его принимать, если у кого-то осталась копия.

Что нужно:

  • Короткий токен доступа (минуты или часы) и отдельный токен обновления, который можно отозвать.
  • Хранилище сессий на сервере или список отозванных токенов — чтобы «выйти» и «выйти на всех устройствах» действительно что-то делали.
  • Отзыв всех сессий при смене пароля и почты.

Сброс пароля

Здесь ошибки самые дорогие, потому что сброс — это вход без пароля по определению.

  • Ссылка не одноразовая и без срока. Письмо полугодовой давности в чужом ящике должно быть бесполезным. Срок — минуты или часы, использование — одно.
  • Токен угадывается. Идентификатор пользователя, время или короткое число вместо криптографически случайной строки.
  • Ссылка собирается из заголовка Host. Тогда злоумышленник запрашивает сброс для чужой почты с подменённым заголовком, и жертва получает настоящее письмо со ссылкой на чужой домен. Адрес сайта берётся из конфига, а не из запроса.
  • Ответ выдаёт, есть ли такая почта. «Пользователь не найден» превращает форму в инструмент проверки чужих адресов. Отвечай одинаково: «если такой адрес есть, мы отправили письмо».
  • После сброса старые сессии живы. Человек сбросил пароль, потому что подозревает взлом, а тот, кто взломал, остаётся внутри.

Проверки только в интерфейсе

Самая распространённая и самая опасная ошибка — права проверяет интерфейс. Кнопка «Админка» скрыта, если в профиле нет флага isAdmin, а сам флаг лежит в localStorage или приходит с клиента в теле запроса.

Признаки:

  • Роль или тариф читаются из того, что прислал браузер.
  • Middleware защищает страницы, но не API: в Next.js легко настроить matcher так, что /api под него не попадает.
  • Сервер проверяет, что человек вошёл, но не проверяет, что запись принадлежит ему.

Правило простое: каждый серверный обработчик сам выясняет, кто пришёл (по сессии, а не по полю в запросе), и сам решает, можно ли ему это. Интерфейс только прячет кнопки, чтобы не путать людей.

Мелочи, которые потом не мелочи

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

Если авторизацию в твоём продукте писал ассистент и никто её с тех пор не читал, начни с неё. SUBXCAT проверяет такие места и чинит их без переписывания всего входа.

Хочешь, сделаем это за тебя?

Расскажи о проекте ассистенту — через пять минут будет примерная смета, через 48 часов разбор.

Созвон с командой 20 минут: инженер, дизайнер и маркетолог посмотрят на проект вместе с тобой.
Записаться на звонок