SAST, DAST и SCA в CI: пайплайн безопасности Shift-Left
Updated Jul 2026
Что такое Shift-Left безопасность?
Shift-left безопасность означает интеграцию тестирования безопасности на ранних этапах жизненного цикла разработки — в идеале в CI/CD-пайплайнах — вместо ожидания тестирования на проникновение перед релизом. Для ИИ-приложений это означает запуск статического анализа, сканирования зависимостей и динамического тестирования при каждом коммите, с правилами, специфичными для ИИ, которые ловят уязвимости, пропускаемые традиционными инструментами.
Ландшафт инструментов
| Категория | Инструмент | Что делает | Точка интеграции | Стоимость |
|---|---|---|---|---|
| SAST | Semgrep | Анализ кода на основе паттернов | Pre-commit hook, CI | Бесплатно (правила с открытым исходным кодом) |
| SAST | CodeQL | Глубокий семантический анализ кода | GitHub Actions (нативно) | Бесплатно для публичных репозиториев |
| DAST | ZAP (OWASP) | Активное сканирование веб-уязвимостей | CI (против staging) | Бесплатно/с открытым кодом |
| DAST | Burp Suite | Комплексное тестирование веб-безопасности | Ручное + CI (Enterprise) | Коммерческий |
| SCA | Snyk | Сканирование уязвимостей зависимостей | CI, IDE, реестр | Freemium |
| SCA | Dependabot | Автоматическое обновление зависимостей | GitHub нативно | Бесплатно |
| Секреты | GitLeaks | Обнаружение секретов в истории git | Pre-commit hook | Бесплатно/с открытым кодом |
| Контейнеры | Trivy | Сканирование уязвимостей образов контейнеров | CI | Бесплатно/с открытым кодом |
Полный CI-пайплайн безопасности
# .github/workflows/security.yml
name: Security Checks
on:
pull_request:
branches: [main]
push:
branches: [main]
jobs:
sast:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Semgrep SAST scan
uses: semgrep/semgrep-action@v1
with:
config: >-
p/owasp-top-ten
p/python
p/typescript
p/secrets
p/ai-security
generateSarif: true
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: semgrep.sarif
sca:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Snyk dependency scan
uses: snyk/actions/python@master
with:
args: --severity-threshold=high
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
secrets:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Detect secrets
uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
dast:
runs-on: ubuntu-latest
needs: [sast, sca] # only run DAST if static checks pass
steps:
- uses: actions/checkout@v4
- name: Deploy to ephemeral environment
run: ./scripts/deploy-ephemeral.sh
- name: OWASP ZAP full scan
uses: zaproxy/action-full-scan@v0.10.0
with:
target: ${{ env.EPHEMERAL_URL }}
rules_file_name: zap-rules.tsv
cmd_options: '-a -j'
- name: Upload ZAP report
uses: actions/upload-artifact@v4
with:
name: zap-report
path: report_html.html
container-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: docker build -t app:${{ github.sha }} .
- name: Trivy container scan
uses: aquasecurity/trivy-action@master
with:
image-ref: app:${{ github.sha }}
format: sarif
output: trivy-results.sarif
severity: 'CRITICAL,HIGH'
- name: Upload Trivy SARIF
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: trivy-results.sarif
Правила Semgrep, специфичные для ИИ
Стандартные правила SAST не обнаруживают уязвимости, специфичные для ИИ. Напишите собственные правила Semgrep:
# .semgrep/ai-security-rules.yaml
rules:
- id: llm-output-used-in-sql
pattern: |
$QUERY = f"... {$LLM_RESPONSE} ..."
$DB.execute($QUERY)
message: "LLM output used directly in SQL query. Use parameterized queries."
severity: ERROR
languages: [python]
metadata:
category: security
owasp: "A03:Injection"
ai_specific: true
- id: llm-output-used-in-shell
patterns:
- pattern: os.system(f"... {$LLM_RESPONSE} ...")
- pattern: subprocess.run(f"... {$LLM_RESPONSE} ...", shell=True)
message: "LLM output used in shell command. Sanitize or use allowlist."
severity: ERROR
languages: [python]
metadata:
category: security
owasp: "A03:Injection"
- id: api-key-in-prompt
pattern: |
$PROMPT = f"... $API_KEY ..."
message: "API key may be included in LLM prompt. Remove sensitive data."
severity: WARNING
languages: [python]
- id: no-output-sanitization
pattern: |
$RESPONSE = $LLM.generate(...)
return $RESPONSE
message: "LLM output returned without sanitization. Add output validation."
severity: WARNING
languages: [python]
- id: no-max-tokens-set
pattern: |
$CLIENT.chat.completions.create(
...,
~max_tokens,
...
)
message: "LLM call without max_tokens. Set a limit to prevent cost/DoS issues."
severity: WARNING
languages: [python]
- id: hardcoded-llm-api-key
patterns:
- pattern: '"sk-..."'
- pattern: "'sk-...'"
- pattern: |
$KEY = "sk-$REST"
message: "Hardcoded OpenAI API key detected. Use environment variables."
severity: ERROR
languages: [python, javascript, typescript]
Понимание каждого уровня безопасности
SAST (Static Application Security Testing)
Анализирует исходный код без его выполнения. Обнаруживает уязвимости на уровне кода на ранних этапах.
Что обнаруживает в ИИ-приложениях:
- Вывод LLM, используемый в SQL/shell без санитизации
- API-ключи, зашитые в шаблоны промптов
- Отсутствие валидации вывода ответов LLM
- Небезопасная десериализация выходных данных модели
Ограничения: Не может обнаружить поведение во время выполнения, проблемы конфигурации или логические дефекты.
DAST (Dynamic Application Security Testing)
Тестирует работающее приложение, отправляя запросы и анализируя ответы.
Что обнаруживает в ИИ-приложениях:
- XSS через HTML-контент, сгенерированный LLM
- SSRF через функции загрузки URL ИИ
- Обход аутентификации на ИИ-эндпоинтах
- Раскрытие информации в сообщениях об ошибках
Ограничения: Требует работающего окружения, медленнее SAST, не видит проблем на уровне кода.
SCA (Software Composition Analysis)
Сканирует зависимости на известные уязвимости (CVE).
Что обнаруживает в ИИ-приложениях:
- CVE в библиотеках PyTorch, TensorFlow, LangChain, Hugging Face
- Уязвимые транзитивные зависимости в ML-пайплайне
- Проблемы соответствия лицензий зависимостей моделей
Специфичные для ML проблемы SCA:
- ML-библиотеки обновляются реже, чем веб-фреймворки
- Файлы моделей из внешних источников могут содержать вредоносные полезные нагрузки
- Экосистема LangChain имела несколько критических CVE
Архитектура пайплайна
Developer Commits Code
|
v
+------------------+
| Pre-commit Hooks | <-- GitLeaks (secrets), Semgrep (quick scan)
| (< 30 seconds) | Runs before code leaves developer machine
+--------+---------+
|
v
+------------------+
| SAST + SCA | <-- Semgrep (full), Snyk (deps), CodeQL (deep)
| (2-5 minutes) | Runs on every PR
+--------+---------+
|
v
+------------------+
| DAST | <-- OWASP ZAP against ephemeral environment
| (10-30 minutes) | Runs after SAST passes (why scan if code is broken?)
+--------+---------+
|
v
+------------------+
| Container Scan | <-- Trivy (image vulnerabilities)
| (2-5 minutes) | Runs on every built image
+--------+---------+
|
v
+------------------+
| AI Security | <-- Prompt injection, jailbreak, data leakage tests
| Tests | Runs when AI code or prompts change
| (5-15 minutes) |
+------------------+
Обработка находок безопасности
Реагирование на основе серьёзности
| Серьёзность | SLA | Действие |
|---|---|---|
| Критическая (напр., SQL-инъекция, утечка API-ключа) | Блокировка мержа, исправить немедленно | PR не может быть смержен до исправления |
| Высокая (напр., XSS, уязвимая зависимость) | Исправить в течение 3 дней | PR может быть смержен с одобрения команды безопасности |
| Средняя (напр., отсутствующие заголовки, раскрытие информации) | Исправить в течение 2 недель | PR может быть смержен, создаётся тикет |
| Низкая (напр., нарушение лучших практик) | Исправить в следующем спринте | Без блокировки мержа, только предупреждение |
Управление ложными срабатываниями
Инструменты SAST генерируют ложные срабатывания. Управляйте ими систематически:
# .semgrep-ignore.yaml
rules:
- id: no-output-sanitization
paths:
# Internal tools that only display to admins
- src/admin/debug_panel.py
comment: "Admin debug panel, no user-facing output"
approved_by: "security-team"
approved_date: "2026-01-15"
Отслеживайте долю ложных срабатываний. Если она превышает 20%, команда перестанет доверять инструменту. Настраивайте правила для снижения шума при сохранении способности обнаружения.
Пайплайн безопасности — это не конфигурация «настроил и забыл». Просматривайте находки еженедельно, обновляйте правила ежемесячно и переоценивайте эффективность инструментов ежеквартально.