Находить уязвимости в публичных программах — это одновременно захватывающе и прибыльно. В этом посте я расскажу, как обнаружил и использовал уязвимость обхода 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 - Хакер