Логические уязвимости API: почему IDOR не находят сканеры и как его ищут на самом деле
Самые дорогие взломы последних лет — не эксплойты и не 0-day, а логические уязвимости API: подставил чужой ID — получил чужие данные. Их не находит ни один сканер из коробки, потому что с точки зрения кода всё работает правильно. Разбираем, как устроен этот класс уязвимостей и как его ищут.
Что такое логическая уязвимость
Логическая уязвимость — это когда приложение работает ровно так, как написано в коде, но не так, как задумывал бизнес. Классические примеры:
- ◇IDOR (insecure direct object reference): эндпоинт /orders/{id} проверяет, что пользователь залогинен, но не проверяет, что заказ — его. Перебор ID отдаёт чужие заказы, платежи, документы.
- ◇Broken access control: обычный пользователь дергает админский эндпоинт, и тот отвечает — потому что проверка роли есть в интерфейсе, но не в API.
- ◇Mass assignment: API принимает весь JSON-объект целиком, и в PATCH-запрос профиля можно дописать role: admin или balance: 100000.
- ◇Workflow abuse: шаги бизнес-процесса вызываются в обход порядка — подтверждение платежа без самого платежа, применение промокода после отмены заказа.
Почему сканеры это не ловят
SAST ищет опасные конструкции в коде, DAST — известные сигнатуры в ответах. Но в IDOR нет опасной конструкции и нет сигнатуры: запрос корректный, ответ — валидный JSON со статусом 200. Понять, что произошла утечка, можно только зная контекст: этот пользователь не должен видеть этот объект.
Поэтому логические уязвимости традиционно находят только руками: пентестер читает API, строит модель «кто что должен видеть», а потом методично проверяет каждый эндпоинт под разными ролями и сравнивает ответы. На API в сотню эндпоинтов это дни однообразной, но требующей понимания работы — и именно поэтому в реальных пентестах логику часто проверяют выборочно, а не сплошь.
Как это автоматизирует Izanagi
Izanagi — наш LLM-driven сканер логических уязвимостей API. Он делает то же, что делает пентестер, но сплошным покрытием: читает OpenAPI-спецификацию, строит гипотезы о ролевой модели и связях объектов, генерирует пары запросов «свой/чужой» под разными учётками и сравнивает ответы. Каждая находка — это доказанный PoC: конкретный запрос, конкретный чужой объект в ответе.
Ключевое отличие от классического DAST — модель понимает семантику API: что orders принадлежат users, что endpoint с put и полем role — кандидат на mass assignment, что цепочка «создать → отменить → применить скидку» стоит проверки. Пилот проходит на вашем стенде за 2–4 недели, результат — отчёт с диффом new/known/fixed против ваших прошлых пентестов.
Что сделать команде уже сейчас
- ◇Проверка прав — на уровне объекта, не эндпоинта: не «пользователь залогинен», а «этот пользователь имеет доступ к этому объекту». В каждом обработчике.
- ◇Белые списки полей на запись: PATCH и PUT принимают только явно разрешённые поля, а не весь объект.
- ◇Тесты на чужие объекты: для каждого эндпоинта — автотест «пользователь A запрашивает объект пользователя B и получает 403». Это дешёвая и очень эффективная страховка в CI.
- ◇Инвентаризация API: логические дыры чаще всего живут в забытых эндпоинтах — старых версиях, внутренних ручках, выставленных наружу, тестовых маршрутах.
FAQ
2–4 недели на вашем стенде: сплошная проверка логики API с доказанными PoC на каждую находку. Скоуп и критерии успеха фиксируются до старта.
Обсудить пилот