
Сканер безопасности Docker на базе ИИ, который объясняет уязвимости простым языком. Лабораторный проект OWASP.
<div align="center"> [](https://owasp.org/DockSec/) [](https://owasp.org/DockSec/) [](https://owasp.slack.com/archives/C0APXGCUW7M) [](https://github.com/OWASP/DockSec/actions) <br>[](https://www.bestpractices.dev/projects/12939) [](https://github.com/OWASP/DockSec/blob/main/LICENSE) [](https://github.com/OWASP/DockSec/commits/main/) [](https://github.com/OWASP/DockSec/graphs/contributors) [](https://github.com/OWASP/DockSec/network/members) [](https://github.com/OWASP/DockSec/stargazers)  [](https://github.com/OWASP/DockSec/issues) [](https://github.com/OWASP/DockSec/pulls) [](https://github.com/OWASP/DockSec/commit/80664db8935e4b5ab44df5867913e) <picture> <source srcset="https://raw.githubusercontent.com/OWASP/DockSec/main/images/docksec-logo-for-github.png" media="(prefers-color-scheme: dark)"> <img src="https://assets.kitploit.com/production/public/readmes/39487/d30ee74abf3ad22a447ed36ba3010acab606147bc21702a1fb428b8633298caf.png" alt="DockSec Logo" width="600"> </picture><br> <img src="https://assets.kitploit.com/production/public/readmes/39487/009ae678c48ab2738e17c17c238c83cb2481510fbc2bf9d7284ea80ec487feda.png" alt="OWASP Logo" width="300"> # [DockSec](https://owasp.org/DockSec/) **Сканер безопасности Docker на базе ИИ, который объясняет уязвимости простым языком** </div> --- ## Что такое DockSec? DockSec — это **лабораторный проект OWASP**, который сокращает разрыв между сложными результатами сканирования безопасности и практическими исправлениями для разработчиков. Он объединяет отраслевые стандартные сканеры (Trivy, Hadolint, Docker Scout) с ИИ для обеспечения **контекстно-зависимого анализа безопасности**. Вместо того чтобы ошеломлять вас списком из 200+ CVE, DockSec: - **Расставляет приоритеты** того, что действительно влияет на вашу конкретную конфигурацию контейнера. - **Объясняет** уязвимости простым языком, а не только с помощью специального жаргона безопасности. - **Предлагает** конкретные исправления для вашего Dockerfile. - **Создаёт** профессиональные интерактивные отчёты о безопасности для вашей команды. Всё сканируется локально; единственное, что когда-либо покидает вашу машину, — это (с удалёнными секретами) содержимое файлов, отправляемое выбранному вами провайдеру ИИ. А при использовании локальной модели или режима только сканирования ничего не покидает машину вообще. См. [Поток данных и конфиденциальность](#data-flow-and-privacy). --- ## Как это работает <div align="center"> <img src="https://assets.kitploit.com/production/public/readmes/39487/99b4247f599cc8f7a260f285815f8793ca4d2c050ea6656480818a846d590fb0.png" alt="DockSec Workflow" width="800"> <p><em>Рабочий процесс DockSec: от сканирования до практических выводов</em></p> </div> DockSec следует конвейеру из пяти этапов: 1. **Сканирование**: запускает Trivy (уязвимости образов и ошибки конфигурации Dockerfile), Hadolint и Docker Scout локально в вашей среде. 2. **Приоритизация**: ранжирует каждую находку CVE по серьёзности в сочетании с [EPSS](https://www.first.org/epss/) — вероятностью эксплуатации, поэтому список упорядочен по тому, что исправлять в первую очередь, а не по тому, что было найдено первым. 3. **Корреляция**: обнаруживает [цепочки эксплойтов](https://github.com/owasp/docksec/blob/main/docs/exploit-chains.md), где отдельные находки объединяются в один путь атаки — база данных с учётными данными, доступная из интернет-сервиса, — это цепочка, а не две несвязанные находки. При наличии API-ключа ИИ-проход анализирует полный вывод сканирования, чтобы ранжировать, объяснить и расширить это. 4. **Рекомендации**: создаёт команды исправления для копирования и запуска, а также конкретные изменения Dockerfile или compose и указывает, сколько находок они устраняют. 5. **Отчёт**: экспортирует практические результаты в форматах HTML, PDF, JSON, CSV, Markdown, SARIF и CycloneDX SBOM. --- ## Начало работы ### 1. Предварительные требования DockSec оркестрирует локальные сканеры, поэтому ему требуется: | Требование | Для чего нужно | Установка | |---|---|---| | Python 3.12+ | Сам DockSec | [python.org](https://www.python.org/downloads/) | | Trivy | Все сканирования (обязательно) | `brew install trivy` или [документация Trivy](https://trivy.dev/latest/getting-started/installation/) | | Hadolint | Линтинг Dockerfile | `brew install hadolint` или [документация Hadolint](https://github.com/hadolint/hadolint#install) | | Docker | Сканирование образов (`-i`) | [документация Docker](https://docs.docker.com/get-docker/) | Или позвольте DockSec установить Trivy и Hadolint за вас:```bash python -m docksec.setup_external_tools ``` ### 2. Установка DockSec```bash # Full install with AI analysis support (recommended) pip install "docksec[ai]" # Or the slim, scan-only core (no LLM dependencies, no API key needed) pip install docksec ``` ### 3. Запустите первое сканирование Для локального сканирования API-ключ не требуется:```bash docksec Dockerfile --scan-only ``` Каждое сканирование завершается сводкой результатов: таблица серьёзности, оценка безопасности от 0 до 100 с рейтингом, блок действий «Quick take», сгенерированные отчёты (по умолчанию сохраняются в `~/.docksec/results/`) и предлагаемая следующая команда. ### 4. Включение AI-анализа AI-анализ объясняет обнаруженные проблемы и предлагает исправления. Выберите провайдера, задайте его API-ключ и выполните:```bash # OpenAI (default provider) export OPENAI_API_KEY="sk-..." docksec Dockerfile # Anthropic Claude export ANTHROPIC_API_KEY="sk-ant-..." docksec Dockerfile --ai-only --provider anthropic --model claude-sonnet-5 # Google Gemini export GOOGLE_API_KEY="..." docksec Dockerfile --ai-only --provider google # Ollama (fully local, no API key, data never leaves your machine) docksec Dockerfile --ai-only --provider ollama --model llama3.1 ``` У каждого провайдера есть разумная модель по умолчанию (OpenAI: `gpt-4o`, Anthropic: `claude-haiku-4-5`, Google: `gemini-1.5-pro`, Ollama: `llama3.1`), поэтому `--model` необязателен. Чтобы не повторять флаги, задайте переменные окружения (или поместите их в файл `.env` в каталоге, из которого вы запускаете — DockSec загружает его автоматически):```bash export LLM_PROVIDER=anthropic export LLM_MODEL=claude-sonnet-5 docksec Dockerfile ``` Перед отправкой любого содержимого AI-провайдеру значения, похожие на секреты (пароли, токены, API-ключи, блоки приватных ключей), автоматически маскируются. См. [Поток данных и конфиденциальность](#data-flow-and-privacy). ### 5. Или запустите образ контейнера (ничего устанавливать не нужно) Опубликованный образ содержит закреплённые версии Trivy и Hadolint, так что ничего не нужно устанавливать и ничего настраивать:```bash docker run --rm -v "$PWD:/github/workspace" \ -e INPUT_DOCKERFILE=Dockerfile \ -e INPUT_SCAN_ONLY=true \ ghcr.io/owasp/docksec:latest ``` Публикуется для нескольких архитектур (amd64 и arm64) при каждом релизе. В CI указывайте конкретную версию (`ghcr.io/owasp/docksec:2026.9.21`) или минорную серию (`ghcr.io/owasp/docksec:2026.9`), а не `latest`. Каждый образ содержит аттестацию происхождения сборки:```bash gh attestation verify oci://ghcr.io/owasp/docksec:latest --repo OWASP/DockSec ``` Образ читает те же переменные `INPUT_*`, что и GitHub Action, поэтому здесь работает любой вход Action: `INPUT_IMAGE`, `INPUT_COMPOSE`, `INPUT_SEVERITY`, `INPUT_FAIL_ON`, `INPUT_FORMAT`, `INPUT_SARIF`, `INPUT_OUTPUT_DIR`. Записывайте отчёты куда-нибудь в примонтированный каталог, чтобы сохранить их после завершения контейнера:```bash docker run --rm -v "$PWD:/github/workspace" \ -e INPUT_COMPOSE=docker-compose.yml \ -e INPUT_SCAN_ONLY=true \ -e INPUT_FORMAT=json,html \ -e INPUT_OUTPUT_DIR=/github/workspace/docksec-reports \ ghcr.io/owasp/docksec:latest ``` ### 6. Или используйте GitHub Action```yaml - name: Run DockSec AI Scanner uses: OWASP/[email protected] with: dockerfile: 'Dockerfile' openai_api_key: ${{ secrets.OPENAI_API_KEY }} ``` ## Общие команды```bash # Scan Dockerfile + Docker image (AI + scanners) docksec Dockerfile -i myapp:latest # Scan a Docker Compose file and all its services docksec --compose docker-compose.yml # Scan only a Docker image docksec --image-only -i myapp:latest # Fast local scan, no AI, no API key docksec Dockerfile --scan-only # Choose which severity levels the image scan reports (default: CRITICAL,HIGH) docksec -i myapp:latest --image-only --severity CRITICAL,HIGH,MEDIUM # Fail the build (exit 1) if any finding is HIGH or above docksec -i myapp:latest --image-only --fail-on high # Write only the report formats you want, to a directory of your choice docksec Dockerfile --scan-only --format json,html --output-dir ./reports # Write a Markdown report for posting directly into a pull request comment docksec Dockerfile --scan-only --format markdown # Print results as JSON to stdout for scripts and CI pipelines docksec -i myapp:latest --image-only --json # Write a SARIF report for GitHub Code Scanning docksec Dockerfile --scan-only --sarif # Write a CycloneDX SBOM of an image for supply-chain tooling docksec --image-only -i myapp:latest --sbom # Fully offline scan: local Trivy DB, no network, no AI docksec --image-only -i myapp:latest --offline # Save today's findings as a baseline, then only gate on new findings later docksec -i myapp:latest --image-only --baseline .docksec-baseline.json --update-baseline docksec -i myapp:latest --image-only --baseline .docksec-baseline.json --fail-on high # Suppress triaged findings with an auditable ignore file docksec -i myapp:latest --image-only --ignore-file .docksec-ignore.yml # Force a fresh scan, bypassing the results cache docksec -i myapp:latest --image-only --no-cache # Install AI-assistant skill files (Claude Code, Cursor, Copilot, and more) docksec install-skill # Output control docksec Dockerfile --scan-only --quiet # warnings, errors, summary only docksec Dockerfile --scan-only --verbose # INFO-level diagnostics on stderr docksec Dockerfile --scan-only --verbose --log-file logs/docksec.log docksec Dockerfile --scan-only --compact-output # shorter per-finding output docksec Dockerfile --no-color # also honors NO_COLOR # Apply the mechanical Dockerfile fixes (keeps a .bak, re-scans, shows the delta) docksec Dockerfile --scan-only --fix --dry-run # print the diff, change nothing docksec Dockerfile --scan-only --fix # Rank findings by severity alone, with no EPSS lookup and no network call docksec Dockerfile --scan-only --no-epss # Treat a scan that could not complete as a failure, not a pass docksec Dockerfile --scan-only --fail-on high --incomplete-policy fail ``` --- ## Файл конфигурации Зафиксируйте `.docksec.yml` в корне вашего репозитория, и вся команда — и каждый CI-задание — будут сканировать по одной и той же политике, вместо того чтобы каждый разработчик передавал свои собственные флаги.```yaml # yaml-language-server: $schema=https://owasp.org/DockSec/docksec-config-schema.json severity: CRITICAL,HIGH fail_on: HIGH formats: [json, html] output_dir: ./security-reports rules: disabled: - compose-missing-healthcheck ``` Каждая настройка необязательна; всё, что вы пропустите, будет взято из переменной окружения, а затем из встроенного значения по умолчанию. Полный аннотированный пример находится в [`examples/.docksec.yml`](https://github.com/owasp/docksec/blob/main/examples/.docksec.yml). ### Приоритет Сначала наивысший приоритет:``` CLI flag > environment variable > .docksec.yml > built-in default ``` Таким образом, зафиксированное значение `severity: LOW` всё равно переопределяется флагом `--severity CRITICAL` в командной строке и переменной окружения `DOCKSEC_DEFAULT_SEVERITY`. ### Обнаружение DockSec ищет `.docksec.yml` (или `.docksec.yaml`) в рабочем каталоге, а затем поднимается вверх до корня репозитория, поэтому сервис в подкаталоге монорепозитория наследует политику, зафиксированную на верхнем уровне. Поиск останавливается на каталоге, содержащем `.git`, поэтому он никогда не подхватывает файл из-за пределов репозитория. - `--config FILE` использует конкретный файл вместо поиска. - `--no-config` игнорирует любой файл конфигурации для воспроизводимых запусков CI. Действующий файл конфигурации отображается в баннере сканирования, поэтому всегда ясно, какая политика была применена. ### Настройки | Настройка | Эквивалентный флаг | Примечания | | --- | --- | --- | | `severity` | `--severity` | Уровни серьёзности для сканирования образа | | `fail_on` | `--fail-on` | Порог для CI-гейта | | `formats` | `--format` | Форма списка: `[json, html]` | | `output_dir` | `--output-dir` | Назначение отчёта | | `provider` | `--provider` | `openai`, `anthropic`, `google`, `ollama` | | `model` | `--model` | Имя модели для провайдера | | `offline` | `--offline` | Без сети; пропускает AI и Docker Scout | | `skip_ai_scoring` | `--skip-ai-scoring` | Устарело и игнорируется; оценка всегда детерминирована | | `no_redact` | `--no-redact` | Не маскировать секреты перед вызовом AI | | `no_cache` | `--no-cache` | Обойти кэш сканирования | | `ignore_file` | `--ignore-file` | Путь к файлу исключений | | `baseline` | `--baseline` | Путь к файлу базовой линии | | `rules.disabled` | - | ID правил, которые нужно полностью отключить | Некорректный файл конфигурации — неизвестный ключ, неверный уровень серьёзности — это критическая ошибка, завершающаяся с кодом `2`, а не предупреждение, поэтому сломанный файл политики никогда не сможет привести к запуску сканирования по правилам, которые команда не фиксировала. ### Автодополнение в редакторе Комментарий `# yaml-language-server:` в первой строке обеспечивает автодополнение и встроенную валидацию в редакторах VS Code и JetBrains. Схема опубликована по адресу [`docs/docksec-config-schema.json`](https://github.com/owasp/docksec/blob/main/docs/docksec-config-schema.json) и может быть перегенерирована с помощью `docksec --print-config-schema`. ### Отключение правил `rules.disabled` полностью отключает проверку везде — она удаляется перед оценкой, отчётами, `--json` и гейтом `--fail-on`. Используйте это для проверок, которые не применимы к вашей среде. Для отдельных находок, которые ваша команда проанализировала и приняла, предпочтите [файл исключений](#ignoring-findings-waivers), записи которого содержат причину и дату истечения срока, что обеспечивает возможность аудита. --- ## Интеграция с CI/CD ### Коды выхода DockSec использует удобные для CI коды выхода, чтобы сборки и оболочки могли реагировать на результаты: | Код | Значение | |---|---| | `0` | Успех, нет находок на уровне `--fail-on` или выше | | `1` | Находки на уровне порога `--fail-on` или выше | | `2` | Ошибка использования или аргументов | | `3` | Ошибка инструмента или среды выполнения (сканирование не удалось, образ не найден, отсутствуют инструменты) | `--fail-on` учитывает каждую структурированную находку: уязвимости образа, ошибки конфигурации Dockerfile и ошибки конфигурации compose. Когда `--fail-on` ниже запрошенного `--severity`, серьёзность сканирования автоматически расширяется, чтобы гейт мог обнаружить эти находки. ### Незавершённые сканирования Если сканер не может запуститься, результаты могут содержать пропущенные находки, а не быть действительно чистыми. DockSec сообщает об этом как о пробеле в обнаружении в блоке Coverage и в `--json` в разделе `scan_info.completeness`. Используйте `--incomplete-policy fail`, чтобы завершиться с кодом `3` в этом случае, чтобы CI не мог пройти на сканировании, которое не завершилось:```bash docksec Dockerfile --incomplete-policy fail ``` ### Приоритет: что исправлять в первую очередь Каждая находка CVE оценивается по [EPSS](https://www.first.org/epss/), который оценивает вероятность её эксплуатации в течение следующих 30 дней. В сочетании с уровнем серьёзности это даёт четыре уровня: | Уровень | Значение | |---|---| | **Fix Now** | Критическая или высокая серьёзность, и входит в топ-10% CVE по вероятности эксплуатации | | **Fix Soon** | Критическая или высокая серьёзность, но эксплуатация менее распространена | | **Monitor** | Ниже серьёзность, но активно эксплуатируется | | **Low Priority** | Ниже серьёзность, эксплуатация редка | Это единственный сетевой вызов, который DockSec делает вне AI-прохода, и он намеренно узок: **отправляются только идентификаторы CVE** — никаких имён образов, содержимого файлов или путей. Оценки кэшируются на 24 часа. `--offline` и `--no-epss` отключают его, а любая ошибка приводит к ранжированию только по серьёзности, а не к сбою сканирования. ### Цепочки эксплуатации Представление по каждому сервису сообщает о находках по одной. DockSec также сообщает, где отдельные находки объединяются в единый путь атаки:```text Exploit chains [HIGH] 'web' is internet-facing and can reach 'db' with a committed credential services: web, db combines: compose-plaintext-secret-env, compose-no-network-segmentation 'web' accepts connections from outside the host and shares the default network with 'db'. 'db' is not exposed directly, but its credential is in the compose file, so compromising 'web' yields authenticated access to it. Neither service looks critical on its own. break it: Put 'db' on its own network that 'web' does not join, or move POSTGRES_PASSWORD to a Docker secret. ``` Обнаружение цепочек основано на правилах, поэтому оно работает с `--scan-only`, офлайн и без API-ключа, и возвращает один и тот же результат при каждом запуске. AI-проход ранжирует и расширяет его, а не является обязательным для него. Цепочки также отображаются в `--json` в разделе `exploit_chains`. См. [руководство по цепочкам эксплойтов](https://github.com/owasp/docksec/blob/main/docs/exploit-chains.md) для полного списка и [справочник по правилам compose](https://github.com/owasp/docksec/blob/main/docs/rules/README.md) для каждого правила, которое они объединяют. ### Команды исправления Сканирования завершаются конкретными командами, а не списком идентификаторов, и простым утверждением о том, сколько находок они устраняют:```text Fix commands > apt-get install --only-upgrade -y libgnutls30=3.7.9-2+deb12u7 CRITICAL - 3.7.9-2+deb12u4 -> 3.7.9-2+deb12u7 (CVE-2026-33845 +6) Dockerfile changes - [CRITICAL] Move the secret out of ENV; inject it at runtime (line 4) - [HIGH] Add a non-root USER before CMD/ENTRYPOINT (line 7) Applying all of the above resolves 37 of 93 finding(s); 56 have no mechanical fix yet. ``` ### Машиночитаемый вывод `--json` выводит в stdout один JSON-объект (информацию о сканировании, уязвимости, количество по уровням серьёзности и любые находки ИИ) вместо удобного для человека отчёта, поэтому его можно напрямую передавать в другие инструменты:```bash docksec -i myapp:latest --image-only --json | jq '.severity_counts' ``` При использовании только `--json` файлы отчётов не записываются; объедините его с `--format`, чтобы записывать файлы и выводить JSON в одном запуске. Все сообщения, предназначенные для чтения человеком, перемещаются в stderr в режиме `--json`, поэтому stdout всегда содержит только полезную нагрузку JSON. ### Форматы отчётов `--format` принимает список выходных файлов, разделённых запятыми: | Формат | Что вы получаете | |--------|----------------| | `json` | Файл `.json` с метаданными сканирования, количеством уязвимостей по уровням серьёзности и полным списком уязвимостей (та же структура, что и у полезной нагрузки stdout `--json`, но записанная на диск). | | `csv` | Таблица `.csv` с найденными проблемами (ID, уровень серьёзности, пакет, версия, заголовок и связанные поля). | | `pdf` | Печатная PDF-сводка с информацией о сканировании, оценками и сведениями об уязвимостях. | | `html` | Оформленный HTML-отчёт для просмотра результатов в браузере. | | `markdown` | Отчёт `.md`, который отображается нативно в комментариях к pull request и сводках заданий CI. Опционально: не записывается, если не запрошен. | `json`, `csv`, `pdf` и `html` записываются по умолчанию; добавьте `markdown` явно, чтобы получить его. **CSV при отсутствии находок:** если сканирование не выявляет уязвимостей, но `csv` указан в вашем списке `--format`, DockSec всё равно записывает CSV-файл, содержащий только заголовки столбцов. Это сделано намеренно (экспорт корректен, а не является неудачной записью), чтобы нижестоящие инструменты могли полагаться на стабильную схему даже при чистых сканированиях. О JSON в stdout и передаче в другие инструменты см. [Машиночитаемый вывод](#machine-readable-output) выше. Для CI и GitHub Code Scanning используйте `--sarif` (см. следующий раздел); SARIF отделён от `--format` и всегда создаётся, когда запрошен. ### Вывод SARIF для GitHub Code Scanning `--sarif` записывает отчёт SARIF 2.1.0 наряду с другими форматами отчётов. Загрузите его с помощью стандартного действия `github/codeql-action/upload-sarif`, чтобы видеть найденные проблемы с аннотациями непосредственно в pull request и на вкладке Security:```yaml - name: Run DockSec uses: OWASP/[email protected] with: dockerfile: 'Dockerfile' sarif: 'true' - name: Upload SARIF to GitHub Code Scanning uses: github/codeql-action/upload-sarif@v3 if: always() with: sarif_file: ~/.docksec/results ``` > `if: always()` важен: без него шаг загрузки пропускается всякий раз, когда > `--fail-on` приводит к ненулевому коду выхода DockSec, теряя результаты именно тогда, когда они > важнее всего. ### Режим базовой линии / храповика `--baseline FILE` позволяет включить `--fail-on` в существующем проекте без стены уже имеющихся находок, блокирующих каждую сборку. Запустите один раз с `--update-baseline`, чтобы зафиксировать текущие находки, затем закоммитьте файл базовой линии; с этого момента `--fail-on` будет проверять только находки, которых ещё нет в базовой линии:```bash # Snapshot current findings (does not gate) docksec -i myapp:latest --image-only --baseline .docksec-baseline.json --update-baseline # Later runs only fail on NEW findings above the threshold docksec -i myapp:latest --image-only --baseline .docksec-baseline.json --fail-on high ``` --- [Read more](https://github.com/owasp/docksec)