Расследования по эндпоинтам
Записи расследований в SQLite: статус проверки, теги, заметки и улики.
Когда при первичном отборе (triage) всплывает эндпоинт, за которым стоит последить — кандидат на IDOR, маршрут логина с rate limit, эндпоинт выпуска токенов, — к нему можно привязать постоянную запись расследования. Каждая запись привязана к маршруту из каталога, содержит статус проверки, произвольные теги и поле заметок для улик и шагов воспроизведения. Хранится она в той же базе SQLite, что и импортированные захваты, поэтому переживает перезапуски.
Где живут записи расследований
Записи редактируются из каталога маршрутов в API-лаборатории. Откройте рабочее пространство API, разверните строку маршрута в каталоге — и рядом с панелями схемы, GraphQL и конвейера декодирования для этого маршрута появится секция Investigation record. Когда запись существует, в заголовке секции отображается текущий статус в виде бейджа.
Запись привязана к ключу эндпоинта из записи каталога, поэтому у одного маршрута ровно одна запись. О том, как группируются маршруты, см. /docs/ru/api-re/catalog/.
Создание и редактирование записи
- Разверните нужный маршрут в каталоге.
- В секции Investigation record выберите статус проверки из выпадающего списка (по умолчанию —
unreviewed). - Введите теги через запятую, например
auth, BOLA, tier-1. - Запишите улики и шаги воспроизведения в текстовом поле.
- Нажмите Save. Бейдж статуса обновится, а запись будет сохранена в SQLite.
Чтобы удалить запись, нажмите кнопку с корзиной рядом с Save. Удаление стирает строку целиком; маршрут возвращается в состояние «записи нет» (а не сбрасывается в unreviewed).
Состояния статуса проверки
Статус — это состояние рабочего процесса расследования. Бэкенд отклоняет любое значение вне этого набора с кодом HTTP 400.
| Статус | Значение | Бейдж |
|---|---|---|
unreviewed | По умолчанию; замечен, но ещё не оценён | нейтральный |
reviewed | Оценён, действий не требует | зелёный |
interesting | Стоит более глубокого расследования | янтарный |
vulnerable | Подтверждённая находка на авторизованной цели | красный |
false-positive | Сигнал опровергнут | нейтральный |
[!NOTE]
vulnerableпредназначен для находок, подтверждённых на системах, которые вам разрешено тестировать. Зафиксируйте в заметках область авторизации, чтобы запись была самодостаточной при последующем пересмотре.
Теги
Теги — это короткие метки для группировки и фильтрации. При сохранении бэкенд нормализует их:
- У каждого тега обрезаются окружающие пробелы.
- Пустые теги отбрасываются.
- Дубликаты удаляются без учёта регистра (
auth,AuthиAUTHсхлопываются в первый встреченный вариант написания). - Тег длиннее 64 символов или 31-й по счёту тег не проходит валидацию с кодом HTTP 400.
В редакторе вводите теги одной строкой через запятую; при сохранении они разбиваются и обрезаются.
Заметки и улики
Поле заметок — это область свободного текста для сути расследования: наблюдаемого поведения, шагов воспроизведения, результатов replay, владельцев и способов устранения. Плейсхолдер редактора подсказывает: Evidence, reproduction notes, owner, remediation….
Размер заметок ограничен 20 000 символов; ввод большей длины отклоняется с кодом HTTP 400. Отдельного объекта улик нет — статус отражает состояние рабочего процесса, а поле заметок — это место, где живут улики и детали воспроизведения. Вставляйте конкретные фрагменты запросов/ответов и шаги, воспроизводящие поведение, чтобы находка была самодостаточной.
[!TIP] Если находка зависит от replay, укажите использованные переменные replay и выражения вывода (derivation expressions), чтобы воспроизведение было повторяемым. См. /docs/ru/replay/variables/ и /docs/ru/replay/workbench/.
Как записи сохраняются
Записи хранятся в таблице endpoint_annotations базы SQLite Traffic Jam (по умолчанию .traffic-jam/traffic-jam-v2.sqlite3, переопределяется через TRAFFIC_JAM_DB_PATH):
create table if not exists endpoint_annotations (
endpoint_key text primary key,
status text not null default 'unreviewed',
tags_json text not null default '[]',
notes text not null default '',
updated_at text not null
);
endpoint_key — первичный ключ, поэтому сохранение работает как upsert: повторное сохранение для того же маршрута перезаписывает статус, теги и заметки и обновляет updated_at (хранится как метка времени RFC 3339 в UTC). Теги хранятся как JSON-массив в tags_json. Вторичный индекс по (status, updated_at desc) обеспечивает выборку по статусу и давности. Поскольку данные находятся в базе захватов, записи переживают перезапуски API и перемещаются вместе с файлом базы.
Как записи связаны с каталогом и replay
Связь между записью расследования и остальным рабочим пространством — ключ эндпоинта в формате method:host:pathTemplate, например:
GET:api.example.test:/users/{id}
Это тот же ключ, который идентифицирует маршрут в каталоге и служит ключом для конвейеров декодирования и анализа сигнатур по маршруту. Таким образом, запись аннотирует маршрут каталога напрямую: задержка маршрута, доля ошибок и число сессий в каталоге — это контекст вокруг вашей находки, а replay запускается из той же записи каталога. Используйте поле заметок, чтобы привязать запись к конкретным прогонам replay и пассивным находкам (см. /docs/ru/security/findings/).
REST API
Фронтенд обращается к небольшому JSON API, которым можно управлять и напрямую:
| Метод | Путь | Назначение |
|---|---|---|
GET | /api/endpoint-annotations | Список всех записей, сначала самые свежие по updated_at |
POST | /api/endpoint-annotations | Создать или обновить запись (upsert по endpointKey) |
DELETE | /api/endpoint-annotations/{endpointKey} | Удалить одну запись |
Тело POST:
{
"endpointKey": "GET:api.example.test:/users/{id}",
"status": "interesting",
"tags": ["auth", "BOLA"],
"notes": "User A can read user B's profile by swapping the id."
}
Ошибки валидации (отсутствует endpointKey, неизвестный статус, слишком длинные теги или заметки) возвращают HTTP 400; удаление несуществующего ключа возвращает HTTP 404. Запросы должны удовлетворять тем же правилам origin и capability-токена, что и остальная часть API.
Рабочий процесс: от интересного эндпоинта к задокументированной находке
- Найдите кандидата в поиске или пассивных находках и откройте его маршрут в каталоге.
- Переведите запись в
interestingи пометьте тегом предполагаемый класс (BOLA,auth-bypass,rate-limit). - Выполните replay маршрута — варьируя учётные данные или ID в пути в соответствии с гипотезой — и зафиксируйте в заметках подтверждающий запрос/ответ. См. /docs/ru/replay/workbench/.
- После подтверждения на авторизованной цели переведите статус в
vulnerableи запишите область, влияние и способ устранения. Если сигнал не воспроизводится, пометьте его какfalse-positive. - Оставьте запись на месте как постоянный аудиторский след; она хранится в SQLite вместе с захватом, который её породил.