Комментарии 15
Извлекать
userIdтолько из токена/сессии и игнорироватьuserId, присланный клиентом.
А почему игнорировать? Я бы сравнивал... и алерт, если несоответствие.
Если сервер не принимает userId из тела запроса, то и сравнивать не нужно - он сам извлекает userId из токена и работает только с записями этого пользователя. Если же userId передаётся клиентом - проверка обязательна, чтобы не дать ему действовать от чужого имени. В данном случае предпочтительнее вообще не передавать userId в теле запроса, потому что так проще. Если userId не передается клиентом - он не может его подделать. Нет параметра - нет риска.
Не-не... давайте не отрываться от обсуждаемой фразы. А фраза однозначно утверждает, что userIdи извлекается из токена, и присылается клиентом. Согласитесь, что если имеется две независимо полученные копии одного и того же значения, вполне разумно сверить их. И если эта сверка даст отрицательный результат, то где-то имеет место быть проблема, на которую просто нельзя не реагировать.
Вопрос о том, какой должна быть эта реакция - это уже другой вопрос, за рамками. Но само рассуждение, наоборот, приводит к мысли, что наличие параметра может работать как ловушка на беспечного плохиша. Зачем упускать такую возможность?
Да, при наличии двух источников одного и того же значения (токен и тело запроса) - логично их сверить, так что вы правы) Но цель моей рекомендации - полностью исключить использование клиентского userId, потому что если клиент не может передать userId, то подделка невозможна и проверять нечего.
В случае же, если мы по какой-то причине всё же принимаем userId от клиента - да, его надо сравнивать с тем, что в токене, и при несовпадении - выдавать 403/400 или хотя бы писать alert (как вы и предложили).
Согласитесь, что если имеется две независимо полученные копии одного и того же значения, вполне разумно сверить их.
«Человек, у которого одни часы, всегда знает, который час. Человек, у которого двое часов, никогда в этом не уверен» ©
Сравнение это лишняя сущность и усложнение логики. Единственный источник правды о том кто выполняет действие, это токен. Клиент не должен иметь права голоса в этом вопросе. Если сервер в принципе не смотрит на userId из тела запроса, то уязвимости просто нет по определению. Это проще и надежнее
В более сложных системах, да и в этой тоже - для админа, например, может быть вполне легальная ситуация, когда userid в токене не совпадает с userid в теле запроса. Это просто будет означать, что залогиненный пользователь имеет право действовать от имени другого или получать информацию о другом пользователе. И сервер, естественно, это право должен проверить на этапе исполнения запроса - при авторизации.
Просто как напоминание:
Аутентикация: проверка кто ты есть
Авторизация: проверка что ты имеешь право делать
Простые правки — требование аутентификации для критичных операций, получение userId только из токена/сессии, нормализация email и скрытие приватных полей в API — закрывают основные входы для атак.
Забавно, что таблицы в pocketbase по дефолту доступны снаружи только для суперпользователей. То есть, кто-то из ваших кодеров не поленился снять это ограничение, но не стал добавлять правило @request.auth.id=user_id, которое в том же диалоге делается.
Спасибо за замечание, и вы абсолютно правы - базовые меры безопасности это must-have. Но это был первый полноценный проект моего коллеги-фронтендера, и писал он его с нуля и самостоятельно - и, как часто бывает в таких случаях, фокус был на "сделать так, чтобы работало", а не на "сделать безопасно". Главное, что он не просто оставил как есть, а пришёл к нам, попросил проверить на безопасность, признал недочёты и сам исправил все критичные уязвимости. Это и есть рост.
Отличный пример здоровой культуры в компании) Разработчик не боится показать свой проект ИБ-отделу, а ИБ-отдел не просто выдает сухой отчет, а помогает разобраться и превращает это в обучающий материал для всех. Вот такая совместная работа а не игра в кошки-мышки и растит нормальных профессионалов
Сервис дырявый весь насквозь, как будто специально для статьи сделан)
Очень на мой взгляд странная практика - передавать UserID с запросом - всё, что я писал даже для внутреннего использования, за последние лет 20, даже отчёты по потреблённому трафику, использовало данные либо из $_SESSION, либо через mysqli_query/pg_fetch* по полю из $_SESSION, и это делал "программист", окончивший официальное обучение аж в 1994-м году (ладно, то, что я писал 30+ лет назад вообще не подразумевало какой-либо авторизации/аутентификации - не те времена были). Но вообще, дичь, конечно, встречать в GET-запросах (которые в адресную строку подставляются) чувствительную информацию - благо, последние годы это всё "спрятали" на POST-запросами, но сама логика продолжает вызывать недоумение.
Информация
- Сайт
- slc.tl
- Дата регистрации
- Дата основания
- Численность
- 1 001–5 000 человек
- Местоположение
- Россия
- Представитель
- Александр Шилов

Розыгрыш стула, похищение прав: что нашел пентестер в пет-проекте