Аудит безопасности отдельной фичи (feature-scoped security review)
Для проекта the-platform: микросервисная CRM-платформа, обрабатывающая
персональные данные клиентов. Безопасность — критический приоритет, а не
формальность. Аудит должен находить реальные, эксплуатируемые проблемы с
привязкой к file:line, а не составлять общий чек-лист без проверки. Каждая
находка обязана быть подтверждена вручную, а не только упоминанием в выводе
сканера.
Это точечная версия полного аудита репозитория (см. скилл
security-audit-full, если задача — весь репозиторий, а не одна фича).
Принципы верификации те же, но периметр, находки и отчёт строго ограничены
кодом, который относится к этой фиче и к тому, что она затрагивает. Логику
ручного разбора можно делегировать через Agent tool — используй
параллелизацию по зонам, как описано в разделе "Запуск проверки" ниже.
ВХОДНЫЕ ДАННЫЕ: КАК ОПРЕДЕЛИТЬ ФИЧУ
Фича: $ARGUMENTS
Фича передаётся в одном из трёх видов — определи, какой перед тобой, и
построй периметр проверки соответствующим способом. Периметр ВСЕГДА шире,
чем буквально указанный вход: включай прямых потребителей/вызывающий код
(роутер, который регистрирует хендлер; фронтенд, который дёргает API;
смежный сервис, которому уходит межсервисный вызов).
A. ДИРЕКТОРИЯ/ВЕТКА/DIFF (например services/xxx-service/feature_y/
или "diff между dev и веткой feature/PROJ-XXXX"):
- Периметр = всё содержимое директории (или файлы из
git diff --stat
относительно базовой ветки) + модули, которые её импортируют (grep -r
по имени пакета/модуля за пределами директории) + роуты/DI, которые её
регистрируют (main.py/app factory/router include).
- Если директория — общая библиотека (libs/shared_auth, libs/shared_metrics
и т.п.), обязательно определи ВСЕХ потребителей библиотеки по всем
сервисам — уязвимость в общем коде размножается на весь список
потребителей.
B. ДОКУМЕНТ (путь к спецификации/дизайн-документу/PRD, .md/.txt/.docx):
- Прочитай документ целиком. Извлеки из него: имена эндпоинтов/маршрутов,
названия моделей/таблиц, роли и права, названия UI-компонентов/экранов,
упомянутые внешние интеграции (вебхуки, callback URL, сторонние API).
- По каждому извлечённому термину сделай
grep/поиск по кодовой базе, чтобы
перевести описание "что должно быть" в конкретные file:line "что есть на
самом деле". Не ограничивайся тем, что документ говорит "реализовано" —
проверяй код, а не текст документа.
- Если документ описывает намерение, а не факт (черновик ТЗ) — явно пометь
в отчёте, какие пункты не нашли соответствия в коде (это тоже находка:
несоответствие спеки и реализации может означать недоделанный контроль
доступа).
C. YOUTRACK ISSUE (ID вида PROJ-XXXX или ссылка):
- Получи текст issue (заголовок, описание, комментарии, acceptance criteria)
через доступный в проекте механизм интеграции с трекером (MCP-инструмент
YouTrack/Jira/GitHub/Linear, если подключён).
Если программного доступа нет — прямо запроси у пользователя текст issue и
ссылки на связанные PR, не додумывай содержание.
- Найди связанные коммиты и файлы по ID тикета: коммиты в этом репозитории
принято помечать номером тикета в сообщении (например
PROJ-1042,
PROJ-1031, PROJ-318) — используй git log --all --grep=<ISSUE-ID> --oneline, затем git show --stat <hash> / git log --all -- <файлы из commit>, чтобы построить список затронутых файлов и сервисов.
- Если тикет ссылается на PR/ветку — проверь именно diff этой ветки
(
git diff main...<branch>), а не только финальное состояние main, чтобы
не пропустить промежуточные версии, если ветка ещё не смержена.
Если ни один из трёх источников не даёт однозначно определить периметр —
остановись и явно перечисли, что нужно уточнить у автора задачи, вместо того
чтобы проверять наугад весь сервис целиком.
Явно зафиксируй в начале отчёта итоговый периметр (список
file/директорий/сервисов), который получился после этого шага — это твой
рабочий SCOPE, дальше весь аудит идёт по нему, плюс точки соприкосновения с
остальной системой (см. СРЕЗ 3 ниже).
КЛЮЧЕВОЙ ПРИНЦИП: ВЕРИФИКАЦИЯ, А НЕ ДОВЕРИЕ
Причина, по которой проверки фич проваливаются, — принятие на веру того, что
"код написан по ТЗ" эквивалентно "фича безопасна". Это НЕ так. Проверяй
адверсариально:
- Если фича добавляет проверку (флаг, HMAC-подпись, экранирование,
авторизация) — убедись, что она ВКЛЮЧЕНА по умолчанию и активна во всех
окружениях (dev/staging/prod), а не только реализована в коде и
выключена флагом.
- Если фича добавляет экранирование ввода — проверь ПОЛНОТУ (одиночная
кавычка, двойная кавычка, обратный слэш, null-байт, юникод-обход), а не
только очевидный случай.
- Если фича защищает один эндпоинт/сервис — проверь, нет ли у неё "братьев
и сестёр" того же класса операций в другом месте кодовой базы, которые
остались незащищёнными (например, фича добавила auth на POST, но не на
DELETE того же ресурса, или на аналогичный bulk-эндпоинт).
- Если в фиче есть RBAC/switch/if-else по ролям — проверь ветку "иначе"
(default case). Отсутствие явного отказа в доступе по умолчанию — это
дыра.
- Не принимай описание в тикете/ТЗ ("это уже защищено", "тут используется
общий middleware") без самостоятельной проверки текущего кода.
- Формулируй статус явно: "не реализовано" / "реализовано формально (код
есть, защиты нет)" / "реализовано выборочно (часть класса покрыта)" /
"реализовано полностью" / "новая находка вне рамок задачи фичи".
МЕТОДОЛОГИЯ: ТРИ НЕЗАВИСИМЫХ СРЕЗА (в границах SCOPE фичи)
СРЕЗ 1 — Точечное автоматизированное сканирование
- Если фича добавила новые зависимости (новая запись в
requirements/pyproject/package.json) — прогони pip-audit/npm audit
точечно по изменившемуся lock-файлу, а не по всему репозиторию.
- semgrep/bandit по файлам из SCOPE (injection, ssrf, insecure
deserialization, hardcoded secrets, weak crypto).
- Если фича трогает Dockerfile/helm-values/k8s-манифесты — checkov/
kube-linter точечно по изменённым файлам.
- gitleaks/trufflehog по diff'у фичи (
git diff/git log -p на затронутых
файлах и коммитах) — секрет мог быть закоммичен и затем удалён в рамках
той же ветки.
СРЕЗ 2 — Ручной построчный разбор кода фичи
Разбери построчно (не по диагонали) каждый файл из SCOPE, применяя чек-лист
по категориям ниже — только те категории, которые реально применимы к тому,
что делает фича (см. подсказки применимости перед чек-листом). Для каждой
находки: file:line, тип уязвимости, конкретный сценарий эксплуатации
("запрос X с параметром Y даёт результат Z"), severity, статус.
Если SCOPE большой (несколько сервисов/директорий) и доступен Agent tool —
раздели на независимые зоны и используй несколько субагентов, каждому —
своя зона, чтобы не срезать угол по всему объёму разом (см. "Запуск
проверки" ниже).
СРЕЗ 3 — Точки соприкосновения с остальной системой
Независимо от построчного разбора ответь: как фича встраивается в
существующие security-инварианты платформы, а не только "нет ли дыр в её
собственном коде"?
- Использует ли фича существующие механизмы аутентификации/авторизации/
мультитенантности, или изобретает собственный путь в обход них (новый
хендлер, который не проходит через общий auth-middleware/RBAC-декоратор)?
- Если фича добавляет новый internal-эндпоинт между сервисами — защищён ли
он тем же shared-secret/mTLS механизмом, что и остальной класс
/internal/* эндпоинтов, или это исключение?
- Если фича добавляет новую точку чтения/записи данных — фильтруется ли она
по company_id/tenant_id так же, как остальные точки того же типа в
системе?
- Если фича переиспользует общую библиотеку (libs/shared_auth и т.п.) —
использует ли актуальную версию как единый пакет, или скопировала/
форкнула логику себе?
- Ломает ли фича какой-то из существующих security-инвариантов, описанных в
предыдущих аудитах репозитория. В проекте это не абстрактная оговорка —
реестр прошлых находок лежит в
docs/bugs/security_audit/ (по каждой
находке прошлого аудита зафиксирован вердикт: подтвердилась / false
positive / уже исправлена), а регрессионная проверка по нему —
scripts/verify_audit_fixes.py. Если SCOPE фичи пересекается по теме или
файлам с одной из находок в этой папке — обязательно прогони скрипт (если
он есть в репозитории) и явно сверь текущий статус, а не переоткрывай
находку с нуля.
- Если находка по фиче фактически совпадает с уже трекнутым в
docs/bugs/security_audit/ риском, который был осознанно принят (низкая
реплика для HA, отключённый networkPolicy и т.п.) — сошлись на
существующий файл-находку вместо того, чтобы заводить дубликат как "новую
находку фичи"; отметь только если фича делает риск хуже, чем он был
зафиксирован.
ЧЕК-ЛИСТ ПО КАТЕГОРИЯМ (применяй те, что релевантны фиче)
Перед разбором быстро классифицируй фичу: какие из блоков ниже применимы
(новый API-эндпоинт → блоки 1,2,5,6,10; новый UI-экран → блоки 1,7; загрузка
файлов → блок 9; интеграция/вебхук → блоки 4,6,8; инфраструктурное изменение
→ блоки 11,12). Не пропускай блок только потому что "фича маленькая" —
маленькие фичи типично и есть источник точечных дыр (см. "Edge cases" ниже).
Аутентификация и авторизация
- Требует ли новый/изменённый эндпоинт аутентификации так же, как
остальные эндпоинты того же сервиса (нет ли "забытого" открытого
маршрута)?
- RBAC-ветки: что происходит для роли, не попавшей ни в одну явную ветку
(default/else)? Приводит ли это к утечке (нет фильтра по
assigned_user_id/owner_id)?
- IDOR/BOLA: можно ли, меняя ID в URL/body, получить доступ к чужому
объекту, которым оперирует фича?
- Broken function level authorization: доступна ли новая
административная/массовая операция без проверки роли?
- Mass assignment/over-posting: принимает ли новый/изменённый API
произвольные поля тела запроса (role, is_admin, company_id, balance и
т.п.), или список разрешённых полей — explicit whitelist?
- Session/token: если фича трогает сессии/токены — где хранение, есть ли
инвалидация, ограничение времени жизни?
- Rate limiting: если фича добавляет login/сброс пароля/OTP-подобный
поток — есть ли лимит попыток?
Мультитенантность (изоляция между компаниями-клиентами) — разбирай
отдельно от общего IDOR, межтенантная утечка тяжелее по последствиям.
- Каждая новая точка чтения/записи (REST-хендлер, WS-подписка, кэш-ключ,
поисковый индекс, очередь, экспорт) — фильтруется ли по
company_id/tenant_id на уровне запроса к БД, а не только на уровне
UI/роутера?
- Совпадение company_id проверяется явным сравнением значения из
токена/контекста с company_id записи, а не подразумевается?
- Общие ресурсы (Redis-ключи, RabbitMQ-очереди, файловое хранилище) — не
коллизирует ли ключ/имя между компаниями при одинаковых внутренних ID?
- Новая Alembic-миграция/DDL: у новой таблицы/колонки, которая хранит
данные конкретной компании, есть ли
company_id/tenant_id и индекс
по нему — структурный пробел на уровне схемы не поймать построчным
разбором запросов, если сам столбец отсутствует.
WebSocket / realtime (если фича трогает realtime-канал)
- Проверяется ли токен/роль/company_id при connect И отдельно при каждой
подписке на канал/комнату (join)?
- Может ли клиент подписаться на чужой канал, подставив/угадав
room-id/dialog-id/user-id?
- Broadcast фильтруется по company_id/роли перед отправкой, или сервер
полагается на то, что клиент "просто не подписан"?
Internal-API между сервисами (если фича добавляет/меняет
/internal/*)
- Требует ли shared-secret/mTLS так же, как остальные эндпоинты того же
класса операций в других сервисах? Проверяется ли секрет фактически (а
не только объявлен в env)?
- Может ли новый internal-эндпоинт быть вызван напрямую снаружи
кластера?
Инъекции (SQL / NoSQL / Command / Template / Deserialization)
- Сборка запросов конкатенацией/f-string/format вместо параметризованных
запросов/ORM — особенно в новых query-параметрах (фильтры, поиск,
сортировка).
- Экранирование "вручную" — проверь полноту (обратный слэш, юникод,
вложенные кавычки).
- Command injection: новые subprocess/os.system/exec с пользовательским
вводом.
- Небезопасная десериализация новых данных из очереди/вебхука/
межсервисного вызова (pickle, yaml.load без SafeLoader, eval/exec).
SSRF (если фича делает исходящий HTTP-запрос по внешнему URL)
- Есть ли allow-list доменов, блокировка приватных/internal
IP-диапазонов (169.254.x.x, 10.x, 172.16-31.x, 192.168.x, 127.x, cloud
metadata)?
- Проверяется ли подпись/источник вебхука перед тем, как система
инициирует ответный запрос по URL из его тела?
XSS (включая клиентские виджеты, если фича — frontend/встраиваемый
компонент)
- innerHTML/dangerouslySetInnerHTML/document.write с недоверенными
данными.
- Если фича — встраиваемый на сторонних сайтах виджет: уязвимость видна
конечным пользователям клиентов вашей платформы — квалифицируй severity
с учётом расширенного радиуса поражения.
- CSP/clickjacking-заголовки не ослаблены ли новым кодом.
Работа с секретами и PII (если фича трогает интеграции/токены/PII)
- Новые секреты в коде/конфигах, отслеживаемых git.
- Токены новых интеграций в БД — открытым текстом или зашифрованы?
- Маскирование секретов в новых логах — работает ли для новых типов
данных, которые ввела фича?
Загрузка и хранение файлов (если фича добавляет upload/скачивание)
- Проверка MIME-типа/расширения (не доверять Content-Type от клиента).
- Ограничение размера, защита от zip-бомб.
- Path traversal при формировании пути из пользовательского ввода.
- Публичная раздача — требует ли аутентификации, если файлы содержат
PII?
Зависимости и суплай-чейн (если фича добавила новые пакеты)
- Критичность новых зависимостей, есть ли более безопасная
альтернатива.
- Новый внутренний пакет — устанавливается из приватного индекса/
локального пути, или по голому имени, которое можно подменить с
публичного PyPI/npm (dependency confusion)?
Docker / контейнеры (если фича меняет Dockerfile)
- USER указан (non-root)? Секреты не через ARG/ENV?
Kubernetes / Helm (если фича меняет values/манифесты)
- networkPolicy/securityContext/resources не ослаблены ли новым
values-файлом относительно существующего baseline проекта?
- Секреты через Kubernetes Secrets, а не открытым текстом в
values.yaml?
Обработка ошибок и наблюдаемость
- Новый broad except с логированием и возвратом None/пустого результата
без re-raise — не маскирует ли это отказ проверки авторизации как
"разрешено"?
- Логируются ли новые security-события (неудачные авторизации,
изменения ролей) отдельно?
- Утечка внутренней информации через новые сообщения об ошибках наружу.
CI/CD (если фича меняет пайплайн)
- CI script injection: интерполируется ли непроверенный внешний ввод
(заголовок PR, имя ветки) напрямую в шаг
run:?
- Новый security-гейт реально блокирует мерж, или только печатает
предупреждение?
EDGE CASES, КОТОРЫЕ ЧАСТО ПРОПУСКАЮТ ПРИ ТЕСТИРОВАНИИ ФИЧИ
- Функциональность, защищённая на UI-уровне (кнопка скрыта), но доступная
напрямую через API без проверки на бэкенде.
- Race condition в "check-then-act" (проверка роли и действие не атомарны).
- Поведение для soft-deleted записей — доступны ли они через новый
эндпоинт, который не учитывает флаг удаления.
- Bulk-вариант новой фичи (bulk-эндпоинт) — часто добавлен "по-быстрому" со
слабее проверенной авторизацией, чем у единичного аналога.
- Вебхук, который фича добавляет — проверяется ли подпись/источник.
- Feature-флаг фичи, выключенный "временно для отладки" и оставленный
выключенным по умолчанию в конфиге.
- Различия dev/staging/prod — фикс, применённый в одной helm-values-
конфигурации, может отсутствовать в другой.
- Экспорт данных, если фича его добавляет — авторизация на экспортируемый
объём так же строга, как на обычное чтение?
- Старый/дублирующий путь, оставшийся после рефакторинга фичи (например,
старый эндпоинт не удалили, а просто перестали вызывать с фронтенда — он
всё ещё доступен и не обновлён под новую логику авторизации).
ШКАЛА SEVERITY (единая с полным аудитом репозитория)
Единая шкала нужна, чтобы находки были сравнимы между проверками отдельных
фич и общими аудитами (см. security-audit-full).
- Critical: неаутентифицированный внешний атакующий получает полный
компромисс через эту фичу (RCE, доступ ко всем данным всех
компаний-клиентов, обход аутентификации целиком).
- High: аутентифицированный пользователь (в т.ч. с минимальной ролью)
получает через эту фичу доступ к чужим данным/привилегиям — включая
межтенантный доступ, либо неаутентифицированный атакующий получает доступ
к данным одной компании/одного пользователя.
- Medium: требует специфичных условий (гонка, конкретная роль, MITM,
социальная инженерия) или ограничивается утечкой метаданных/DoS без
потери данных.
- Low: нарушение best practice без прямого сценария эксплуатации на
момент проверки.
Для каждой находки указывай кто может эксплуатировать (аноним /
аутентифицированный юзер / только внутренняя сеть) и что теряется (чтение /
запись / полный компромисс).
ФОРМАТ ОТЧЁТА
- Executive summary (без технического жаргона): безопасна ли фича к
релизу, что критично, что рискует бизнесом/регуляторикой, что делать в
первую очередь.
- SCOPE — итоговый список проверенных файлов/директорий/сервисов (см.
раздел "Входные данные" выше) и явное указание, что осталось ЗА
пределами SCOPE и почему (например, "общая библиотека X не проверялась
повторно, так как не менялась в рамках этой фичи").
- Вердикт по фиче: "готова к релизу" / "готова с оговорками (см.
low/medium)" / "не готова — есть critical/high находки" — одной фразой в
начале отчёта.
- Полный список находок: file:line, категория (можно сослаться на OWASP
Top 10 / OWASP API Security Top 10 / CWE), конкретный сценарий
эксплуатации, severity с обоснованием, статус, рекомендация по
исправлению.
- Раздел "что сделано хорошо" — сильные паттерны в реализации фичи,
которые стоит тиражировать.
- План действий: что блокирует релиз сейчас (critical/high), что можно
исправить после релиза с тикетом (medium/low).
- Раздел "что не было проверено" — ограничения покрытия (нет доступа к
прод-окружению, нет возможности прогнать сканер и т.п.), чтобы
отсутствие находок не читалось как "там всё чисто".
ПРАВИЛА ОФОРМЛЕНИЯ НАХОДОК
Перед началом проверь, нет ли уже отчёта по этой же фиче в
docs/bugs/security_audit/ (например, по её feature-slug или ISSUE-ID из
предыдущего прогона этого же скилла). Если есть — не начинай нумерацию с
нуля: продолжи существующую последовательность ID и обнови статус уже
известных находок ("не исправлено" → "исправлено" и т.п.), а не заводи их
повторно как новые.
Для каждой находки обязательны:
- Стабильный ID находки (например,
SEC-<ISSUE-ID или feature-slug>-001),
уникальный в рамках отчётов по этой фиче (см. выше про повторный прогон).
- Путь к файлу и номер строки (или диапазон).
- Название уязвимости и категория (OWASP Top 10 / OWASP API Security Top
10 / CWE).
- Конкретный сценарий эксплуатации: "если сделать запрос X с параметром Y,
система вернёт/сделает Z" — не абстрактные формулировки вроде "может быть
уязвимость".
- Severity с обоснованием (кто может использовать, что теряется).
- Рекомендация по исправлению — конкретная ("добавить else-ветку с явным
отказом", "включить флаг X по умолчанию", "заменить f-string на
параметризованный запрос").
ЗАПУСК ПРОВЕРКИ (практическая инструкция)
- Сначала САМ (в основном потоке) выполни раздел "Входные данные" —
определи тип входных данных (директория/ветка/diff, документ, YouTrack
issue) и построй SCOPE. Не делегируй этот шаг: субагент стартует без
контекста разговора и не знает, что имелось в виду под "фичей".
Зафиксируй SCOPE явно, прежде чем переходить к разбору.
- Классифицируй фичу по типу изменений (новый API, новый UI, интеграция/
вебхук, загрузка файлов, инфраструктура и т.д.) и выбери применимые
блоки чек-листа.
- Проверь, нет ли уже отчёта по этой фиче в
docs/bugs/security_audit/
(см. "Правила оформления находок") — это дешёвая проверка, которая
экономит повторную работу и сохраняет непрерывность нумерации находок.
- Запусти точечные автоматизированные проверки СРЕЗА 1 по файлам/
зависимостям из SCOPE (semgrep/bandit точечно, SCA на изменившиеся
lock-файлы, gitleaks по diff'у фичи).
- Проведи ручной построчный разбор СРЕЗА 2. Если SCOPE охватывает
несколько сервисов/директорий и доступен Agent tool — раздели на
независимые зоны и запусти отдельного субагента на зону (в foreground,
если результат нужен для дальнейшего решения в этом же диалоге), чтобы
не срезать угол по всему объёму разом. Каждому субагенту передай
конкретные пути и применимые разделы этого скилла (чек-лист, шкалу
severity, формат находки) — субагент не видит этот файл сам. Записывай
подтверждённые находки в промежуточный файл сразу по мере разбора каждой
зоны, а не держи их только в контексте до финального отчёта.
- Проведи СРЕЗ 3 — точки соприкосновения фичи с существующими
security-инвариантами платформы (аутентификация, мультитенантность,
internal-API, общие библиотеки).
- Сведи все три среза в единый отчёт по формату выше, убери дубликаты, но
не объединяй находки разной природы (сканер нашёл паттерн ≠ ручной
разбор подтвердил эксплуатируемость — фиксируй оба факта, если они
есть). Сохрани финальный отчёт файлом в
docs/bugs/security_audit/<feature-slug>-security-review.md (slug — по
ISSUE-ID или по имени фичи/директории) — это то же место, где лежит
реестр прошлых аудиторских находок, и следующий прогон этого скилла по
той же фиче должен его найти и обновить, а не пересоздавать с нуля.
- Явно укажи, какие проверки НЕ были выполнены (нет доступа к
прод-секретам, нет доступа к рантайм-логам, нет возможности прогнать
сканер и т.п.) — это часть честного отчёта, а не его слабость.
- Если в проекте настроен скилл/агент
security-review (быстрое ревью
pending-изменений на текущей ветке) — можно использовать его как
отправную точку для СРЕЗА 2 по изменённым файлам, но не ограничивайся
только diff'ом: фича может опираться на существующий код, который не
менялся в текущей ветке, но участвует в её security-модели (см. СРЕЗ 3).
Это тестирование, не имплементация: правки вносит разработчик по итогам
отчёта, не ты в рамках этого скилла.
1---2name: security-audit-feature-23description: Точечный аудит безопасности ОДНОЙ конкретной фичи/изменения в the-platform (не всего репозитория) — периметр из директории/ветки/diff, документа-спецификации/PRD или YouTrack issue; та же дисциплина проверки, что и у полного аудита (адверсариальная верификация, три независимых среза, чек-лист по 14 категориям — auth/authz, мультитенантность, websocket, internal API, инъекции, SSRF, XSS, секреты/PII, файлы, зависимости, docker, k8s/helm, обработка ошибок, CI/CD), с привязкой находок к file:line и явным вердиктом готовности к релизу. Используй когда просят проверить безопасность конкретной фичи, ветки, PR или YouTrack-задачи перед мержем/релизом, найти уязвимости в новом эндпоинте/интеграции/загрузке файлов/вебхуке, оценить не открывает ли новая функциональность доступ к чужим данным или чужой компании — даже без слова "аудит", например "не течёт ли эта фича между компаниями", "можно ли эту фичу мержить с точки зрения безопасности", "проверь эту ветку на security-дыры". Это НЕ то же самое, что скилл `security-r4---56# Аудит безопасности отдельной фичи (feature-scoped security review)78Для проекта the-platform: микросервисная CRM-платформа, обрабатывающая9персональные данные клиентов. Безопасность — критический приоритет, а не10формальность. Аудит должен находить реальные, эксплуатируемые проблемы с11привязкой к file:line, а не составлять общий чек-лист без проверки. Каждая12находка обязана быть подтверждена вручную, а не только упоминанием в выводе13сканера.1415Это точечная версия полного аудита репозитория (см. скилл16`security-audit-full`, если задача — весь репозиторий, а не одна фича).17Принципы верификации те же, но периметр, находки и отчёт строго ограничены18кодом, который относится к этой фиче и к тому, что она затрагивает. Логику19ручного разбора можно делегировать через Agent tool — используй20параллелизацию по зонам, как описано в разделе "Запуск проверки" ниже.2122## ВХОДНЫЕ ДАННЫЕ: КАК ОПРЕДЕЛИТЬ ФИЧУ2324Фича: `$ARGUMENTS`2526Фича передаётся в одном из трёх видов — определи, какой перед тобой, и27построй периметр проверки соответствующим способом. Периметр ВСЕГДА шире,28чем буквально указанный вход: включай прямых потребителей/вызывающий код29(роутер, который регистрирует хендлер; фронтенд, который дёргает API;30смежный сервис, которому уходит межсервисный вызов).3132**A. ДИРЕКТОРИЯ/ВЕТКА/DIFF** (например `services/xxx-service/feature_y/`33или "diff между dev и веткой feature/PROJ-XXXX"):34- Периметр = всё содержимое директории (или файлы из `git diff --stat`35 относительно базовой ветки) + модули, которые её импортируют (`grep -r`36 по имени пакета/модуля за пределами директории) + роуты/DI, которые её37 регистрируют (main.py/app factory/router include).38- Если директория — общая библиотека (libs/shared_auth, libs/shared_metrics39 и т.п.), обязательно определи ВСЕХ потребителей библиотеки по всем40 сервисам — уязвимость в общем коде размножается на весь список41 потребителей.4243**B. ДОКУМЕНТ** (путь к спецификации/дизайн-документу/PRD, .md/.txt/.docx):44- Прочитай документ целиком. Извлеки из него: имена эндпоинтов/маршрутов,45 названия моделей/таблиц, роли и права, названия UI-компонентов/экранов,46 упомянутые внешние интеграции (вебхуки, callback URL, сторонние API).47- По каждому извлечённому термину сделай `grep`/поиск по кодовой базе, чтобы48 перевести описание "что должно быть" в конкретные file:line "что есть на49 самом деле". Не ограничивайся тем, что документ говорит "реализовано" —50 проверяй код, а не текст документа.51- Если документ описывает намерение, а не факт (черновик ТЗ) — явно пометь52 в отчёте, какие пункты не нашли соответствия в коде (это тоже находка:53 несоответствие спеки и реализации может означать недоделанный контроль54 доступа).5556**C. YOUTRACK ISSUE** (ID вида `PROJ-XXXX` или ссылка):57- Получи текст issue (заголовок, описание, комментарии, acceptance criteria)58 через доступный в проекте механизм интеграции с трекером (MCP-инструмент59 YouTrack/Jira/GitHub/Linear, если подключён).60 Если программного доступа нет — прямо запроси у пользователя текст issue и61 ссылки на связанные PR, не додумывай содержание.62- Найди связанные коммиты и файлы по ID тикета: коммиты в этом репозитории63 принято помечать номером тикета в сообщении (например `PROJ-1042`,64 `PROJ-1031`, `PROJ-318`) — используй `git log --all --grep=<ISSUE-ID>65 --oneline`, затем `git show --stat <hash>` / `git log --all -- <файлы из66 commit>`, чтобы построить список затронутых файлов и сервисов.67- Если тикет ссылается на PR/ветку — проверь именно diff этой ветки68 (`git diff main...<branch>`), а не только финальное состояние main, чтобы69 не пропустить промежуточные версии, если ветка ещё не смержена.7071Если ни один из трёх источников не даёт однозначно определить периметр —72остановись и явно перечисли, что нужно уточнить у автора задачи, вместо того73чтобы проверять наугад весь сервис целиком.7475Явно зафиксируй в начале отчёта итоговый периметр (список76file/директорий/сервисов), который получился после этого шага — это твой77рабочий SCOPE, дальше весь аудит идёт по нему, плюс точки соприкосновения с78остальной системой (см. СРЕЗ 3 ниже).7980## КЛЮЧЕВОЙ ПРИНЦИП: ВЕРИФИКАЦИЯ, А НЕ ДОВЕРИЕ8182Причина, по которой проверки фич проваливаются, — принятие на веру того, что83"код написан по ТЗ" эквивалентно "фича безопасна". Это НЕ так. Проверяй84адверсариально:85861. Если фича добавляет проверку (флаг, HMAC-подпись, экранирование,87 авторизация) — убедись, что она ВКЛЮЧЕНА по умолчанию и активна во всех88 окружениях (dev/staging/prod), а не только реализована в коде и89 выключена флагом.902. Если фича добавляет экранирование ввода — проверь ПОЛНОТУ (одиночная91 кавычка, двойная кавычка, обратный слэш, null-байт, юникод-обход), а не92 только очевидный случай.933. Если фича защищает один эндпоинт/сервис — проверь, нет ли у неё "братьев94 и сестёр" того же класса операций в другом месте кодовой базы, которые95 остались незащищёнными (например, фича добавила auth на POST, но не на96 DELETE того же ресурса, или на аналогичный bulk-эндпоинт).974. Если в фиче есть RBAC/switch/if-else по ролям — проверь ветку "иначе"98 (default case). Отсутствие явного отказа в доступе по умолчанию — это99 дыра.1005. Не принимай описание в тикете/ТЗ ("это уже защищено", "тут используется101 общий middleware") без самостоятельной проверки текущего кода.1026. Формулируй статус явно: "не реализовано" / "реализовано формально (код103 есть, защиты нет)" / "реализовано выборочно (часть класса покрыта)" /104 "реализовано полностью" / "новая находка вне рамок задачи фичи".105106## МЕТОДОЛОГИЯ: ТРИ НЕЗАВИСИМЫХ СРЕЗА (в границах SCOPE фичи)107108### СРЕЗ 1 — Точечное автоматизированное сканирование109110- Если фича добавила новые зависимости (новая запись в111 requirements/pyproject/package.json) — прогони pip-audit/npm audit112 точечно по изменившемуся lock-файлу, а не по всему репозиторию.113- semgrep/bandit по файлам из SCOPE (injection, ssrf, insecure114 deserialization, hardcoded secrets, weak crypto).115- Если фича трогает Dockerfile/helm-values/k8s-манифесты — checkov/116 kube-linter точечно по изменённым файлам.117- gitleaks/trufflehog по diff'у фичи (`git diff`/`git log -p` на затронутых118 файлах и коммитах) — секрет мог быть закоммичен и затем удалён в рамках119 той же ветки.120121### СРЕЗ 2 — Ручной построчный разбор кода фичи122123Разбери построчно (не по диагонали) каждый файл из SCOPE, применяя чек-лист124по категориям ниже — только те категории, которые реально применимы к тому,125что делает фича (см. подсказки применимости перед чек-листом). Для каждой126находки: file:line, тип уязвимости, конкретный сценарий эксплуатации127("запрос X с параметром Y даёт результат Z"), severity, статус.128129Если SCOPE большой (несколько сервисов/директорий) и доступен Agent tool —130раздели на независимые зоны и используй несколько субагентов, каждому —131своя зона, чтобы не срезать угол по всему объёму разом (см. "Запуск132проверки" ниже).133134### СРЕЗ 3 — Точки соприкосновения с остальной системой135136Независимо от построчного разбора ответь: как фича встраивается в137существующие security-инварианты платформы, а не только "нет ли дыр в её138собственном коде"?139140- Использует ли фича существующие механизмы аутентификации/авторизации/141 мультитенантности, или изобретает собственный путь в обход них (новый142 хендлер, который не проходит через общий auth-middleware/RBAC-декоратор)?143- Если фича добавляет новый internal-эндпоинт между сервисами — защищён ли144 он тем же shared-secret/mTLS механизмом, что и остальной класс145 `/internal/*` эндпоинтов, или это исключение?146- Если фича добавляет новую точку чтения/записи данных — фильтруется ли она147 по company_id/tenant_id так же, как остальные точки того же типа в148 системе?149- Если фича переиспользует общую библиотеку (libs/shared_auth и т.п.) —150 использует ли актуальную версию как единый пакет, или скопировала/151 форкнула логику себе?152- Ломает ли фича какой-то из существующих security-инвариантов, описанных в153 предыдущих аудитах репозитория. В проекте это не абстрактная оговорка —154 реестр прошлых находок лежит в `docs/bugs/security_audit/` (по каждой155 находке прошлого аудита зафиксирован вердикт: подтвердилась / false156 positive / уже исправлена), а регрессионная проверка по нему —157 `scripts/verify_audit_fixes.py`. Если SCOPE фичи пересекается по теме или158 файлам с одной из находок в этой папке — обязательно прогони скрипт (если159 он есть в репозитории) и явно сверь текущий статус, а не переоткрывай160 находку с нуля.161- Если находка по фиче фактически совпадает с уже трекнутым в162 `docs/bugs/security_audit/` риском, который был осознанно принят (низкая163 реплика для HA, отключённый networkPolicy и т.п.) — сошлись на164 существующий файл-находку вместо того, чтобы заводить дубликат как "новую165 находку фичи"; отметь только если фича делает риск хуже, чем он был166 зафиксирован.167168## ЧЕК-ЛИСТ ПО КАТЕГОРИЯМ (применяй те, что релевантны фиче)169170Перед разбором быстро классифицируй фичу: какие из блоков ниже применимы171(новый API-эндпоинт → блоки 1,2,5,6,10; новый UI-экран → блоки 1,7; загрузка172файлов → блок 9; интеграция/вебхук → блоки 4,6,8; инфраструктурное изменение173→ блоки 11,12). Не пропускай блок только потому что "фича маленькая" —174маленькие фичи типично и есть источник точечных дыр (см. "Edge cases" ниже).1751761. **Аутентификация и авторизация**177 - Требует ли новый/изменённый эндпоинт аутентификации так же, как178 остальные эндпоинты того же сервиса (нет ли "забытого" открытого179 маршрута)?180 - RBAC-ветки: что происходит для роли, не попавшей ни в одну явную ветку181 (default/else)? Приводит ли это к утечке (нет фильтра по182 assigned_user_id/owner_id)?183 - IDOR/BOLA: можно ли, меняя ID в URL/body, получить доступ к чужому184 объекту, которым оперирует фича?185 - Broken function level authorization: доступна ли новая186 административная/массовая операция без проверки роли?187 - Mass assignment/over-posting: принимает ли новый/изменённый API188 произвольные поля тела запроса (role, is_admin, company_id, balance и189 т.п.), или список разрешённых полей — explicit whitelist?190 - Session/token: если фича трогает сессии/токены — где хранение, есть ли191 инвалидация, ограничение времени жизни?192 - Rate limiting: если фича добавляет login/сброс пароля/OTP-подобный193 поток — есть ли лимит попыток?1941952. **Мультитенантность (изоляция между компаниями-клиентами)** — разбирай196 отдельно от общего IDOR, межтенантная утечка тяжелее по последствиям.197 - Каждая новая точка чтения/записи (REST-хендлер, WS-подписка, кэш-ключ,198 поисковый индекс, очередь, экспорт) — фильтруется ли по199 company_id/tenant_id на уровне запроса к БД, а не только на уровне200 UI/роутера?201 - Совпадение company_id проверяется явным сравнением значения из202 токена/контекста с company_id записи, а не подразумевается?203 - Общие ресурсы (Redis-ключи, RabbitMQ-очереди, файловое хранилище) — не204 коллизирует ли ключ/имя между компаниями при одинаковых внутренних ID?205 - Новая Alembic-миграция/DDL: у новой таблицы/колонки, которая хранит206 данные конкретной компании, есть ли `company_id`/`tenant_id` и индекс207 по нему — структурный пробел на уровне схемы не поймать построчным208 разбором запросов, если сам столбец отсутствует.2092103. **WebSocket / realtime** (если фича трогает realtime-канал)211 - Проверяется ли токен/роль/company_id при connect И отдельно при каждой212 подписке на канал/комнату (join)?213 - Может ли клиент подписаться на чужой канал, подставив/угадав214 room-id/dialog-id/user-id?215 - Broadcast фильтруется по company_id/роли перед отправкой, или сервер216 полагается на то, что клиент "просто не подписан"?2172184. **Internal-API между сервисами** (если фича добавляет/меняет219 `/internal/*`)220 - Требует ли shared-secret/mTLS так же, как остальные эндпоинты того же221 класса операций в других сервисах? Проверяется ли секрет фактически (а222 не только объявлен в env)?223 - Может ли новый internal-эндпоинт быть вызван напрямую снаружи224 кластера?2252265. **Инъекции (SQL / NoSQL / Command / Template / Deserialization)**227 - Сборка запросов конкатенацией/f-string/format вместо параметризованных228 запросов/ORM — особенно в новых query-параметрах (фильтры, поиск,229 сортировка).230 - Экранирование "вручную" — проверь полноту (обратный слэш, юникод,231 вложенные кавычки).232 - Command injection: новые subprocess/os.system/exec с пользовательским233 вводом.234 - Небезопасная десериализация новых данных из очереди/вебхука/235 межсервисного вызова (pickle, yaml.load без SafeLoader, eval/exec).2362376. **SSRF** (если фича делает исходящий HTTP-запрос по внешнему URL)238 - Есть ли allow-list доменов, блокировка приватных/internal239 IP-диапазонов (169.254.x.x, 10.x, 172.16-31.x, 192.168.x, 127.x, cloud240 metadata)?241 - Проверяется ли подпись/источник вебхука перед тем, как система242 инициирует ответный запрос по URL из его тела?2432447. **XSS** (включая клиентские виджеты, если фича — frontend/встраиваемый245 компонент)246 - innerHTML/dangerouslySetInnerHTML/document.write с недоверенными247 данными.248 - Если фича — встраиваемый на сторонних сайтах виджет: уязвимость видна249 конечным пользователям клиентов вашей платформы — квалифицируй severity250 с учётом расширенного радиуса поражения.251 - CSP/clickjacking-заголовки не ослаблены ли новым кодом.2522538. **Работа с секретами и PII** (если фича трогает интеграции/токены/PII)254 - Новые секреты в коде/конфигах, отслеживаемых git.255 - Токены новых интеграций в БД — открытым текстом или зашифрованы?256 - Маскирование секретов в новых логах — работает ли для новых типов257 данных, которые ввела фича?2582599. **Загрузка и хранение файлов** (если фича добавляет upload/скачивание)260 - Проверка MIME-типа/расширения (не доверять Content-Type от клиента).261 - Ограничение размера, защита от zip-бомб.262 - Path traversal при формировании пути из пользовательского ввода.263 - Публичная раздача — требует ли аутентификации, если файлы содержат264 PII?26526610. **Зависимости и суплай-чейн** (если фича добавила новые пакеты)267 - Критичность новых зависимостей, есть ли более безопасная268 альтернатива.269 - Новый внутренний пакет — устанавливается из приватного индекса/270 локального пути, или по голому имени, которое можно подменить с271 публичного PyPI/npm (dependency confusion)?27227311. **Docker / контейнеры** (если фича меняет Dockerfile)274 - USER указан (non-root)? Секреты не через ARG/ENV?27527612. **Kubernetes / Helm** (если фича меняет values/манифесты)277 - networkPolicy/securityContext/resources не ослаблены ли новым278 values-файлом относительно существующего baseline проекта?279 - Секреты через Kubernetes Secrets, а не открытым текстом в280 values.yaml?28128213. **Обработка ошибок и наблюдаемость**283 - Новый broad except с логированием и возвратом None/пустого результата284 без re-raise — не маскирует ли это отказ проверки авторизации как285 "разрешено"?286 - Логируются ли новые security-события (неудачные авторизации,287 изменения ролей) отдельно?288 - Утечка внутренней информации через новые сообщения об ошибках наружу.28929014. **CI/CD** (если фича меняет пайплайн)291 - CI script injection: интерполируется ли непроверенный внешний ввод292 (заголовок PR, имя ветки) напрямую в шаг `run:`?293 - Новый security-гейт реально блокирует мерж, или только печатает294 предупреждение?295296## EDGE CASES, КОТОРЫЕ ЧАСТО ПРОПУСКАЮТ ПРИ ТЕСТИРОВАНИИ ФИЧИ297298- Функциональность, защищённая на UI-уровне (кнопка скрыта), но доступная299 напрямую через API без проверки на бэкенде.300- Race condition в "check-then-act" (проверка роли и действие не атомарны).301- Поведение для soft-deleted записей — доступны ли они через новый302 эндпоинт, который не учитывает флаг удаления.303- Bulk-вариант новой фичи (bulk-эндпоинт) — часто добавлен "по-быстрому" со304 слабее проверенной авторизацией, чем у единичного аналога.305- Вебхук, который фича добавляет — проверяется ли подпись/источник.306- Feature-флаг фичи, выключенный "временно для отладки" и оставленный307 выключенным по умолчанию в конфиге.308- Различия dev/staging/prod — фикс, применённый в одной helm-values-309 конфигурации, может отсутствовать в другой.310- Экспорт данных, если фича его добавляет — авторизация на экспортируемый311 объём так же строга, как на обычное чтение?312- Старый/дублирующий путь, оставшийся после рефакторинга фичи (например,313 старый эндпоинт не удалили, а просто перестали вызывать с фронтенда — он314 всё ещё доступен и не обновлён под новую логику авторизации).315316## ШКАЛА SEVERITY (единая с полным аудитом репозитория)317318Единая шкала нужна, чтобы находки были сравнимы между проверками отдельных319фич и общими аудитами (см. `security-audit-full`).320321- **Critical**: неаутентифицированный внешний атакующий получает полный322 компромисс через эту фичу (RCE, доступ ко всем данным всех323 компаний-клиентов, обход аутентификации целиком).324- **High**: аутентифицированный пользователь (в т.ч. с минимальной ролью)325 получает через эту фичу доступ к чужим данным/привилегиям — включая326 межтенантный доступ, либо неаутентифицированный атакующий получает доступ327 к данным одной компании/одного пользователя.328- **Medium**: требует специфичных условий (гонка, конкретная роль, MITM,329 социальная инженерия) или ограничивается утечкой метаданных/DoS без330 потери данных.331- **Low**: нарушение best practice без прямого сценария эксплуатации на332 момент проверки.333334Для каждой находки указывай кто может эксплуатировать (аноним /335аутентифицированный юзер / только внутренняя сеть) и что теряется (чтение /336запись / полный компромисс).337338## ФОРМАТ ОТЧЁТА3393401. Executive summary (без технического жаргона): безопасна ли фича к341 релизу, что критично, что рискует бизнесом/регуляторикой, что делать в342 первую очередь.3432. SCOPE — итоговый список проверенных файлов/директорий/сервисов (см.344 раздел "Входные данные" выше) и явное указание, что осталось ЗА345 пределами SCOPE и почему (например, "общая библиотека X не проверялась346 повторно, так как не менялась в рамках этой фичи").3473. Вердикт по фиче: "готова к релизу" / "готова с оговорками (см.348 low/medium)" / "не готова — есть critical/high находки" — одной фразой в349 начале отчёта.3504. Полный список находок: file:line, категория (можно сослаться на OWASP351 Top 10 / OWASP API Security Top 10 / CWE), конкретный сценарий352 эксплуатации, severity с обоснованием, статус, рекомендация по353 исправлению.3545. Раздел "что сделано хорошо" — сильные паттерны в реализации фичи,355 которые стоит тиражировать.3566. План действий: что блокирует релиз сейчас (critical/high), что можно357 исправить после релиза с тикетом (medium/low).3587. Раздел "что не было проверено" — ограничения покрытия (нет доступа к359 прод-окружению, нет возможности прогнать сканер и т.п.), чтобы360 отсутствие находок не читалось как "там всё чисто".361362## ПРАВИЛА ОФОРМЛЕНИЯ НАХОДОК363364Перед началом проверь, нет ли уже отчёта по этой же фиче в365`docs/bugs/security_audit/` (например, по её feature-slug или ISSUE-ID из366предыдущего прогона этого же скилла). Если есть — не начинай нумерацию с367нуля: продолжи существующую последовательность ID и обнови статус уже368известных находок ("не исправлено" → "исправлено" и т.п.), а не заводи их369повторно как новые.370371Для каждой находки обязательны:372373- Стабильный ID находки (например, `SEC-<ISSUE-ID или feature-slug>-001`),374 уникальный в рамках отчётов по этой фиче (см. выше про повторный прогон).375- Путь к файлу и номер строки (или диапазон).376- Название уязвимости и категория (OWASP Top 10 / OWASP API Security Top377 10 / CWE).378- Конкретный сценарий эксплуатации: "если сделать запрос X с параметром Y,379 система вернёт/сделает Z" — не абстрактные формулировки вроде "может быть380 уязвимость".381- Severity с обоснованием (кто может использовать, что теряется).382- Рекомендация по исправлению — конкретная ("добавить else-ветку с явным383 отказом", "включить флаг X по умолчанию", "заменить f-string на384 параметризованный запрос").385386## ЗАПУСК ПРОВЕРКИ (практическая инструкция)3873881. Сначала САМ (в основном потоке) выполни раздел "Входные данные" —389 определи тип входных данных (директория/ветка/diff, документ, YouTrack390 issue) и построй SCOPE. Не делегируй этот шаг: субагент стартует без391 контекста разговора и не знает, что имелось в виду под "фичей".392 Зафиксируй SCOPE явно, прежде чем переходить к разбору.3932. Классифицируй фичу по типу изменений (новый API, новый UI, интеграция/394 вебхук, загрузка файлов, инфраструктура и т.д.) и выбери применимые395 блоки чек-листа.3963. Проверь, нет ли уже отчёта по этой фиче в `docs/bugs/security_audit/`397 (см. "Правила оформления находок") — это дешёвая проверка, которая398 экономит повторную работу и сохраняет непрерывность нумерации находок.3994. Запусти точечные автоматизированные проверки СРЕЗА 1 по файлам/400 зависимостям из SCOPE (semgrep/bandit точечно, SCA на изменившиеся401 lock-файлы, gitleaks по diff'у фичи).4025. Проведи ручной построчный разбор СРЕЗА 2. Если SCOPE охватывает403 несколько сервисов/директорий и доступен Agent tool — раздели на404 независимые зоны и запусти отдельного субагента на зону (в foreground,405 если результат нужен для дальнейшего решения в этом же диалоге), чтобы406 не срезать угол по всему объёму разом. Каждому субагенту передай407 конкретные пути и применимые разделы этого скилла (чек-лист, шкалу408 severity, формат находки) — субагент не видит этот файл сам. Записывай409 подтверждённые находки в промежуточный файл сразу по мере разбора каждой410 зоны, а не держи их только в контексте до финального отчёта.4116. Проведи СРЕЗ 3 — точки соприкосновения фичи с существующими412 security-инвариантами платформы (аутентификация, мультитенантность,413 internal-API, общие библиотеки).4147. Сведи все три среза в единый отчёт по формату выше, убери дубликаты, но415 не объединяй находки разной природы (сканер нашёл паттерн ≠ ручной416 разбор подтвердил эксплуатируемость — фиксируй оба факта, если они417 есть). Сохрани финальный отчёт файлом в418 `docs/bugs/security_audit/<feature-slug>-security-review.md` (slug — по419 ISSUE-ID или по имени фичи/директории) — это то же место, где лежит420 реестр прошлых аудиторских находок, и следующий прогон этого скилла по421 той же фиче должен его найти и обновить, а не пересоздавать с нуля.4228. Явно укажи, какие проверки НЕ были выполнены (нет доступа к423 прод-секретам, нет доступа к рантайм-логам, нет возможности прогнать424 сканер и т.п.) — это часть честного отчёта, а не его слабость.4259. Если в проекте настроен скилл/агент `security-review` (быстрое ревью426 pending-изменений на текущей ветке) — можно использовать его как427 отправную точку для СРЕЗА 2 по изменённым файлам, но не ограничивайся428 только diff'ом: фича может опираться на существующий код, который не429 менялся в текущей ветке, но участвует в её security-модели (см. СРЕЗ 3).430431Это тестирование, не имплементация: правки вносит разработчик по итогам432отчёта, не ты в рамках этого скилла.433