
🐍 🔍 GuardDog est un outil CLI pour identifier les paquets PyPI et npm malveillants.
GuardDog est un outil en ligne de commande qui identifie les paquets PyPI et npm malveillants, les modules Go, les crates Rust, les gems RubyGems, les actions GitHub ou les extensions VSCode. Il exécute une analyse statique sur le code source des paquets (via des règles YARA) et analyse les métadonnées des paquets pour détecter les attaques de la chaîne d'approvisionnement.
Ce qui rend GuardDog différent : au lieu de simplement lister des motifs suspects, GuardDog corrèle les résultats pour identifier les risques réels basés sur les chaînes d'attaque. Un paquet doit posséder à la fois la capacité d'effectuer une action (par exemple, l'accès réseau) et un indicateur de menace (par exemple, un domaine suspect) dans le même fichier pour être signalé comme à haut risque.
Il télécharge et analyse le code de :

GuardDog utilise un modèle de détection basé sur les risques qui corrèle les capacités du code avec les indicateurs de menace :
Les outils SAST traditionnels signalent chaque motif suspect indépendamment, ce qui entraîne une fatigue d'alerte. GuardDog comprend que :
Les paquets reçoivent un score de 0-10 basé sur quatre facteurs :
Étiquettes de score :
Étapes de la chaîne d'attaque (basées sur MITRE ATT&CK) :
Le moyen le plus simple d'exécuter GuardDog est d'utiliser uvx :
uvx guarddog pypi scan requests
Pour l'installer localement :
uv tool install guarddog
# ou
pip install guarddog
Ou utilisez l'image Docker :
docker pull ghcr.io/datadog/guarddog
alias guarddog='docker run --rm ghcr.io/datadog/guarddog'
Remarque : Sous Windows, la seule méthode d'installation prise en charge est Docker.
# Analyse la version la plus récente du paquet 'requests'
guarddog pypi scan requests
# Analyse une version spécifique du paquet 'requests'
guarddog pypi scan requests --version 2.28.1
# Analyse le paquet 'request' en utilisant 2 heuristiques spécifiques
guarddog pypi scan requests --rules exec-base64 --rules code-execution
# Analyse le paquet 'requests' en utilisant toutes les règles sauf une
guarddog pypi scan requests --exclude-rules exec-base64
# Analyse une archive locale de paquet
guarddog pypi scan /tmp/triage.tar.gz
# Analyse un répertoire local de paquet
guarddog pypi scan /tmp/triage/
# Analyse un paquet stocké dans S3 (un dossier/préfixe ou un objet archive unique)
guarddog pypi scan s3://my-bucket/path/to/package/
guarddog pypi scan s3://my-bucket/path/to/package.tar.gz
# Analyse chaque paquet référencé dans un fichier requirements.txt d'un dossier local
guarddog pypi verify workspace/guarddog/requirements.txt
# Analyse chaque paquet référencé dans un fichier requirements.txt et génère un fichier sarif - fonctionne uniquement pour verify
guarddog pypi verify --output-format=sarif workspace/guarddog/requirements.txt
# Sortie JSON sur la sortie standard - fonctionne pour chaque commande
guarddog pypi scan requests --output-format=json
# Toutes les commandes fonctionnent également sur npm, go, crates, rubygems
guarddog npm scan express
guarddog go scan github.com/DataDog/dd-trace-go
guarddog go verify /tmp/repo/go.mod
# Analyse les crates Rust
guarddog crates scan serde
guarddog crates verify /tmp/repo/Cargo.lock
# Analyse les paquets RubyGems
guarddog rubygems scan rails
guarddog rubygems verify /tmp/repo/Gemfile.lock
# Peut également prendre en charge l'analyse des actions GitHub implémentées en JavaScript
guarddog github_action scan DataDog/synthetics-ci-github-action
guarddog github_action verify /tmp/repo/.github/workflows/main.yml
# Analyse les extensions VSCode du marketplace
guarddog extension scan ms-python.python
# Analyse une version spécifique d'une extension VSCode
guarddog extension scan ms-python.python --version 2023.20.0
# Analyse un répertoire local d'extension VSCode ou une archive VSIX
guarddog extension scan /tmp/my-extension/
# Exécute en mode débogage
guarddog --log-level debug npm scan express
Lors de l'analyse de paquets, GuardDog exécute l'analyse du code source dans un sandbox au niveau du noyau (Linux via Landlock, macOS via Seatbelt, en utilisant nono). Le sandbox bloque tout accès réseau et restreint les opérations sur le système de fichiers aux seuls chemins nécessaires à l'analyse. Cela protège contre les paquets malveillants qui tentent d'exécuter du code pendant l'extraction de l'archive ou l'analyse.
Par défaut, le sandbox est obligatoire : s'il n'est pas disponible sur la plateforme, l'analyse échoue au lieu de s'exécuter sans protection. Pour analyser sans lui, vous devez explicitement passer --no-sandbox :
# Par défaut : exiger le sandbox, sortir avec une erreur s'il est indisponible
guarddog pypi scan requests
# Désactiver explicitement le sandbox
guarddog pypi scan requests --no-sandbox
Pour les paquets distants, trois phases s'exécutent avec différents niveaux de privilèges :
Le sandbox a été introduit pour atténuer les vulnérabilités de traversée de chemin et d'exécution de code lors de l'extraction d'archives (CVE-2022-23530, CVE-2022-23531, CVE-2026-22870, CVE-2026-22871).
GuardDog peut analyser un paquet stocké dans S3, soit en tant que dossier/préfixe, soit en tant qu'objet archive unique :
guarddog npm scan s3://my-bucket/path/to/package/
guarddog npm scan s3://my-bucket/path/to/package.tar.gz
Cela utilise vos identifiants AWS existants (variables d'environnement, ~/.aws, SSO ou un rôle IAM). GuardDog vérifie l'authentification via STS avant toute action et sort avec une erreur si aucun identifiant valide n'est trouvé. Les objets sont synchronisés vers un répertoire temporaire, analysés sous le sandbox comme tout autre contenu non fiable, puis supprimés du disque ensuite.
GuardDog utilise deux types de règles de détection, qui participent toutes deux au moteur de scoring basé sur les risques :
Pour la liste complète des règles par écosystème, voir RULES.md.
Pour des conseils sur la rédaction de nouvelles règles, voir WRITING_RULES.md.
Le moyen le plus simple d'intégrer GuardDog dans votre pipeline CI est d'utiliser le format de sortie SARIF et de le téléverser vers la fonctionnalité code scanning de GitHub.
Avec cela, vous obtenez :
Exemple d'action GitHub utilisant 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 ou poetry shell puis exécutez guarddogExécution de tous les tests unitaires : make test
Exécution des tests unitaires sur les heuristiques de métadonnées des paquets : make test-metadata-rules (les tests sont ici).
Vous pouvez exécuter GuardDog sur des paquets légitimes et malveillants pour déterminer les faux positifs et les faux négatifs. Voir ./tests/samples
Exécutez le vérificateur de types avec
mypy --install-types --non-interactive guarddog
et le linter avec
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
Le comportement de GuardDog peut être personnalisé à l'aide de variables d'environnement :
| Variable d'environnement | Description | Valeur par défaut |
|---|---|---|
GUARDDOG_NEW_DEPENDENCY_RISK_THRESHOLD | Score de risque minimum pour qu'une dépendance nouvellement introduite signale le paquet parent dans la règle risky_new_dependency | 5.0 |
GuardDog implémente plusieurs contrôles de sécurité lors de l'extraction des archives de paquets pour se protéger contre les bombes de compression et les attaques d'épuisement des descripteurs de fichiers :
Inspiration :
| Facteur | Pondération | Description |
|---|
| Sévérité | 30 % | Résultat le plus sévère (faible/moyen/élevé) |
| Chaîne d'attaque | 20 % | Présence d'étapes d'attaque complètes (précoce → intermédiaire/tardive) |
| Spécificité | 30 % | Degré de spécificité des motifs aux logiciels malveillants par rapport au code légitime |
| Sophistication | 20 % | Niveau d'avancement des techniques |
| Variable d'environnement | Description | Valeur par défaut |
|---|
GUARDDOG_PARALLELISM | Nombre de threads à utiliser pour le traitement parallèle | Nombre de CPU disponibles |
GUARDDOG_VERIFY_EXHAUSTIVE_DEPENDENCIES | Analyser toutes les versions possibles des dépendances (true/false) | false |
GUARDDOG_NPM_INCLUDE_DEV_DEPENDENCIES | Inclure les devDependencies lors de l'analyse des fichiers npm package.json (true/false) ; peut également être activé par invocation avec guarddog npm verify --include-dev-dependencies | false |
GUARDDOG_TOP_PACKAGES_CACHE_LOCATION | Emplacement du répertoire de cache des principaux paquets | guarddog/analyzer/metadata/resources |
GUARDDOG_YARA_EXT_EXCLUDE | Liste séparée par des virgules des extensions de fichiers à exclure de l'analyse 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 |
| Variable d'environnement | Description | Valeur par défaut |
|---|
GUARDDOG_MAX_UNCOMPRESSED_SIZE | Taille maximale autorisée non compressée en octets (évite l'épuisement de l'espace disque) | 2147483648 (2 Go) |
GUARDDOG_MAX_COMPRESSION_RATIO | Ratio de compression maximal autorisé (détecte les modèles de compression suspects) | 100 (100:1) |
GUARDDOG_MAX_FILE_COUNT | Nombre maximal de fichiers autorisés dans une archive (empêche l'épuisement des descripteurs de fichiers/inodes) | 100000 |