Writing findings
Находка попадает в отчёт по праву, только когда инженер может её воспроизвести, видит реальное влияние и знает фикс. Воспроизведение + влияние + важность + исправление — это единица работы, а голый ярлык важности — шум.
Два отчёта после авторизованной работы ложатся на стол одному и тому же техлиду. Первый гласит: «High — IDOR на эндпоинте инвойсов. Рекомендуем починить контроль доступа.» Техлид читает, не может воспроизвести, не знает, какие записи утекают и эксплуатируется ли это неаутентифицированным пользователем, и подшивает в папку «пентестеры вечно так говорят». Через шесть недель баг всё ещё открыт. Второй отчёт по тому же багу даёт точный запрос для повтора с двумя тестовыми аккаунтами, показывает, как аккаунт B достаёт инвойс аккаунта A с именем и последними цифрами карты, ставит High с однострочным обоснованием и отдаёт трёхстрочный серверный фикс. Закрыт за день. Та же уязвимость, та же важность. Разница лишь в том, что один написан как находка, а другой — как мнение.
К концу урока ты разберёшь анатомию находки, по которой инженер реально может действовать, — воспроизведение, влияние, важность и исправление — и поймёшь, почему голый ярлык важности, с которого начинают джуны, наименее полезен.
Находка — единственный значимый артефакт
Всё, что было раньше в этом юните — авторизация, инструментарий, методология — существует ради одного артефакта: находки, которую заказчик может починить. Пентест оценивают не по числу найденных багов, а по числу закрытых, а баг закрывается только тогда, когда инженер, не участвовавший в работе, может воспроизвести его, понять, почему он важен, и применить фикс. Это меняет всю рамку: твоя аудитория — не другой хакер, которого впечатлит эксплойт, а занятой бэкенд-инженер с сорока другими тикетами, который отложит всё, по чему не может немедленно действовать. Находка, написанная не для той аудитории, — это находка, которая останется открытой, что для бизнеса равно уязвимости, которую ты вовсе не нашёл.
Поэтому находка — это единица работы, а не повод похвастаться. Зрелая дисциплина — писать каждую находку так, чтобы незнакомый человек взял её «с холода» и довёл до закрытия, не задав тебе ни единого вопроса.
Четыре части, нужные каждой находке
Находка, которая закрывается, несёт четыре вещи, и потеря любой из них — это разница между двумя отчётами из вступления.
| Часть | На какой вопрос отвечает | Как выглядит «хорошо» | Сбой, если её нет |
|---|---|---|---|
| Воспроизведение | Как мне увидеть это самому? | Точный запрос, аккаунты, предусловия, ожидаемое vs фактическое | «Не воспроизводится» → закрыто как won’t-fix |
| Влияние | Что реально может сделать атакующий? | Конкретно: кто, какие данные/действие, какой ущерб в этом приложении | Выглядит теоретически → деприоритизируется |
| Важность | Насколько это срочно на фоне прочего? | Рейтинг с однострочным обоснованием, которое можешь защитить | Несогласованная сортировка; «всё High» |
| Исправление | Что именно я меняю? | Фикс корневой причины, не «санитизируй ввод»; изменение на уровне кода | Инженер гадает → неверный или поверхностный фикс |
Воспроизведение — та часть, которую джуны пропускают, а зрелые ставят впереди, потому что именно она превращает заявление в факт. Инженер должен суметь повторить твои шаги и увидеть баг на своей машине: точный эндпоинт, два тестовых аккаунта и кто из них кто, любые предусловия (зашёл низкопривилегированным пользователем, конкретный id записи), точный отправленный запрос и — что критично — ожидаемое vs фактическое, чтобы нарушение было однозначным. «Аккаунт B запросил инвойс аккаунта A и получил его (ожидалось: 403)» не оставляет места для трактовки. Без этого первое, что делает заказчик, — не воспроизводит, а находку, которую никто не может воспроизвести, закрывают как won’t-fix, какой бы реальной она ни была.
Влияние отвечает на вопрос и что с того. Важность — это число; влияние — фраза, которая это число заслуживает. Ловушка — писать общее влияние («IDOR может привести к несанкционированному доступу к данным») вместо конкретного для этого приложения («любой аутентифицированный пользователь может прочитать инвойс любого другого — имя, адрес выставления счёта и последние цифры карты — инкрементируя одно целое число»). Конкретное влияние удерживает инженера от того, чтобы подшить баг как теоретический пентестерский шум; оно привязывает уязвимость к данным и ущербу, которые он узнаёт.
Важность — это сигнал приоритизации, и её задача — согласованность. Используй определённую шкалу — CVSS для каталогизированных CVE, качественный рейтинг вероятность × влияние для логических багов — и приложи однострочное обоснование, которое защитишь на разборе. Самый частый сбой здесь — инфляция важности: пометить всё как High, чтобы отчёт выглядел грозно. Это бьёт по тебе же — когда каждая находка High, заказчик не отличит SSRF к metadata-учёткам от отсутствующего security-заголовка, и твой настоящий критикал тонет. Откалиброванная важность — это то, что делает отчёт пригодным как очередь работ.
Исправление должно чинить корневую причину, а не симптом. «Санитизируй ввод» — канонический плохой фикс: это совет, а не изменение, и часто он латает не тот слой. Хорошее исправление называет конкретное изменение на уровне кода: для IDOR — ограничь запрос вызывающим (WHERE id = ? AND owner_id = ?, на сервере), а не «добавь валидацию». Исправление, которое инженер может вставить и адаптировать, стоит десяти абзацев предыстории.
Пишем для инженера, а не для хакера
Самый трудный сдвиг для сильного тестировщика — осознать, что отчёт это документ передачи, а получатель не разделяет твой контекст. Три привычки отделяют находку, которая закрывается, от той, что гниёт. Первое: пиши ожидаемое vs фактическое для каждого шага воспроизведения — это самая рычажная фраза, потому что она делает нарушение неоспоримым и самопроверяемым. Второе: не прячь главное — начинай с однострочного резюме (что + влияние + важность), затем детали, потому что инженер, сортирующий пятьдесят находок, читает первую строку каждой и распределяет бюджет от неё. Третье: сделай исправление вставляемым — укажи точный обработчик и точное изменение, и где можешь — сошлись на соответствующий контроль (например, тест WSTG, который ему сопоставлен), чтобы фикс был проверяемым.
▸Почему это работает
Почему именно воспроизведение реально чинит баг — больше, чем влияние или важность? Потому что это единственная часть, которую инженер может проверить независимо до того, как тратить усилия. Влияние и важность — твоя оценка, инженеру приходится тебе верить. Воспроизведение — это факт, который он повторит на своей машине за две минуты, и в момент, когда он видит, как аккаунт B достаёт инвойс аккаунта A, спор окончен: это уже не «пентестеры утверждают X», а «я только что видел это сам». Отчёт с железобетонным воспроизведением и посредственным рейтингом важности всё равно закрывается; отчёт с идеальным баллом CVSS и без воспроизведения заспаривают в забвение. Воспроизведение — место, где обналичивается твоё доверие.
Проработанная находка против голого ярлыка
Возьми IDOR из вступления. Плохая версия — одна строка: «High — IDOR на инвойсах.» Версия-находка звучит так: Резюме — любой аутентифицированный пользователь может прочитать инвойс любого другого, изменив id (High). Воспроизведение — войди тестовым аккаунтом B, отправь GET /api/invoices/{A_invoice_id} с сессией B, наблюдай 200 с инвойсом аккаунта A (имя, адрес выставления, последние цифры карты); ожидалось 403. Влияние — полный доступ на чтение к PII всех клиентов и части данных карты по всему тенанту, эксплуатируется любым залогиненным пользователем без особых прав. Важность — High: тривиально эксплуатируется (целое число правится в URL), ценные данные, широкий радиус поражения. Исправление — обеспечь владение на сервере по фактической записи: смени запрос на WHERE id = ? AND owner_id = ? (или эквивалентную проверку авторизации) на этом и на каждом обработчике объекта по id; запрет по умолчанию. Одна из них закрывается за день; другая — это мнение.
Ты нашёл реальный IDOR на авторизованной работе. Срок отчёта подошёл. Какой способ его описать даёт заказчику лучший шанс реально починить баг?
Заказчик отвечает на твой отчёт: «Мы попробовали вот это и не смогли воспроизвести, поэтому закрываем как won't-fix». На что это, скорее всего, указывает в находке?
Джун помечает каждую находку в отчёте «High», чтобы клиент отнёсся к работе серьёзно. Почему это сбой именно письма?
Упорядочь части письменной находки так, как их читает и использует сортирующий инженер — от первого взгляда до закрытия тикета:
- 1 Однострочное резюме: баг + конкретное влияние + важность (главное, по чему сортируют)
- 2 Воспроизведение: точный запрос, аккаунты, предусловия, ожидаемое vs фактическое
- 3 Влияние: что атакующий реально может сделать с данными/пользователями этого приложения
- 4 Обоснование важности: почему этот рейтинг, защитимое на разборе
- 5 Исправление: изменение на уровне кода и корневой причины, которое закрывает баг
- 01Какие четыре части нужны каждой actionable-находке, на что отвечает каждая и что ломается, если её убрать?
- 02Почему именно воспроизведение реально чинит баг и что из этого следует для того, как ты пишешь отчёт?
Единственный значимый итог пентеста — находка, которую заказчик может починить, поэтому находка — это единица работы, а не повод похвастаться, и пишется она для занятого инженера, который её закроет, а не для хакера, который восхитился бы эксплойтом. Каждая actionable-находка несёт четыре части: воспроизведение (точный запрос, аккаунты, предусловия и ожидаемое-vs-фактическое, позволяющие инженеру подтвердить баг на своей машине), конкретное влияние (что атакующий реально может сделать с данными и пользователями этого приложения, а не общей учебной строкой), откалиброванную важность с однострочным обоснованием (CVSS для каталогизированных CVE, качественный вероятность × влияние для логических багов — и никогда не раздувай всё до High, что убивает отчёт как очередь работ) и исправление корневой причины, которое инженер вставит и адаптирует (ограничь запрос владельцем, а не «санитизируй ввод»). Воспроизведение — та часть, что чинит баги, потому что только её заказчик может проверить до траты усилий; в момент, когда он видит, как аккаунт B читает инвойс аккаунта A, спор окончен. Поэтому начинай с главного, пиши ожидаемое-vs-фактическое для каждого шага и делай фикс вставляемым. Голый ярлык важности, с которого начинает джун, — «High, IDOR, чините контроль доступа» — наименее полезная фраза в отчёте; именно находка вокруг него закрывает баг.
Практика
Начни сверху. Задачи идут от простого к сложному: вспомнить факт, применить к случаю, затем senior-уровень. Открой, попробуй, потом открой ответ.
Что-то непонятно?
Задай вопрос по этому уроку. Вопросы анонимны и попадают напрямую автору — урок станет лучше.