Обсудить проект

Автоматизация пентеста в CI/CD: безопасность до деплоя, не после

28.09.2026

Здравствуй, воин клавиатуры! 🔥 Пора зашить безопасность в конвейер, а не тушить пожар после релиза. Гоняем очередной репорт — «security as code», без соплей, только payload’ы и yaml.

Точка входа: почему «после деплоя» — уже поздно

Классика провала: пентест раз в квартал, а между сканами накопилось 200 коммитов с новыми зависимостями и дырами. Формула DevSecOps простая — чем раньше находишь баг, тем дешевле его чинить: на этапе кода это копейки, в проде — инцидент, репутационные потери и разбор полётов с клиентом. Смещаем проверки влево (shift left) и бьём тревогу на каждый push, а не на релиз.

Карта стадий: что сканить и где

CI/CD — это конвейер с чёткими точками контроля, под каждую — свой класс инструментов:

Стадия пайплайна Что проверяем Инструменты
Pre-commit / код Секреты, утечки токенов gitleaks, TruffleHog
Build (SAST) Уязвимые паттерны в коде Semgrep, CodeQL, Bandit, Gosec
Build (SCA) Дырявые зависимости Snyk, OWASP Dependency-Check, Trivy
Package Уязвимости в Docker-образах Trivy, Grype, Clair
IaC Мисконфиги Terraform/K8s Checkov, Terrascan
Staging / после деплоя Живые баги в работающем приложении OWASP ZAP, Nuclei

Каждая стадия — отдельный gate. WAF — не стена, а приглашение, но пайплайн без gate — открытая дверь с ковриком «welcome, hacker».

Секреты и SAST: ловим на входе

Первый рубеж — не пускать хардкод-пароли и API-ключи в репу. Ставь pre-commit хук с detect-secrets или gitleaks локально у разработчиков, а в CI — обязательный шаг, который валит билд при находке:

- name: Secrets scan
  uses: gitleaks/gitleaks-action@v2

Дальше — SAST. Semgrep рвёт по скорости и покрывает JS/TS/Python/Go одним движком с готовыми правилами под OWASP Top 10:

- name: SAST scan
  run: semgrep ci --config=auto

Контейнеры и зависимости: не тащи дыры в прод

Собрал Docker-образ — прогони Trivy до пуша в registry, иначе твой красивый минимальный Alpine окажется с уязвимой libssl внутри:

- name: Container scan
  uses: aquasecurity/trivy-action@master
  with:
    image-ref: myapp:latest
    exit-code: 1
    severity: CRITICAL,HIGH

Флаг exit-code: 1 — это твой gate: находит критическую CVE — валит пайплайн, деплой не проходит. Без этого сканирование превращается в красивый, но бесполезный отчёт, который никто не читает.

DAST после деплоя: nuclei в бою

На staging нужен живой прогон против реально работающего приложения — тут в дело идёт nuclei-action, официальный GitHub Action от ProjectDiscovery:

name: DAST-scan
on:
  push:
    branches: [staging]
jobs:
  scan:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@v4
      - name: Run Nuclei
        uses: projectdiscovery/nuclei-action@v3
        with:
          args: -u https://staging.example.com -severity critical,high -tags cve,exposure

Лайфхак от опытных ребят: всегда вешай timeout-minutes на джобу со сканом. Завис скан — встал весь пайплайн, включая деплои, стоящие в очереди за ним. Забыл — и твой конвейер превращается в пробку на Кутузовском в пятницу вечером.

Результаты можно выгружать в SARIF и публиковать прямо в GitHub Code Scanning — тогда находки Nuclei ложатся рядом с findings от CodeQL в одной вкладке Security.

Лайфхаки и грабли

  • Не сканируй прод напрямую первым запуском. Гоняй Nuclei и ZAP на staging-копии, иначе легитимный скан выглядит как настоящая атака и вызывает панику у SOC.
  • Разделяй gate по severity. Критические уязвимости — блокируют деплой, medium/low — создают issue, но не рушат билд. Иначе разработчики просто выключат твой pipeline через неделю.
  • Регулярно обновляй темплейты и правила. Свежие nuclei-templates и Semgrep-rules ловят вчерашние 0day, устаревшие — только позавчерашние.
  • Собирай всё в один дашборд. DefectDojo или ASPM-платформа типа Cycode агрегируют находки SAST/SCA/DAST в единый список, иначе разработчики тонут в пяти разных отчётах.
  • Секреты — приоритет номер один. Утечка одного AWS-ключа в коммите весит больше, чем десять XSS в форме обратной связи.

Собери пайплайн так: секреты → SAST → SCA/контейнер → IaC → деплой на staging → DAST → gate на прод. Каждая стадия — фильтр, и только чистый код долетает до продакшена. Зашей это в пентест-практику, и админы перестанут думать, что их код безопасен просто потому, что «тесты прошли» 😎.