Находить уязвимости в публичных программах — это одновременно захватывающе и прибыльно. В этом посте я расскажу, как обнаружил и использовал уязвимость обхода 2FA в одной публичной баг-баунти программе (название скрыто, используется redacted.com из соображений конфиденциальности), что принесло мне в общей сложности $6000. Для лучшего понимания я поделюсь техническими деталями, включая пример HTTP-запроса, а также расскажу о результатах повторного тестирования.
Первичное обнаружение — обход проверки OTP
Всё началось со стандартного процесса входа на redacted.com. После ввода правильных учетных данных веб-приложение запрашивало одноразовый пароль (OTP) в рамках двухфакторной аутентификации (2FA). Чтобы проанализировать процесс, я запустил Burp Suite для перехвата HTTP-запросов.
Вот что я сделал:
- Перехватил запрос на ввод OTP: Я ввел случайный OTP, перехватил этот запрос во вкладке Proxy в Burp Suite и отправил его в модуль Repeater для дальнейшего анализа.
- Отклонил запрос: Вместо того чтобы отправить этот запрос с OTP дальше, я полностью его отменил.
- Проанализировал запрос: В запросе на верификацию OTP, в Authorization заголовке находился JSON Web Token (JWT), который был создан еще до проверки OTP. Это была критическая уязвимость, так как JWT, давал доступ к защищённым эндпоинтам.
Ниже приведён обезличенный пример перехваченного HTTP-запроса для наглядности:
POST /api/verify-otp HTTP/1.1
Host:
redacted.com
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiMTIzNDU2Nzg5MCIsImlhdCI6MTcyODAwMDAwMCwiZXhwIjoxNzI4MDAzNjAwfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Connection: close
{
"otp": "123456"
}
JWT-токен в заголовке Authorization оказался ключом. Отклонив запрос на проверку OTP, я предположил, что токен всё ещё может быть действителен для доступа к другим эндпоинтам.
Изучение API-эндпоинтов с помощью GAP и Intruder
Чтобы проверить масштаб уязвимости, я использовал расширение Burp Suite Get All Parameters (GAP) для перечисления всех API-эндпоинтов, связанных с redacted.com. Затем я применил инструмент Intruder из Burp Suite, чтобы отправлять запросы на эти эндпоинты, добавляя JWT-токен в заголовок Authorization.
К моему удивлению, я получил доступ ко всем API-эндпоинтам без прохождения проверки OTP. Это была серьёзная уязвимость безопасности, так как таким образом механизмы двухфакторной аутентификации (2FA) полностью обходились.
Отчетность и вознаграждение
Я сообщил об уязвимости в рамках программы, подробно описав шаги для воспроизведения и возможные последствия (например, несанкционированный доступ к конфиденциальным пользовательским данным или действиям). Компания признала проблему, исправила баг и вручила мне награду в размере $4000.

Повторное тестирование – Уязвимость платёжного эндпоинта
После исправления я повторно протестировал приложение (через год), чтобы убедиться, что уязвимость устранена. Процесс проверки OTP теперь казался более надёжным, и большинство эндпоинтов перенаправляли неавторизованные запросы на страницу ввода OTP. Однако я решил исследовать дальше, используя другой подход — принудительный переход через браузер (browser forcing).
Вместо того чтобы взаимодействовать с окном ввода OTP в браузере, я вручную перешёл на страницу оплаты/заказа (/payment/order), напрямую введя адрес в браузерной строке. К своему удивлению, я обнаружил, что этот эндпоинт всё ещё был доступен без проверки OTP. Я мог просматривать и использовать функционал оплаты, что являлось серьёзной недоработкой.
Вот пример HTTP-запроса к этому платёжному эндпоинту.
GET /payment/order/transection HTTP/1.1
Host:
redacted.com
Cookie:
Connection: close
Я протестировал другие эндпоинты, но они корректно перенаправляли на страницу ввода OTP. Только эндпоинт payment/order/transection оставался уязвимым, что указывало на неполное исправление.
Второй отчёт и дополнительное вознаграждение
Я отправил повторный отчёт, в котором подчеркнул сохраняющуюся проблему с эндпоинтом payment/order. Компания быстро устранила недочёт и выплатила мне дополнительные $2000, увеличив общий размер вознаграждения до $6000.

Ключевые выводы
Несколько важных уроков как для охотников за багами, так и для разработчиков:
Проверяйте неочевидное. Прерывание запросов или обход пользовательских интерфейсов (например, с помощью browser forcing) может выявить скрытые уязвимости.
Тщательно перебирайте эндпоинты. Инструменты вроде GAP и Intruder незаменимы для поиска незащищённых эндпоинтов.
Повторно тестируйте после исправлений. Неполные патчи могут оставить критические эндпоинты открытыми для атак, как это случилось со страницей payment/order.
Подробное описание. Чёткие и подробные отчёты помогают компаниям быстро исправлять проблемы и честно вознаграждать исследователей.
Для разработчиков этот случай подчёркивает важность проверки аутентификации и авторизации на каждом эндпоинте, особенно для чувствительных функций вроде платежей. Генерация JWT до завершения 2FA — это рецепт беды.
Заключение
Найти и проэксплуатировать этот обход 2FA — отличный опыт с точки зрения развития. Находка доказала ценность настойчивости, креативного тестирования и тщательной перепроверки в баг-баунти. Надеюсь, этот отчёт вдохновит других исследователей копать глубже и поможет разработчикам усилить безопасность своих приложений.
Ещё больше познавательного контента в Telegram-канале — Life-Hack - Хакер
Egyda-AI
Отличный кейс! Особенно впечатляет, как вы совместили классические методы (Burp Suite) с креативным подходом — например, browser forcing для обхода интерфейса. Интересно, проверяли ли вы валидность JWT после отклонения запроса через Repeater? Иногда токены имеют короткий TTL, но тут явно был зазор для эксплуатации.
Как вы тестируете 2FA в своих проектах? Проверяете ли все эндпоинты на предмет «тихих» токенов, или фокусируетесь только на основных сценариях?