IDOR уязвимость в API: перехват трафика через Burp Suite и подмена JWT

На пентесте API мобильного приложения перехватил через Burp Suite рядовой GET-запрос к /api/v2/accounts/1547 — в ответе пришли полные реквизиты чужого счёта. Заменил 1547 на 1548 — ещё один счёт, другой пользователь. Сервер не проверял, кому принадлежит запрошенный объект. Ни единой записи в логе. Весь «пентест» этого эндпоинта занял три минуты, а бизнес-импакт — полная выгрузка данных клиентов.
Это классическая IDOR уязвимость в API. По рейтингу OWASP API Security Top 10 (открытый рейтинг самых критичных рисков для API) она стабильно на первой строке — API1:2023 Broken Object Level Authorization. Ниже — полный разбор: от настройки перехвата трафика мобильного приложения до подмены JWT-токена и продвинутых техник обхода авторизации.
Что такое IDOR и почему это проблема номер один в API
IDOR (Insecure Direct Object Reference — небезопасная прямая ссылка на объект) возникает, когда приложение берёт идентификатор из пользовательского запроса для доступа к объекту (записи в базе, файлу, профилю) и не проверяет, имеет ли запрашивающий право на этот объект. В терминологии OWASP эту же проблему называют BOLA — Broken Object Level Authorization (нарушение авторизации на уровне объекта). Разные названия, суть одна: сервер отдаёт чужое, потому что никто не спросил «а ты кто?».
Бизнес-логика атаки: зачем это злоумышленнику
Чтобы оценить реальный импакт уязвимости, полезно понимать мотивацию атакующего:
- Массовая выгрузка данных. Перебор числовых ID через скрипт или Burp Intruder открывает доступ к профилям, документам и платёжным реквизитам всех пользователей. По данным Verizon DBIR 2025, веб-атаки составляют 26% всех подтверждённых нарушений — IDOR в API остаётся одним из основных векторов такой выгрузки.
- Изменение чужих данных. Если IDOR работает не только на чтение (GET), но и на запись (PUT/PATCH/DELETE), атакующий может сменить email жертвы, сбросить пароль, подменить платёжные реквизиты. В кейсе Laburity (исследовательская лаборатория по безопасности) именно такая IDOR-уязвимость позволила перезаписать биллинговые данные подписчика через манипуляцию с параметром email и подмену ответа сервера.
- Эскалация привилегий. Если ID администратора предсказуем (часто это
1или0), заменаuser_idв запросе даёт доступ к админ-панели без единого эксплойта. Просто другая цифра в URL.
В терминах MITRE ATT&CK (открытая база тактик и техник атак — каждая техника имеет свой T-код, например T1190) эксплуатация IDOR относится к технике T1190 Exploit Public-Facing Application (тактика Initial Access): атакующий использует публично доступный API как точку входа. Когда через IDOR удаётся получить учётные данные другого пользователя, это уже T1078 Valid Accounts — использование легитимных аккаунтов для дальнейшего продвижения по инфраструктуре.
Три условия, при одновременном выполнении которых IDOR эксплуатируется:
- Приложение принимает идентификатор объекта от клиента (в URL, теле запроса, заголовке, cookie).
- Идентификатор предсказуем или доступен атакующему (числовой инкремент, UUID из утечки, base64-закодированный ID).
- Сервер не проверяет — принадлежит ли запрошенный объект авторизованному пользователю.
Убери любое из трёх — вектор закрыт.
Перехват HTTPS трафика мобильного приложения через Burp Suite
Прежде чем искать IDOR уязвимость в API, нужно увидеть, какие запросы мобильное приложение реально отправляет. Многие эндпоинты не документированы и не видны в веб-версии — они доступны только из мобильного клиента. Для перехвата используется Burp Suite (инструмент-перехватчик трафика от PortSwigger) в роли MITM-прокси. MITM — Man-in-the-Middle, «человек посередине»: Burp встаёт между приложением и сервером, пропуская весь трафик через себя.
Настройка прокси: пошаговая инструкция
Что понадобится: Burp Suite Community Edition (бесплатная версия, скачивается с portswigger.net), мобильное устройство или эмулятор Android в одной Wi-Fi-сети с компьютером.
Шаг 1. Запусти Burp и настрой Listener. Открой Proxy → Proxy settings → добавь listener на порту 8080, привязанный к All interfaces (все интерфейсы). Если оставить «Loopback only» — телефон не сможет подключиться, потому что loopback принимает соединения только с того же компьютера. Ожидаемый результат: в настройках виден активный listener *:8080.
Шаг 2. Настрой прокси на устройстве. На Android: Settings → Wi-Fi → текущая сеть → Proxy → Manual. Укажи IP-адрес компьютера (узнать: ifconfig на macOS/Linux, ipconfig на Windows) и порт 8080. На iOS — аналогично через настройки Wi-Fi. Ожидаемый результат: устройство перестанет открывать HTTPS-сайты (ещё нет доверенного сертификата), но HTTP-сайты откроются.
Шаг 3. Установи сертификат Burp. Открой на устройстве браузер, перейди по http://burp — скачается файл сертификата CA. На Android: Settings → Security → Install from storage → выбери скачанный файл. Без этого шага HTTPS-трафик не расшифруется: в Burp вместо читаемых запросов будет зашифрованный мусор.
Результат после всех трёх шагов: во вкладке Proxy → HTTP history начнут появляться запросы мобильного приложения — URL, заголовки, тело запроса и ответа в открытом виде. Тут видны параметры с ID объектов, JWT-токены в заголовке Authorization и вся структура API.
Обход certificate pinning
Многие мобильные приложения используют certificate pinning — приложение «запоминает» сертификат своего сервера и отказывается работать через прокси с подменным сертификатом Burp. Симптом: Burp перехватывает соединение, но приложение показывает ошибку сети или пустой экран.
Обход на Android с root-доступом: утилита Frida (фреймворк для динамической инструментации — позволяет «на лету» менять поведение приложения) с серверным компонентом frida-server на устройстве и скриптом обхода pinning на компьютере. Без root на Android 7+: декомпиляция APK через apktool, добавление в network_security_config.xml доверия к пользовательским сертификатам, пересборка и подпись APK.
Если после настройки прокси приложение перестаёт загружать данные — это pinning. Без его обхода анализ API невозможен.
Поиск IDOR через Burp Suite: от перехвата до эксплуатации
После настройки перехвата начинается анализ трафика. Ниже — мыслительный процесс пентестера: «что вижу → что подозреваю → что проверяю → что получаю».
Шаг 1. Собери карту API-эндпоинтов. Пройди обычный сценарий использования приложения: залогинься, открой профиль, посмотри заказы, измени настройки, загрузи документ. Burp Suite запишет все запросы в HTTP history. Ищи запросы с идентификаторами. Типичные паттерны:
/api/users/42/profile— числовой ID в URL-пути{"order_id": "ORD-10234"}в JSON-теле POST-запроса- Заголовок
X-User-ID: 42— кастомный заголовок с ID Cookie: session=eyJ1c2VyX2lkIjoxMjN9— base64-закодированный JSON с ID внутри cookie
Каждый такой параметр — потенциальная точка IDOR. По методологии тестирования PortSwigger, IDOR чаще обнаруживается в API-эндпоинтах (запросы из мобильного клиента или JS-фронтенда), а не в URL адресной строки.
Шаг 2. Подготовь два аккаунта. Для подтверждения IDOR нужны минимум два аккаунта: A (от имени которого отправляешь запросы) и B (чьи данные пытаешься получить). Зарегистрируй оба, запомни их числовые ID.
Зачем два? Чтобы отличить «сервер вернул мои данные» от «сервер вернул чужие данные». Без контрольного аккаунта невозможно доказать наличие IDOR — сервер может возвращать одинаковые тестовые данные для любого ID.
Шаг 3. Подмени идентификатор. В HTTP history найди запрос с ID аккаунта A. Правый клик → Send to Repeater. Repeater — вкладка Burp для ручной отправки и модификации одиночных запросов: меняешь параметры, нажимаешь Send, смотришь ответ.
Замени ID аккаунта A на ID аккаунта B. Отправь. Анализируй ответ:
| Ответ сервера | Что это значит |
|---|---|
| 200 OK + данные аккаунта B | IDOR подтверждён — авторизация не проверяется |
| 403 Forbidden или 401 Unauthorized | Авторизация работает корректно |
| 200 OK + данные аккаунта A | Сервер игнорирует подменённый ID, использует ID из токена |
| 200 OK + пустой ответ | Объект не найден или доступ закрыт без явной ошибки |
Массовый перебор через Burp Intruder. Если нужно проверить диапазон ID: отправь запрос в Intruder (Ctrl+I), пометь ID как payload-позицию (символами § вокруг значения), выбери Payload type → Numbers (от 1 до 1000, шаг 1). Запусти атаку и отсортируй результаты по длине ответа — разные размеры указывают на данные разных пользователей.
Автоматизация с расширением Autorize. Для систематической проверки IDOR установи расширение Autorize из BApp Store (вкладка Extender). Принцип работы: Autorize перехватывает каждый запрос и повторяет его с токеном другого пользователя (с меньшими привилегиями или вообще без авторизации). Если ответы совпадают — авторизация на эндпоинте не проверяется. Настройка: вставь cookie или токен аккаунта B в поле «Authorization header» расширения, включи перехват и работай в приложении от имени аккаунта A. Autorize подсветит все проблемные эндпоинты автоматически. Это, пожалуй, самый быстрый способ покрыть десятки эндпоинтов за один проход.
Анализ и подмена JWT токена для эксплуатации IDOR
Многие API мобильных приложений используют JWT (JSON Web Token) для авторизации. JWT — стандартный формат токена, который содержит данные пользователя и криптографическую подпись. Токен передаётся в заголовке Authorization: Bearer <token> каждого запроса.
Структура JWT и что в ней искать
JWT состоит из трёх частей, разделённых точками: header.payload.signature. Каждая часть — base64url-закодированный JSON. Декодируется тривиально: через вкладку Decoder в Burp Suite, через сайт jwt.io или утилиту jwt_tool в терминале.
{
"sub": "user_42",
"role": "user",
"user_id": 42,
"exp": 1735689600
}
Здесь payload (полезная нагрузка) содержит: sub — идентификатор субъекта, role — роль пользователя, user_id — числовой ID, exp — срок действия токена в формате Unix timestamp. Если поле user_id или sub используется сервером для определения, чьи данные вернуть — это потенциальная точка для IDOR через JWT-подмену.
Типичные уязвимости JWT
По материалам PortSwigger Web Security Academy, основные уязвимости JWT-реализаций:
| Уязвимость | Суть | Как проверить |
|---|---|---|
| Нет проверки подписи | Сервер вызывает decode() вместо verify() |
Измени payload, оставь оригинальную подпись — если ответ 200, подпись не проверяется |
Алгоритм none |
Сервер принимает "alg": "none" в заголовке |
Замени alg на none, убери подпись (третью часть после точки) |
| Слабый секретный ключ | HMAC-ключ короткий или словарный | Подбор через hashcat -m 16500 jwt.txt wordlist.txt |
Инъекция через jwk |
Сервер доверяет ключу из заголовка токена | Сгенерируй свой RSA-ключ, вставь в jwk-параметр заголовка |
Подмена JWT: практическая цепочка
Что нужно: Burp Suite с перехваченным JWT из мобильного приложения.
Шаг 1. Скопируй токен из заголовка Authorization: Bearer eyJ... перехваченного запроса.
Шаг 2. Декодируй payload: во вкладке Decoder вставь среднюю часть токена (текст между первой и второй точкой), выбери Base64 decode. На выходе — JSON с полями пользователя.
Шаг 3. Измени значение user_id (или sub, или role — зависит от приложения) на значение жертвы. Закодируй модифицированный JSON обратно в base64url. Нюанс, на котором многие спотыкаются: в base64url символы + заменяются на -, / на _, а = в конце убираются. Обычный base64 не подойдёт — сервер отвергнет токен.
Шаг 4. Собери модифицированный токен: оригинальный_header.модифицированный_payload.оригинальная_подпись. Подставь его в заголовок запроса через Repeater и отправь.
Что ожидать:
— Сервер принимает модифицированный токен и возвращает данные другого пользователя → подпись не проверяется → критическая уязвимость (JWT + IDOR)
— Сервер возвращает 401 Unauthorized → подпись проверяется, но можно попробовать алгоритм none или брутфорс ключа
— Сервер возвращает 200 с данными текущего пользователя → сервер берёт user_id из подписанной части токена, а не из изменяемого payload → этот вектор закрыт
В Burp Suite Professional есть встроенная вкладка JSON Web Tokens, которая автоматически парсит JWT в запросе и позволяет редактировать payload прямо в интерфейсе. В Community Edition тот же результат достигается через Decoder и Repeater вручную — дольше, но работает.
HTB Editorial writeup: анализ API на практике
HackTheBox — платформа для отработки навыков пентеста на уязвимых виртуальных машинах. Машина Editorial — характерный пример, где начальный вектор связан с веб-приложением, через которое можно добраться до внутренних API-эндпоинтов.
Методология, которая работает на Editorial и аналогичных машинах:
1. Перехвати весь трафик. Каждый запрос от веб-приложения фиксируется в Burp Suite. Особое внимание — на формы загрузки файлов, поля с URL (для подгрузки обложки, импорта данных, webhook-уведомлений). Именно такие поля часто позволяют обращаться к внутренним сервисам, которые не должны быть доступны снаружи.
2. Ищи обращения к внутренним адресам. Если приложение принимает URL от пользователя (для загрузки изображения, предпросмотра ссылки), попробуй подставить http://127.0.0.1:5000/ и перебрать другие локальные порты. Это техника SSRF (Server-Side Request Forgery — подделка запроса на стороне сервера): ты заставляешь сервер сходить по указанному адресу, и если этот адрес внутренний — раскрываются API, недоступные извне.
3. Проанализируй ответы внутренних API. В них нередко содержатся учётные данные (в терминах MITRE ATT&CK это T1552.001 Credentials In Files), внутренние идентификаторы пользователей, секретные ключи. Один JSON-ответ внутреннего API может содержать логин и пароль для SSH — и это не гипотетический сценарий, а то, что реально встречается на HTB-машинах.
4. Используй найденные данные. Учётные записи из внутреннего API → SSH-доступ → дальнейшая эскалация привилегий через историю коммитов git, конфигурационные файлы, cron-задачи.
Ключевой урок из HackTheBox writeup подобных машин: сканер уязвимостей не находит IDOR и SSRF. Эти уязвимости обнаруживаются при ручном анализе каждого HTTP-ответа в Burp Suite — когда замечаешь, что приложение возвращает данные, которые не должно отдавать текущему пользователю.
Продвинутые техники эксплуатации IDOR уязвимости
Базовая подмена числового ID — только начало. Если замена id=42 на id=43 возвращает 403, есть техники обхода, описанные в исследованиях PortSwigger и OWASP.
HTTP Parameter Pollution. Дублирование параметра: ?user_id=42&user_id=43. В зависимости от бэкенд-фреймворка обрабатывается первое или последнее значение. Если WAF (Web Application Firewall — межсетевой экран уровня приложения) проверяет первое значение, а приложение использует последнее — проверка обходится. На практике это работает чаще, чем кажется: разные компоненты стека по-разному разбирают query string.
Смена HTTP-метода. Замени GET на POST, PUT или DELETE. Часто разработчики настраивают авторизацию для GET-эндпоинта, но забывают про POST к тому же маршруту. По документации PortSwigger, смена метода — один из самых простых способов обнаружить дыру в авторизации.
Подмена Content-Type. Переключение между application/json и application/xml или application/x-www-form-urlencoded может обойти middleware-проверки. Некоторые фреймворки по-разному парсят тело запроса в зависимости от Content-Type и могут пропустить проверку авторизации для непривычного формата.
Эксплуатация устаревших версий API. Если текущая версия — /api/v3/users/42, попробуй /api/v2/users/42 и /api/v1/users/42. Старые версии нередко остаются доступными, но без исправлений авторизации, добавленных в новых версиях. Я встречал ситуации, когда v3 была защищена идеально, а v1 — вообще без auth.
JSON Globbing. Вместо конкретного ID подставь массив или специальное значение в JSON-теле:
{"user_id": [42, 43, 44]}
{"user_id": "*"}
{"user_id": true}
Некоторые бэкенды вернут данные по всем указанным ID или по всем объектам. На боевых системах с этой техникой осторожнее — запрос с "*" может вернуть полный дамп базы, и это уже не «проверка», а инцидент.
Статические ключевые слова. Если API использует me, self или current вместо числового ID (/api/users/me), попробуй заменить на конкретный числовой ID: /api/users/1. Обратное тоже работает: если API принимает /api/users/42, подставь /api/users/me — иногда это раскрывает данные текущего пользователя через эндпоинт без проверки авторизации.
UUID-перечисление. Если приложение использует UUID (формат 550e8400-e29b-41d4-a716-446655440000) вместо числовых ID — прямой перебор невозможен (пространство 2^122). Но UUID часто утекает через другие эндпоинты: публичные профили, ответы API на запросы списков, JS-файлы фронтенда, email-уведомления, Wayback Machine. UUID версии 1 (time-based) предсказуемы, если известен timestamp создания — об этом подробно пишет Hackviser.
Защита API от IDOR уязвимостей: чеклист
Если работаешь не только на стороне атаки, но и защиты — вот минимальный набор мер, закрывающих IDOR:
1. Object-level authorization на каждом эндпоинте. Не if user.is_authenticated, а if object.owner_id == current_user.id. Каждый запрос к каждому объекту проверяет принадлежность. Это центральное требование OWASP A01:2021 Broken Access Control — по их данным, 94% протестированных приложений содержали ту или иную форму нарушения контроля доступа. Аутентификация («ты залогинен?») и авторизация («тебе можно смотреть именно этот объект?») — разные вещи, и путать их дорого.
2. Непредсказуемые идентификаторы. UUID v4 вместо последовательных числовых ID. Это не замена авторизации (UUID тоже утекает), но радикально усложняет массовый перебор.
3. Rate limiting. Ограничение в 100 запросов в минуту на пользователя не позволит выгрузить базу из миллиона записей даже при наличии IDOR. Это мера из OWASP API4:2023 Unrestricted Resource Consumption (неограниченное потребление ресурсов API).
4. Логирование и мониторинг. Каждый запрос к чувствительным объектам записывается с user_id запрашивающего, запрошенным object_id и результатом. Без логов IDOR может эксплуатироваться месяцами — это проблема из OWASP A09:2021 Security Logging and Monitoring Failures.
5. Автоматизированное тестирование авторизации. Интеграция проверок типа Autorize/AuthMatrix в CI/CD-пайплайн (конвейер автоматической сборки и деплоя): при каждом деплое автоматически подставляется токен низкопривилегированного пользователя в каждый эндпоинт. Регрессия в авторизации обнаруживается до попадания в прод.
6. Политика минимальных привилегий. API-ответы возвращают только те поля, которые нужны клиенту. Если мобильному приложению нужны имя и аватар — не отдавай email, телефон и платёжные реквизиты в том же ответе. Это снижает импакт IDOR, даже если авторизация где-то пропущена. Требование из OWASP API3:2023 Broken Object Property Level Authorization (BOPLA — нарушение авторизации на уровне свойств объекта).
Восемь из десяти IDOR, которые я находил на пентестах, были в API мобильных приложений, а не в веб-интерфейсах. Причина простая: разработчики мобильных приложений чаще сфокусированы на фронтенде — кнопки, экраны, UX — и реже думают про бэкенд-авторизацию каждого конкретного объекта. Веб-фронтенд прячет ID в DOM-структуре страницы, а мобильное приложение отправляет их в чистом JSON. Мобильный трафик исторически воспринимается как «защищённый» благодаря certificate pinning — но pinning обходится за 15 минут с Frida, и весь «защищённый» трафик ложится в Burp Suite как на ладони.
BOLA/IDOR остаётся уязвимостью номер один в API не потому, что о ней не знают. О ней знают все. Проблема в другом: авторизация на уровне объекта — архитектурная задача, которую невозможно закрыть одним middleware на входе. Каждый эндпоинт, каждый объект, каждый HTTP-метод — отдельная проверка прав. Разработчики это понимают, менеджеры — не всегда, и строчка «проверить, может ли user_42 читать order_43» стабильно уезжает в конец бэклога. Именно поэтому IDOR будет в топе OWASP ещё не один год.
Для тех, кто входит в пентест API: IDOR — лучшая точка старта. Не нужен exploit-dev, не нужна реверс-инженерия бинарников, не нужны годы опыта. Нужен Burp Suite, два тестовых аккаунта и систематический подход к анализу каждого эндпоинта. Первый найденный IDOR — это и первый реальный навык, и первая строчка в портфолио для собеседования. Если ищешь джуниор-роль в ИБ — IB Basics на codeby.school плюс пара решённых лаб дают что показать работодателю.
Эту тему и смежные навыки разбирают на практике в курсе «Тестирование веб-приложений на проникновение (WAPT)» Codeby Academy.