Аудит безопасности отдельной фичи (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: ru-283description: Точечный аудит безопасности ОДНОЙ конкретной фичи/изменения в 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---5# Аудит безопасности отдельной фичи (feature-scoped security review)67Для проекта the-platform: микросервисная CRM-платформа, обрабатывающая8персональные данные клиентов. Безопасность — критический приоритет, а не9формальность. Аудит должен находить реальные, эксплуатируемые проблемы с10привязкой к file:line, а не составлять общий чек-лист без проверки. Каждая11находка обязана быть подтверждена вручную, а не только упоминанием в выводе12сканера.1314Это точечная версия полного аудита репозитория (см. скилл15`security-audit-full`, если задача — весь репозиторий, а не одна фича).16Принципы верификации те же, но периметр, находки и отчёт строго ограничены17кодом, который относится к этой фиче и к тому, что она затрагивает. Логику18ручного разбора можно делегировать через Agent tool — используй19параллелизацию по зонам, как описано в разделе "Запуск проверки" ниже.2021## ВХОДНЫЕ ДАННЫЕ: КАК ОПРЕДЕЛИТЬ ФИЧУ2223Фича: `$ARGUMENTS`2425Фича передаётся в одном из трёх видов — определи, какой перед тобой, и26построй периметр проверки соответствующим способом. Периметр ВСЕГДА шире,27чем буквально указанный вход: включай прямых потребителей/вызывающий код28(роутер, который регистрирует хендлер; фронтенд, который дёргает API;29смежный сервис, которому уходит межсервисный вызов).3031**A. ДИРЕКТОРИЯ/ВЕТКА/DIFF** (например `services/xxx-service/feature_y/`32или "diff между dev и веткой feature/PROJ-XXXX"):33- Периметр = всё содержимое директории (или файлы из `git diff --stat`34 относительно базовой ветки) + модули, которые её импортируют (`grep -r`35 по имени пакета/модуля за пределами директории) + роуты/DI, которые её36 регистрируют (main.py/app factory/router include).37- Если директория — общая библиотека (libs/shared_auth, libs/shared_metrics38 и т.п.), обязательно определи ВСЕХ потребителей библиотеки по всем39 сервисам — уязвимость в общем коде размножается на весь список40 потребителей.4142**B. ДОКУМЕНТ** (путь к спецификации/дизайн-документу/PRD, .md/.txt/.docx):43- Прочитай документ целиком. Извлеки из него: имена эндпоинтов/маршрутов,44 названия моделей/таблиц, роли и права, названия UI-компонентов/экранов,45 упомянутые внешние интеграции (вебхуки, callback URL, сторонние API).46- По каждому извлечённому термину сделай `grep`/поиск по кодовой базе, чтобы47 перевести описание "что должно быть" в конкретные file:line "что есть на48 самом деле". Не ограничивайся тем, что документ говорит "реализовано" —49 проверяй код, а не текст документа.50- Если документ описывает намерение, а не факт (черновик ТЗ) — явно пометь51 в отчёте, какие пункты не нашли соответствия в коде (это тоже находка:52 несоответствие спеки и реализации может означать недоделанный контроль53 доступа).5455**C. YOUTRACK ISSUE** (ID вида `PROJ-XXXX` или ссылка):56- Получи текст issue (заголовок, описание, комментарии, acceptance criteria)57 через доступный в проекте механизм интеграции с трекером (MCP-инструмент58 YouTrack/Jira/GitHub/Linear, если подключён).59 Если программного доступа нет — прямо запроси у пользователя текст issue и60 ссылки на связанные PR, не додумывай содержание.61- Найди связанные коммиты и файлы по ID тикета: коммиты в этом репозитории62 принято помечать номером тикета в сообщении (например `PROJ-1042`,63 `PROJ-1031`, `PROJ-318`) — используй `git log --all --grep=<ISSUE-ID>64 --oneline`, затем `git show --stat <hash>` / `git log --all -- <файлы из65 commit>`, чтобы построить список затронутых файлов и сервисов.66- Если тикет ссылается на PR/ветку — проверь именно diff этой ветки67 (`git diff main...<branch>`), а не только финальное состояние main, чтобы68 не пропустить промежуточные версии, если ветка ещё не смержена.6970Если ни один из трёх источников не даёт однозначно определить периметр —71остановись и явно перечисли, что нужно уточнить у автора задачи, вместо того72чтобы проверять наугад весь сервис целиком.7374Явно зафиксируй в начале отчёта итоговый периметр (список75file/директорий/сервисов), который получился после этого шага — это твой76рабочий SCOPE, дальше весь аудит идёт по нему, плюс точки соприкосновения с77остальной системой (см. СРЕЗ 3 ниже).7879## КЛЮЧЕВОЙ ПРИНЦИП: ВЕРИФИКАЦИЯ, А НЕ ДОВЕРИЕ8081Причина, по которой проверки фич проваливаются, — принятие на веру того, что82"код написан по ТЗ" эквивалентно "фича безопасна". Это НЕ так. Проверяй83адверсариально:84851. Если фича добавляет проверку (флаг, HMAC-подпись, экранирование,86 авторизация) — убедись, что она ВКЛЮЧЕНА по умолчанию и активна во всех87 окружениях (dev/staging/prod), а не только реализована в коде и88 выключена флагом.892. Если фича добавляет экранирование ввода — проверь ПОЛНОТУ (одиночная90 кавычка, двойная кавычка, обратный слэш, null-байт, юникод-обход), а не91 только очевидный случай.923. Если фича защищает один эндпоинт/сервис — проверь, нет ли у неё "братьев93 и сестёр" того же класса операций в другом месте кодовой базы, которые94 остались незащищёнными (например, фича добавила auth на POST, но не на95 DELETE того же ресурса, или на аналогичный bulk-эндпоинт).964. Если в фиче есть RBAC/switch/if-else по ролям — проверь ветку "иначе"97 (default case). Отсутствие явного отказа в доступе по умолчанию — это98 дыра.995. Не принимай описание в тикете/ТЗ ("это уже защищено", "тут используется100 общий middleware") без самостоятельной проверки текущего кода.1016. Формулируй статус явно: "не реализовано" / "реализовано формально (код102 есть, защиты нет)" / "реализовано выборочно (часть класса покрыта)" /103 "реализовано полностью" / "новая находка вне рамок задачи фичи".104105## МЕТОДОЛОГИЯ: ТРИ НЕЗАВИСИМЫХ СРЕЗА (в границах SCOPE фичи)106107### СРЕЗ 1 — Точечное автоматизированное сканирование108109- Если фича добавила новые зависимости (новая запись в110 requirements/pyproject/package.json) — прогони pip-audit/npm audit111 точечно по изменившемуся lock-файлу, а не по всему репозиторию.112- semgrep/bandit по файлам из SCOPE (injection, ssrf, insecure113 deserialization, hardcoded secrets, weak crypto).114- Если фича трогает Dockerfile/helm-values/k8s-манифесты — checkov/115 kube-linter точечно по изменённым файлам.116- gitleaks/trufflehog по diff'у фичи (`git diff`/`git log -p` на затронутых117 файлах и коммитах) — секрет мог быть закоммичен и затем удалён в рамках118 той же ветки.119120### СРЕЗ 2 — Ручной построчный разбор кода фичи121122Разбери построчно (не по диагонали) каждый файл из SCOPE, применяя чек-лист123по категориям ниже — только те категории, которые реально применимы к тому,124что делает фича (см. подсказки применимости перед чек-листом). Для каждой125находки: file:line, тип уязвимости, конкретный сценарий эксплуатации126("запрос X с параметром Y даёт результат Z"), severity, статус.127128Если SCOPE большой (несколько сервисов/директорий) и доступен Agent tool —129раздели на независимые зоны и используй несколько субагентов, каждому —130своя зона, чтобы не срезать угол по всему объёму разом (см. "Запуск131проверки" ниже).132133### СРЕЗ 3 — Точки соприкосновения с остальной системой134135Независимо от построчного разбора ответь: как фича встраивается в136существующие security-инварианты платформы, а не только "нет ли дыр в её137собственном коде"?138139- Использует ли фича существующие механизмы аутентификации/авторизации/140 мультитенантности, или изобретает собственный путь в обход них (новый141 хендлер, который не проходит через общий auth-middleware/RBAC-декоратор)?142- Если фича добавляет новый internal-эндпоинт между сервисами — защищён ли143 он тем же shared-secret/mTLS механизмом, что и остальной класс144 `/internal/*` эндпоинтов, или это исключение?145- Если фича добавляет новую точку чтения/записи данных — фильтруется ли она146 по company_id/tenant_id так же, как остальные точки того же типа в147 системе?148- Если фича переиспользует общую библиотеку (libs/shared_auth и т.п.) —149 использует ли актуальную версию как единый пакет, или скопировала/150 форкнула логику себе?151- Ломает ли фича какой-то из существующих security-инвариантов, описанных в152 предыдущих аудитах репозитория. В проекте это не абстрактная оговорка —153 реестр прошлых находок лежит в `docs/bugs/security_audit/` (по каждой154 находке прошлого аудита зафиксирован вердикт: подтвердилась / false155 positive / уже исправлена), а регрессионная проверка по нему —156 `scripts/verify_audit_fixes.py`. Если SCOPE фичи пересекается по теме или157 файлам с одной из находок в этой папке — обязательно прогони скрипт (если158 он есть в репозитории) и явно сверь текущий статус, а не переоткрывай159 находку с нуля.160- Если находка по фиче фактически совпадает с уже трекнутым в161 `docs/bugs/security_audit/` риском, который был осознанно принят (низкая162 реплика для HA, отключённый networkPolicy и т.п.) — сошлись на163 существующий файл-находку вместо того, чтобы заводить дубликат как "новую164 находку фичи"; отметь только если фича делает риск хуже, чем он был165 зафиксирован.166167## ЧЕК-ЛИСТ ПО КАТЕГОРИЯМ (применяй те, что релевантны фиче)168169Перед разбором быстро классифицируй фичу: какие из блоков ниже применимы170(новый API-эндпоинт → блоки 1,2,5,6,10; новый UI-экран → блоки 1,7; загрузка171файлов → блок 9; интеграция/вебхук → блоки 4,6,8; инфраструктурное изменение172→ блоки 11,12). Не пропускай блок только потому что "фича маленькая" —173маленькие фичи типично и есть источник точечных дыр (см. "Edge cases" ниже).1741751. **Аутентификация и авторизация**176 - Требует ли новый/изменённый эндпоинт аутентификации так же, как177 остальные эндпоинты того же сервиса (нет ли "забытого" открытого178 маршрута)?179 - RBAC-ветки: что происходит для роли, не попавшей ни в одну явную ветку180 (default/else)? Приводит ли это к утечке (нет фильтра по181 assigned_user_id/owner_id)?182 - IDOR/BOLA: можно ли, меняя ID в URL/body, получить доступ к чужому183 объекту, которым оперирует фича?184 - Broken function level authorization: доступна ли новая185 административная/массовая операция без проверки роли?186 - Mass assignment/over-posting: принимает ли новый/изменённый API187 произвольные поля тела запроса (role, is_admin, company_id, balance и188 т.п.), или список разрешённых полей — explicit whitelist?189 - Session/token: если фича трогает сессии/токены — где хранение, есть ли190 инвалидация, ограничение времени жизни?191 - Rate limiting: если фича добавляет login/сброс пароля/OTP-подобный192 поток — есть ли лимит попыток?1931942. **Мультитенантность (изоляция между компаниями-клиентами)** — разбирай195 отдельно от общего IDOR, межтенантная утечка тяжелее по последствиям.196 - Каждая новая точка чтения/записи (REST-хендлер, WS-подписка, кэш-ключ,197 поисковый индекс, очередь, экспорт) — фильтруется ли по198 company_id/tenant_id на уровне запроса к БД, а не только на уровне199 UI/роутера?200 - Совпадение company_id проверяется явным сравнением значения из201 токена/контекста с company_id записи, а не подразумевается?202 - Общие ресурсы (Redis-ключи, RabbitMQ-очереди, файловое хранилище) — не203 коллизирует ли ключ/имя между компаниями при одинаковых внутренних ID?204 - Новая Alembic-миграция/DDL: у новой таблицы/колонки, которая хранит205 данные конкретной компании, есть ли `company_id`/`tenant_id` и индекс206 по нему — структурный пробел на уровне схемы не поймать построчным207 разбором запросов, если сам столбец отсутствует.2082093. **WebSocket / realtime** (если фича трогает realtime-канал)210 - Проверяется ли токен/роль/company_id при connect И отдельно при каждой211 подписке на канал/комнату (join)?212 - Может ли клиент подписаться на чужой канал, подставив/угадав213 room-id/dialog-id/user-id?214 - Broadcast фильтруется по company_id/роли перед отправкой, или сервер215 полагается на то, что клиент "просто не подписан"?2162174. **Internal-API между сервисами** (если фича добавляет/меняет218 `/internal/*`)219 - Требует ли shared-secret/mTLS так же, как остальные эндпоинты того же220 класса операций в других сервисах? Проверяется ли секрет фактически (а221 не только объявлен в env)?222 - Может ли новый internal-эндпоинт быть вызван напрямую снаружи223 кластера?2242255. **Инъекции (SQL / NoSQL / Command / Template / Deserialization)**226 - Сборка запросов конкатенацией/f-string/format вместо параметризованных227 запросов/ORM — особенно в новых query-параметрах (фильтры, поиск,228 сортировка).229 - Экранирование "вручную" — проверь полноту (обратный слэш, юникод,230 вложенные кавычки).231 - Command injection: новые subprocess/os.system/exec с пользовательским232 вводом.233 - Небезопасная десериализация новых данных из очереди/вебхука/234 межсервисного вызова (pickle, yaml.load без SafeLoader, eval/exec).2352366. **SSRF** (если фича делает исходящий HTTP-запрос по внешнему URL)237 - Есть ли allow-list доменов, блокировка приватных/internal238 IP-диапазонов (169.254.x.x, 10.x, 172.16-31.x, 192.168.x, 127.x, cloud239 metadata)?240 - Проверяется ли подпись/источник вебхука перед тем, как система241 инициирует ответный запрос по URL из его тела?2422437. **XSS** (включая клиентские виджеты, если фича — frontend/встраиваемый244 компонент)245 - innerHTML/dangerouslySetInnerHTML/document.write с недоверенными246 данными.247 - Если фича — встраиваемый на сторонних сайтах виджет: уязвимость видна248 конечным пользователям клиентов вашей платформы — квалифицируй severity249 с учётом расширенного радиуса поражения.250 - CSP/clickjacking-заголовки не ослаблены ли новым кодом.2512528. **Работа с секретами и PII** (если фича трогает интеграции/токены/PII)253 - Новые секреты в коде/конфигах, отслеживаемых git.254 - Токены новых интеграций в БД — открытым текстом или зашифрованы?255 - Маскирование секретов в новых логах — работает ли для новых типов256 данных, которые ввела фича?2572589. **Загрузка и хранение файлов** (если фича добавляет upload/скачивание)259 - Проверка MIME-типа/расширения (не доверять Content-Type от клиента).260 - Ограничение размера, защита от zip-бомб.261 - Path traversal при формировании пути из пользовательского ввода.262 - Публичная раздача — требует ли аутентификации, если файлы содержат263 PII?26426510. **Зависимости и суплай-чейн** (если фича добавила новые пакеты)266 - Критичность новых зависимостей, есть ли более безопасная267 альтернатива.268 - Новый внутренний пакет — устанавливается из приватного индекса/269 локального пути, или по голому имени, которое можно подменить с270 публичного PyPI/npm (dependency confusion)?27127211. **Docker / контейнеры** (если фича меняет Dockerfile)273 - USER указан (non-root)? Секреты не через ARG/ENV?27427512. **Kubernetes / Helm** (если фича меняет values/манифесты)276 - networkPolicy/securityContext/resources не ослаблены ли новым277 values-файлом относительно существующего baseline проекта?278 - Секреты через Kubernetes Secrets, а не открытым текстом в279 values.yaml?28028113. **Обработка ошибок и наблюдаемость**282 - Новый broad except с логированием и возвратом None/пустого результата283 без re-raise — не маскирует ли это отказ проверки авторизации как284 "разрешено"?285 - Логируются ли новые security-события (неудачные авторизации,286 изменения ролей) отдельно?287 - Утечка внутренней информации через новые сообщения об ошибках наружу.28828914. **CI/CD** (если фича меняет пайплайн)290 - CI script injection: интерполируется ли непроверенный внешний ввод291 (заголовок PR, имя ветки) напрямую в шаг `run:`?292 - Новый security-гейт реально блокирует мерж, или только печатает293 предупреждение?294295## EDGE CASES, КОТОРЫЕ ЧАСТО ПРОПУСКАЮТ ПРИ ТЕСТИРОВАНИИ ФИЧИ296297- Функциональность, защищённая на UI-уровне (кнопка скрыта), но доступная298 напрямую через API без проверки на бэкенде.299- Race condition в "check-then-act" (проверка роли и действие не атомарны).300- Поведение для soft-deleted записей — доступны ли они через новый301 эндпоинт, который не учитывает флаг удаления.302- Bulk-вариант новой фичи (bulk-эндпоинт) — часто добавлен "по-быстрому" со303 слабее проверенной авторизацией, чем у единичного аналога.304- Вебхук, который фича добавляет — проверяется ли подпись/источник.305- Feature-флаг фичи, выключенный "временно для отладки" и оставленный306 выключенным по умолчанию в конфиге.307- Различия dev/staging/prod — фикс, применённый в одной helm-values-308 конфигурации, может отсутствовать в другой.309- Экспорт данных, если фича его добавляет — авторизация на экспортируемый310 объём так же строга, как на обычное чтение?311- Старый/дублирующий путь, оставшийся после рефакторинга фичи (например,312 старый эндпоинт не удалили, а просто перестали вызывать с фронтенда — он313 всё ещё доступен и не обновлён под новую логику авторизации).314315## ШКАЛА SEVERITY (единая с полным аудитом репозитория)316317Единая шкала нужна, чтобы находки были сравнимы между проверками отдельных318фич и общими аудитами (см. `security-audit-full`).319320- **Critical**: неаутентифицированный внешний атакующий получает полный321 компромисс через эту фичу (RCE, доступ ко всем данным всех322 компаний-клиентов, обход аутентификации целиком).323- **High**: аутентифицированный пользователь (в т.ч. с минимальной ролью)324 получает через эту фичу доступ к чужим данным/привилегиям — включая325 межтенантный доступ, либо неаутентифицированный атакующий получает доступ326 к данным одной компании/одного пользователя.327- **Medium**: требует специфичных условий (гонка, конкретная роль, MITM,328 социальная инженерия) или ограничивается утечкой метаданных/DoS без329 потери данных.330- **Low**: нарушение best practice без прямого сценария эксплуатации на331 момент проверки.332333Для каждой находки указывай кто может эксплуатировать (аноним /334аутентифицированный юзер / только внутренняя сеть) и что теряется (чтение /335запись / полный компромисс).336337## ФОРМАТ ОТЧЁТА3383391. Executive summary (без технического жаргона): безопасна ли фича к340 релизу, что критично, что рискует бизнесом/регуляторикой, что делать в341 первую очередь.3422. SCOPE — итоговый список проверенных файлов/директорий/сервисов (см.343 раздел "Входные данные" выше) и явное указание, что осталось ЗА344 пределами SCOPE и почему (например, "общая библиотека X не проверялась345 повторно, так как не менялась в рамках этой фичи").3463. Вердикт по фиче: "готова к релизу" / "готова с оговорками (см.347 low/medium)" / "не готова — есть critical/high находки" — одной фразой в348 начале отчёта.3494. Полный список находок: file:line, категория (можно сослаться на OWASP350 Top 10 / OWASP API Security Top 10 / CWE), конкретный сценарий351 эксплуатации, severity с обоснованием, статус, рекомендация по352 исправлению.3535. Раздел "что сделано хорошо" — сильные паттерны в реализации фичи,354 которые стоит тиражировать.3556. План действий: что блокирует релиз сейчас (critical/high), что можно356 исправить после релиза с тикетом (medium/low).3577. Раздел "что не было проверено" — ограничения покрытия (нет доступа к358 прод-окружению, нет возможности прогнать сканер и т.п.), чтобы359 отсутствие находок не читалось как "там всё чисто".360361## ПРАВИЛА ОФОРМЛЕНИЯ НАХОДОК362363Перед началом проверь, нет ли уже отчёта по этой же фиче в364`docs/bugs/security_audit/` (например, по её feature-slug или ISSUE-ID из365предыдущего прогона этого же скилла). Если есть — не начинай нумерацию с366нуля: продолжи существующую последовательность ID и обнови статус уже367известных находок ("не исправлено" → "исправлено" и т.п.), а не заводи их368повторно как новые.369370Для каждой находки обязательны:371372- Стабильный ID находки (например, `SEC-<ISSUE-ID или feature-slug>-001`),373 уникальный в рамках отчётов по этой фиче (см. выше про повторный прогон).374- Путь к файлу и номер строки (или диапазон).375- Название уязвимости и категория (OWASP Top 10 / OWASP API Security Top376 10 / CWE).377- Конкретный сценарий эксплуатации: "если сделать запрос X с параметром Y,378 система вернёт/сделает Z" — не абстрактные формулировки вроде "может быть379 уязвимость".380- Severity с обоснованием (кто может использовать, что теряется).381- Рекомендация по исправлению — конкретная ("добавить else-ветку с явным382 отказом", "включить флаг X по умолчанию", "заменить f-string на383 параметризованный запрос").384385## ЗАПУСК ПРОВЕРКИ (практическая инструкция)3863871. Сначала САМ (в основном потоке) выполни раздел "Входные данные" —388 определи тип входных данных (директория/ветка/diff, документ, YouTrack389 issue) и построй SCOPE. Не делегируй этот шаг: субагент стартует без390 контекста разговора и не знает, что имелось в виду под "фичей".391 Зафиксируй SCOPE явно, прежде чем переходить к разбору.3922. Классифицируй фичу по типу изменений (новый API, новый UI, интеграция/393 вебхук, загрузка файлов, инфраструктура и т.д.) и выбери применимые394 блоки чек-листа.3953. Проверь, нет ли уже отчёта по этой фиче в `docs/bugs/security_audit/`396 (см. "Правила оформления находок") — это дешёвая проверка, которая397 экономит повторную работу и сохраняет непрерывность нумерации находок.3984. Запусти точечные автоматизированные проверки СРЕЗА 1 по файлам/399 зависимостям из SCOPE (semgrep/bandit точечно, SCA на изменившиеся400 lock-файлы, gitleaks по diff'у фичи).4015. Проведи ручной построчный разбор СРЕЗА 2. Если SCOPE охватывает402 несколько сервисов/директорий и доступен Agent tool — раздели на403 независимые зоны и запусти отдельного субагента на зону (в foreground,404 если результат нужен для дальнейшего решения в этом же диалоге), чтобы405 не срезать угол по всему объёму разом. Каждому субагенту передай406 конкретные пути и применимые разделы этого скилла (чек-лист, шкалу407 severity, формат находки) — субагент не видит этот файл сам. Записывай408 подтверждённые находки в промежуточный файл сразу по мере разбора каждой409 зоны, а не держи их только в контексте до финального отчёта.4106. Проведи СРЕЗ 3 — точки соприкосновения фичи с существующими411 security-инвариантами платформы (аутентификация, мультитенантность,412 internal-API, общие библиотеки).4137. Сведи все три среза в единый отчёт по формату выше, убери дубликаты, но414 не объединяй находки разной природы (сканер нашёл паттерн ≠ ручной415 разбор подтвердил эксплуатируемость — фиксируй оба факта, если они416 есть). Сохрани финальный отчёт файлом в417 `docs/bugs/security_audit/<feature-slug>-security-review.md` (slug — по418 ISSUE-ID или по имени фичи/директории) — это то же место, где лежит419 реестр прошлых аудиторских находок, и следующий прогон этого скилла по420 той же фиче должен его найти и обновить, а не пересоздавать с нуля.4218. Явно укажи, какие проверки НЕ были выполнены (нет доступа к422 прод-секретам, нет доступа к рантайм-логам, нет возможности прогнать423 сканер и т.п.) — это часть честного отчёта, а не его слабость.4249. Если в проекте настроен скилл/агент `security-review` (быстрое ревью425 pending-изменений на текущей ветке) — можно использовать его как426 отправную точку для СРЕЗА 2 по изменённым файлам, но не ограничивайся427 только diff'ом: фича может опираться на существующий код, который не428 менялся в текущей ветке, но участвует в её security-модели (см. СРЕЗ 3).429430Это тестирование, не имплементация: правки вносит разработчик по итогам431отчёта, не ты в рамках этого скилла.