Попросил сервер удалить чужой список дел. Он ответил «ok».
А список на месте.
Пишу пет-проект, todo на Go, и прогнал его на IDOR (он же BOLA) - первое место в OWASP API Security Top 10 2023.
Проверка простая: два тестовых пользователя, второй подставляет в запросы id списка первого. - чтение - 500, а в теле ответа текст ошибки базы sql: no rows in result set; - удаление - 200 ok; - переименование - 200 ok.
Данные при этом не пострадали: user_id в WHERE берётся из токена, а не из запроса. Доступ закрыт. Но API отвечает неправду и отдаёт клиенту внутренние ошибки.
Причина: UPDATE и DELETE, которые не задели ни одной строки, для базы - успех (в psql так и пишет: DELETE 0). Код не смотрел на число затронутых строк.
Что поменял: - проверяю RowsAffected; ноль строк - ErrNotFound и ответ 404; - чужой и несуществующий объект - одинаковый 404 с одинаковым текстом; - клиенту - только 500 internal server error, детали - в лог.
Почему 404, а не 403: 403 подтверждает, что объект существует, и перебором id можно оценить, сколько их в системе. RFC 9110 (15.5.4) прямо разрешает в таком случае отвечать 404. GitHub на чужой приватный репозиторий отвечает так же.
Вывод для себя: защита от IDOR - это не только «не пустить», но и «не проговориться».
Как у вас принято: на чужой объект отвечаете 403 или 404?