
🐍 🔍 GuardDog — это CLI-инструмент для выявления вредоносных пакетов PyPI и npm
GuardDog — это CLI-инструмент, который выявляет вредоносные пакеты PyPI и npm, модули Go, крейты Rust, гемы RubyGems, GitHub Actions и расширения VSCode. Он выполняет статический анализ исходного кода пакетов (с помощью YARA-правил) и анализирует метаданные пакетов для обнаружения атак на цепочку поставок.
Что делает GuardDog особенным: вместо простого перечисления подозрительных паттернов GuardDog сопоставляет находки, чтобы выявить реальные риски на основе цепочек атак. Пакет должен обладать как возможностью выполнить действие (например, доступ к сети), так и индикатором угрозы (например, подозрительный домен) в одном и том же файле, чтобы быть помеченным как высокорисковый.
Он загружает и сканирует код из:

GuardDog использует риск-ориентированную модель обнаружения, которая сопоставляет возможности кода с индикаторами угроз:
Традиционные SAST-инструменты помечают каждый подозрительный паттерн независимо, что приводит к усталости от ложных срабатываний. GuardDog понимает, что:
Пакеты получают балл от 0 до 10 на основе четырёх факторов:
Метки оценок:
Стадии цепочки атак (на основе MITRE ATT&CK):
Самый простой способ запустить GuardDog — использовать uvx:
uvx guarddog pypi scan requests
Для локальной установки:
uv tool install guarddog
# or
pip install guarddog
Или используйте Docker-образ:
docker pull ghcr.io/datadog/guarddog
alias guarddog='docker run --rm ghcr.io/datadog/guarddog'
Примечание: в Windows единственный поддерживаемый способ установки — Docker.
# Сканировать самую свежую версию пакета 'requests'
guarddog pypi scan requests
# Сканировать конкретную версию пакета 'requests'
guarddog pypi scan requests --version 2.28.1
# Сканировать пакет 'requests' с использованием 2 конкретных эвристик
guarddog pypi scan requests --rules exec-base64 --rules code-execution
# Сканировать пакет 'requests' со всеми правилами, кроме одного
guarddog pypi scan requests --exclude-rules exec-base64
# Сканировать локальный архив пакета
guarddog pypi scan /tmp/triage.tar.gz
# Сканировать локальную директорию пакета
guarddog pypi scan /tmp/triage/
# Сканировать пакет, хранящийся в S3 (папку/префикс или отдельный объект архива)
guarddog pypi scan s3://my-bucket/path/to/package/
guarddog pypi scan s3://my-bucket/path/to/package.tar.gz
# Сканировать каждый пакет, указанный в файле requirements.txt локальной папки
guarddog pypi verify workspace/guarddog/requirements.txt
# Сканировать каждый пакет из requirements.txt и вывести результат в sarif-файл — работает только для verify
guarddog pypi verify --output-format=sarif workspace/guarddog/requirements.txt
# Вывести JSON в стандартный поток вывода — работает для всех команд
guarddog pypi scan requests --output-format=json
# Все команды также работают для npm, go, crates, rubygems
guarddog npm scan express
guarddog go scan github.com/DataDog/dd-trace-go
guarddog go verify /tmp/repo/go.mod
# Сканировать крейты Rust
guarddog crates scan serde
guarddog crates verify /tmp/repo/Cargo.lock
# Сканировать пакеты RubyGems
guarddog rubygems scan rails
guarddog rubygems verify /tmp/repo/Gemfile.lock
# Дополнительно поддерживается сканирование GitHub Actions, реализованных на JavaScript
guarddog github_action scan DataDog/synthetics-ci-github-action
guarddog github_action verify /tmp/repo/.github/workflows/main.yml
# Сканировать расширения VSCode из маркетплейса
guarddog extension scan ms-python.python
# Сканировать конкретную версию расширения VSCode
guarddog extension scan ms-python.python --version 2023.20.0
# Сканировать локальную директорию расширения VSCode или VSIX-архив
guarddog extension scan /tmp/my-extension/
# Запуск в режиме отладки
guarddog --log-level debug npm scan express
При сканировании пакетов GuardDog выполняет анализ исходного кода внутри песочницы на уровне ядра (Linux через Landlock, macOS через Seatbelt, с использованием nono). Песочница блокирует весь сетевой доступ и ограничивает операции с файловой системой только теми путями, которые необходимы для анализа. Это защищает от вредоносных пакетов, пытающихся выполнить код во время извлечения архива или сканирования.
По умолчанию песочница обязательна: если она недоступна на платформе, сканирование завершается ошибкой, а не выполняется без защиты. Чтобы сканировать без неё, необходимо явно передать --no-sandbox:
# По умолчанию: требуется песочница, при её отсутствии выводится ошибка и выход
guarddog pypi scan requests
# Явное отключение песочницы
guarddog pypi scan requests --no-sandbox
Для удалённых пакетов три фазы выполняются с разными уровнями привилегий:
Песочница была введена для снижения риска уязвимостей path traversal и выполнения кода при извлечении архивов (CVE-2022-23530, CVE-2022-23531, CVE-2026-22870, CVE-2026-22871).
GuardDog может сканировать пакет, хранящийся в S3, либо как папку/префикс, либо как отдельный объект архива:
guarddog npm scan s3://my-bucket/path/to/package/
guarddog npm scan s3://my-bucket/path/to/package.tar.gz
При этом используются ваши существующие учётные данные AWS (переменные окружения, ~/.aws, SSO или IAM-роль). GuardDog проверяет аутентификацию через STS перед началом работы и завершается с ошибкой, если действительные учётные данные не найдены. Объекты синхронизируются во временную директорию, сканируются в песочнице, как и любой другой недоверенный контент, а затем удаляются с диска.
GuardDog использует два типа правил обнаружения, оба участвуют в риск-ориентированной системе оценки:
Полный список правил для каждой экосистемы см. в RULES.md.
Руководство по написанию новых правил см. в WRITING_RULES.md.
Самый простой способ интегрировать GuardDog в ваш CI-конвейер — использовать формат вывода SARIF и загружать его в функцию code scanning GitHub.
Благодаря этому вы получаете:
Пример GitHub Action с использованием GuardDog:
name: GuardDog
on:
push:
branches:
- main
pull_request:
branches:
- main
permissions:
contents: read
jobs:
guarddog:
permissions:
contents: read # for actions/checkout to fetch code
security-events: write # for github/codeql-action/upload-sarif to upload SARIF results
name: Scan dependencies
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v7
- run: uvx guarddog pypi verify requirements.txt --output-format sarif --exclude-rules repository_integrity_mismatch > guarddog.sarif
- name: Upload SARIF file to GitHub
uses: github/codeql-action/upload-sarif@v3
with:
category: guarddog-builtin
sarif_file: guarddog.sarif
python >=3.10: poetry env use 3.10.0poetry installpoetry run guarddog или poetry shell, а затем выполните guarddogЗапуск всех модульных тестов: make test
Запуск модульных тестов для эвристик по метаданным пакетов: make test-metadata-rules (тесты находятся здесь).
Вы можете запускать GuardDog на легитимных и вредоносных пакетах, чтобы определить ложные срабатывания и пропуски. См. ./tests/samples
Запустите проверку типов с помощью
mypy --install-types --non-interactive guarddog
и линтер с помощью
flake8 guarddog --count --select=E9,F63,F7,F82 --show-source --statistics --exclude tests/analyzer/sourcecode,tests/analyzer/metadata/resources,evaluator/data
flake8 guarddog --count --max-line-length=120 --statistics --exclude tests/analyzer/sourcecode,tests/analyzer/metadata/resources,evaluator/data --ignore=E203,W503
Поведение GuardDog можно настраивать с помощью переменных окружения:
| Переменная окружения | Описание | Значение по умолчанию |
|---|---|---|
GUARDDOG_NEW_DEPENDENCY_RISK_THRESHOLD | Минимальный балл риска для недавно добавленной зависимости, чтобы пометить родительский пакет в правиле risky_new_dependency | 5.0 |
GuardDog реализует несколько проверок безопасности при извлечении архивов пакетов для защиты от бомб сжатия и атак с исчерпанием файловых дескрипторов:
Вдохновение:
| Фактор | Вес | Описание |
|---|
| Серьёзность | 30% | Наиболее серьёзная находка (низкая/средняя/высокая) |
| Цепочка атак | 20% | Наличие полных стадий атаки (ранняя → средняя/поздняя) |
| Специфичность | 30% | Насколько паттерны специфичны для вредоносного ПО по сравнению с легитимным кодом |
| Сложность | 20% | Уровень продвинутости техники |
| Переменная окружения | Описание | Значение по умолчанию |
|---|
GUARDDOG_PARALLELISM | Количество потоков для параллельной обработки | Количество доступных CPU |
GUARDDOG_VERIFY_EXHAUSTIVE_DEPENDENCIES | Анализировать все возможные версии зависимостей (true/false) | false |
GUARDDOG_NPM_INCLUDE_DEV_DEPENDENCIES | Включать devDependencies при сканировании npm-файлов package.json (true/false); также можно переключать при каждом вызове с помощью guarddog npm verify --include-dev-dependencies | false |
GUARDDOG_TOP_PACKAGES_CACHE_LOCATION | Расположение директории кэша популярных пакетов | guarddog/analyzer/metadata/resources |
GUARDDOG_YARA_EXT_EXCLUDE | Разделённый запятыми список расширений файлов, исключаемых из YARA-сканирования | ini,md,rst,txt,lock,json,yaml,yml,toml,xml,html,csv,sql,pdf,doc,docx,ppt,pptx,xls,xlsx,odt,changelog,readme,makefile,dockerfile,pkg-info,d.ts |
| Переменная окружения | Описание | Значение по умолчанию |
|---|
GUARDDOG_MAX_UNCOMPRESSED_SIZE | Максимально допустимый несжатый размер в байтах (предотвращает исчерпание дискового пространства) | 2147483648 (2 ГБ) |
GUARDDOG_MAX_COMPRESSION_RATIO | Максимально допустимый коэффициент сжатия (обнаруживает подозрительные паттерны сжатия) | 100 (100:1) |
GUARDDOG_MAX_FILE_COUNT | Максимальное количество файлов, допустимое в архиве (предотвращает исчерпание файловых дескрипторов/inode) | 100000 |