
Détection en temps réel des menaces sur la chaîne d'approvisionnement npm/PyPI. Analyse des chaînes comportementales, analyse AST, flux IOC et moteur de notation composite.
MUAD
Installation | Utilisation | Fonctionnalités | VS Code | CI/CD
Les attaques supply-chain npm et PyPI explosent. Shai-Hulud a compromis 25K+ repos en 2025. Les outils existants détectent, mais n'aident pas à répondre.
MUAD'DIB combine 22 scanners paralleles (277 regles de detection), un moteur de desobfuscation, une analyse dataflow inter-module, du scoring compose (21 regles compound), et un sandbox gVisor/Docker pour detecter les menaces connues et les patterns comportementaux suspects dans les packages npm et PyPI. Un classifier XGBoost existe dans le code mais est actuellement inactif (modele effondre, en attente de re-entrainement — voir section ML Classifier ci-dessous).
MUAD'DIB est un scanner supply-chain npm et PyPI libre, ouvert et entièrement auditable. Il détecte les menaces connues (225 000+ IOCs), le RCE à l'installation, les flux credential-puis-exfiltration, les payloads obfusqués et d'autres patterns comportementaux suspects — en local, sans télémétrie.
Il est distribué sous licence AGPL-3.0 ; une licence commerciale est disponible pour les organisations qui doivent l'intégrer dans un produit propriétaire ou l'exécuter en service hébergé fermé (voir Licence).
Il ne cherche volontairement pas à tout couvrir — voir le Threat Model pour ce qu'il détecte et ce qu'il ne détecte pas.
npm install -g muaddib-scanner
git clone https://github.com/DNSZLSK/muad-dib
cd muad-dib
npm install
npm link
muaddib scan .
muaddib scan /chemin/vers/projet
Scanne les dépendances npm (package.json, node_modules) et Python (requirements.txt, setup.py, pyproject.toml).
muaddib
Lance un menu interactif pour vous guider à travers toutes les fonctionnalités.
muaddib install <package>
muaddib install lodash axios --save-dev
muaddib i express -g
muaddib install suspicious-pkg --force # Forcer l'installation malgré les menaces
Scanne les packages AVANT installation. Bloque les packages malveillants connus.
Chaque scan affiche un score de risque 0-100 :
[SCORE] 58/100 [***********---------] HIGH
muaddib scan . --explain
Affiche pour chaque détection :
muaddib scan . --json > results.json # JSON
muaddib scan . --html report.html # HTML
muaddib scan . --sarif results.sarif # SARIF (GitHub Security)
muaddib scan . --fail-on critical # Fail seulement sur CRITICAL
muaddib scan . --fail-on high # Fail sur HIGH et CRITICAL (défaut)
muaddib scan . --fail-on medium # Fail sur MEDIUM, HIGH, CRITICAL
muaddib scan . --paranoid
Détection ultra-stricte avec moins de tolérance. Utile pour les projets critiques. Détecte tout accès réseau, exécution de sous-processus, évaluation de code dynamique et accès aux fichiers sensibles.
muaddib scan . --webhook "https://discord.com/api/webhooks/..."
Envoie une alerte avec le score et les menaces sur Discord ou Slack. Filtrage strict (v2.1.2) : les alertes ne sont envoyées que pour les correspondances IOC, les menaces confirmées par sandbox, ou l'exfiltration de canary tokens — réduisant le bruit des détections heuristiques seules.
muaddib watch .
muaddib daemon
muaddib daemon --webhook "https://discord.com/api/webhooks/..."
Surveille automatiquement tous les npm install et scanne les nouveaux packages.
muaddib update
Charge les 225 000+ IOCs inclus dans le package, fusionne les IOCs YAML et les sources GitHub additionnelles (GenSecAI, DataDog). Lancez cette commande après npm install pour un rafraîchissement instantané des IOCs.
muaddib scrape
Rafraîchissement complet depuis toutes les sources primaires. Télécharge les dumps OSV pour npm et PyPI (~100-200 Mo), OSSF, et toutes les autres sources. Lancez cette commande quand vous voulez les données les plus récentes.
Sources :
muaddib sandbox <nom-package>
muaddib sandbox <nom-package> --strict
Analyse dynamique : installe le package dans un container Docker isolé et surveille le comportement à l'exécution via strace, tcpdump et diff filesystem.
Monitoring multi-couches :
NODE_OPTIONS=--require /opt/preload.js. Patche les APIs de temps (Date.now, setTimeout→0, setInterval→immédiat), intercepte les appels réseau/fichiers/processus/env. Mode multi-run à [0h, 72h, 7j] pour détecter les malwares time-bomb (MITRE T1497.003)Utilisez --strict pour bloquer tout trafic réseau sortant non essentiel via iptables.
Nécessite Docker Desktop installé.
muaddib sandbox lodash # Package safe
muaddib sandbox suspicious-pkg # Analyser un package inconnu
muaddib sandbox-report <nom-package>
muaddib sandbox-report <nom-package> --strict
Identique à sandbox mais affiche un rapport réseau détaillé : résolutions DNS, requêtes HTTP, connexions TLS, connexions bloquées (mode strict), et alertes d'exfiltration de données.
muaddib diff <ref> [path]
Compare les menaces entre la version actuelle et un commit/tag précédent. Affiche uniquement les NOUVELLES menaces introduites depuis la référence.
muaddib diff HEAD~1 # Comparer avec le commit précédent
muaddib diff v1.2.0 # Comparer avec un tag
muaddib diff main # Comparer avec une branche
muaddib diff abc1234 # Comparer avec un commit spécifique
Exemple de sortie :
[MUADDIB DIFF] Comparing abc1234 -> def5678
Risk Score: 25 -> 45 (+20 worse)
Threats: 3 -> 5
NEW threats: 2
REMOVED threats: 0
Unchanged: 3
NEW THREATS (introduced since v1.2.0)
------------------------------------
1. [HIGH] suspicious_dependency
Known malicious package detected
File: package.json
Utilisez en CI pour ne bloquer que sur les nouvelles menaces, pas la dette technique existante :
- run: muaddib diff ${{ github.event.pull_request.base.sha }} --fail-on high
muaddib init-hooks [options]
Scanner automatiquement avant chaque commit. Supporte plusieurs systèmes de hooks :
muaddib init-hooks # Auto-detect (husky/pre-commit/git)
muaddib init-hooks --type husky # Forcer husky
muaddib init-hooks --type pre-commit # Forcer pre-commit framework
muaddib init-hooks --type git # Forcer git hooks natifs
muaddib init-hooks --mode diff # Ne bloquer que les NOUVELLES menaces
Ajoutez à .pre-commit-config.yaml :
repos:
- repo: https://github.com/DNSZLSK/muad-dib
rev: v2.11.117
hooks:
- id: muaddib-scan # Scanner toutes les menaces
# - id: muaddib-diff # Ou: seulement les nouvelles
# - id: muaddib-paranoid # Ou: mode ultra-strict
npx husky add .husky/pre-commit "npx muaddib scan . --fail-on high"
# Ou pour le mode diff :
npx husky add .husky/pre-commit "npx muaddib diff HEAD --fail-on high"
muaddib remove-hooks [path]
Supprime tous les hooks MUAD'DIB (husky et git natif).
muaddib init-hooks --type git
# Crée .git/hooks/pre-commit
MUAD'DIB surveille en continu les registres npm et PyPI pour détecter les nouveaux packages en temps réel, en les scannant automatiquement avec analyse sandbox Docker et alertes webhook. Ce monitoring tourne en interne sur notre infrastructure — les menaces détectées alimentent la base IOC et l'API threat feed.
muaddib scan . --breakdown
Affiche la décomposition explicable du score : contribution de chaque finding au score final, avec les poids par règle et multiplicateurs de sévérité.
muaddib replay
muaddib ground-truth
Rejoue des attaques supply-chain réelles contre le scanner pour valider la couverture de détection. Résultat actuel (mesure v2.11.48) : 90/94 détectées (95.74% TPR@3) sur 96 samples enrichis (94 actifs, 2 hors-scope : GT-005 colors et GT-009 faker, protestware avec min_threats=0). Enrichissement 2026-05-25 : +22 samples (16 synthétiques pour les règles PYSRC/PYAST/AST-092/AICONF-004/PKG-022, 6 tarballs réels depuis l'archive VPS, 7 reconstructions depuis le benchmark data/all-review-results.json). 13 samples PyPI (était 0). TPR@20 : 88.30% (83/94, +3.1pp vs v2.11.47 grâce au compound Track D recon_exfil_direct_ip qui ferme la gap GT-095).
4 misses incluent les 3 attaques browser-only (lottie-player, polyfill-io, trojanized-jquery) plus 1 autre.
MUAD'DIB vérifie automatiquement les nouvelles versions au démarrage et vous notifie si une mise à jour est disponible.
MUAD'DIB détecte et scanne automatiquement les projets Python :
-r récursif, extras, marqueurs d'environnementinstall_requires et setup_requiresLes packages Python sont vérifiés contre 14 000+ packages PyPI malveillants connus (depuis OSV.dev) et testés pour le typosquatting contre les packages PyPI populaires (requests, numpy, flask, django, pandas, etc.) via la normalisation PEP 503.
[PYTHON] Detected Python project (3 dependency files)
requirements.txt: 12 packages
setup.py: 3 packages
pyproject.toml: 8 packages
[CRITICAL] PyPI IOC match: malicious-pkg (all versions)
[HIGH] PyPI typosquat: "reqeusts" looks like "requests"
MUAD'DIB détecte les packages dont le nom ressemble à un package populaire (npm et PyPI) :
[HIGH] Package "lodahs" ressemble à "lodash" (swapped_chars). Possible typosquatting.
Détecte quand du code lit des credentials ET les envoie sur le réseau :
[CRITICAL] Flux suspect: lecture credentials (readFileSync, GITHUB_TOKEN) + envoi réseau (fetch)
Détecte les patterns malveillants dans les fichiers YAML .github/workflows/, incluant les indicateurs de backdoor Shai-Hulud 2.0.
| Campagne | Packages | Status |
|---|---|---|
| GlassWorm (Mars 2026) | 433+ packages (Unicode invisible + Blockchain C2) | Détecté |
| Shai-Hulud v1 (Sept 2025) | @ctrl/tinycolor, ng2-file-upload | Détecté |
| Shai-Hulud v2 (Nov 2025) | @asyncapi/specs, posthog-node, kill-port | Détecté |
| Shai-Hulud v3 (Dec 2025) | @vietmoney/react-big-calendar | Détecté |
| event-stream (2018) | flatmap-stream, event-stream | Détecté |
| eslint-scope (2018) | eslint-scope | Détecté |
| Protestware | node-ipc, colors, faker | Détecté |
| Typosquats | crossenv, mongose, babelcli | Détecté |
| Technique | MITRE | Détection |
|---|---|---|
| Vol credentials (.npmrc, .ssh) | T1552.001 | AST |
| Exfiltration env vars | T1552.001 | AST |
| Exécution code distant | T1105 | Pattern |
| Reverse shell | T1059.004 | Pattern |
| Dead man's switch | T1485 | Pattern |
| Code obfusqué | T1027 | Heuristiques |
| Analyse entropie Shannon | T1027 | Calcul d'entropie |
| Typosquatting (npm + PyPI) | T1195.002 | Levenshtein |
| Supply chain compromise | T1195.002 | IOC matching |
| Package PyPI malveillant | T1195.002 | IOC matching |
| Sandbox analyse dynamique | Multiple | Docker + strace + tcpdump |
| Ajout soudain de script lifecycle | T1195.002 | Analyse temporelle |
| Injection d'API dangereuse entre versions | T1195.002 | Diff AST temporel |
| Anomalie de fréquence de publication | T1195.002 | Métadonnées registre |
| Changement de maintainer/publisher | T1195.002 | Métadonnées registre |
| Exfiltration de canary tokens | T1552.001 | Honey tokens sandbox |
| Weaponisation agent IA | T1059.004 | AST (flags s1ngularity/Nx) |
| Injection prompt config IA | T1059.004 | Scan fichiers (.cursorrules, CLAUDE.md) |
| Vol credentials CLI (gh, gcloud, aws) | T1552.001 | AST |
| Dropper binaire (chmod + exec /tmp) | T1105 | AST |
| Hooking prototype (fetch, XMLHttpRequest) | T1557 | AST |
| Injection workflow (.github/workflows) | T1195.002 | AST |
| Harvest crypto wallets | T1005 | Dataflow |
| Require cache poisoning | T1574.001 | AST |
| Staged eval decode (eval+atob/Buffer) | T1140 | AST |
| Désobfuscation (string concat, charcode, base64, hex) |
MUAD'DIB 2.0 introduit un changement de paradigme : de la détection par IOC (réactive, nécessite des menaces connues) à la détection comportementale d'anomalies (proactive, détecte les menaces inconnues en repérant les changements suspects).
Les scanners supply-chain traditionnels reposent sur des listes de packages malveillants connus. Le problème : ils ne détectent les menaces qu'APRÈS leur identification et signalement. Des attaques comme ua-parser-js (2021), event-stream (2018) et Shai-Hulud (2025) sont passées inaperçues pendant des heures ou des jours car aucun IOC n'existait encore.
MUAD'DIB 2.0 ajoute 5 features de détection comportementale capables d'attraper ces attaques avant leur apparition dans une base d'IOC, en analysant ce qui a changé entre les versions d'un package.
--temporal)Détecte quand des scripts preinstall, install ou postinstall apparaissent soudainement dans une nouvelle version d'un package qui n'en avait jamais. C'est le vecteur d'attaque #1 des attaques supply-chain.
muaddib scan . --temporal
--temporal-ast)Télécharge les deux dernières versions de chaque dépendance et compare leur AST (Abstract Syntax Tree) pour détecter les APIs dangereuses nouvellement ajoutées : child_process, eval, Function, net.connect, process.env, fetch, etc.
muaddib scan . --temporal-ast
--temporal-publish)Détecte les patterns de publication anormaux : rafale de versions en 24h, package dormant soudainement mis à jour après 6+ mois, succession rapide de versions (plusieurs releases en moins d'1h).
muaddib scan . --temporal-publish
--temporal-maintainer)Détecte les changements de maintainers entre versions : nouveau maintainer ajouté, seul maintainer remplacé (pattern event-stream), noms de maintainers suspects, nouveau publisher.
muaddib scan . --temporal-maintainer
Injecte de faux credentials dans l'environnement sandbox avant d'installer un package. Si le package tente d'exfiltrer ces honey tokens via HTTP, DNS, filesystem ou stdout, il est signalé comme malveillant confirmé.
6 honeypots sont injectés :
GITHUB_TOKEN / NPM_TOKEN — Tokens de registreAWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY — Credentials cloudSLACK_WEBHOOK_URL / DISCORD_WEBHOOK_URL — Webhooks de messagerieLes tokens dynamiques (aléatoires par session, depuis canary-tokens.js) et les tokens statiques de fallback (dans sandbox-runner.sh) sont utilisés pour une défense en profondeur.
muaddib sandbox suspicious-package
Activer toutes les features d'analyse temporelle en une commande :
muaddib scan . --temporal-full
# Scan comportemental complet (5 features)
muaddib scan . --temporal-full
# Détection lifecycle scripts uniquement
muaddib scan . --temporal
# Diff AST + changement maintainer
muaddib scan . --temporal-ast --temporal-maintainer
# Sandbox avec canary tokens (activé par défaut)
muaddib sandbox suspicious-package
# Sandbox sans canary tokens
muaddib sandbox suspicious-package --no-canary
| Rule ID | Nom | Sévérité | Feature |
|---|---|---|---|
| MUADDIB-TEMPORAL-001 | Ajout soudain de script lifecycle (Critique) | CRITICAL | --temporal |
| MUADDIB-TEMPORAL-002 | Ajout soudain de script lifecycle | HIGH | --temporal |
| MUADDIB-TEMPORAL-003 | Script lifecycle modifié | MEDIUM | --temporal |
| MUADDIB-TEMPORAL-AST-001 | API dangereuse ajoutée (Critique) | CRITICAL | --temporal-ast |
| MUADDIB-TEMPORAL-AST-002 | API dangereuse ajoutée (High) | HIGH | --temporal-ast |
| MUADDIB-TEMPORAL-AST-003 | API dangereuse ajoutée (Medium) | MEDIUM | --temporal-ast |
| MUADDIB-PUBLISH-001 | Rafale de publications détectée | HIGH | --temporal-publish |
| MUADDIB-PUBLISH-002 | Pic de package dormant | HIGH | --temporal-publish |
| MUADDIB-PUBLISH-003 | Succession rapide de versions | MEDIUM | --temporal-publish |
| MUADDIB-MAINTAINER-001 | Nouveau maintainer ajouté | HIGH | --temporal-maintainer |
| MUADDIB-MAINTAINER-002 | Maintainer suspect détecté | CRITICAL | --temporal-maintainer |
| MUADDIB-MAINTAINER-003 | Seul maintainer changé | HIGH | --temporal-maintainer |
| MUADDIB-MAINTAINER-004 | Nouveau publisher détecté | MEDIUM | --temporal-maintainer |
| MUADDIB-CANARY-001 | Exfiltration de canary token | CRITICAL | sandbox |
Ces features détectent des attaques comme :
postinstall + child_process)flatmap-stream avec eval)Le tout sans avoir besoin d'un seul IOC.
MUAD'DIB agrège la threat intelligence de sources vérifiées uniquement :
| Source | Type | Couverture |
|---|---|---|
| OSV.dev npm dump | Bulk zip | 200 000+ entrées npm MAL-* |
| OSV.dev PyPI dump | Bulk zip | 14 000+ entrées PyPI MAL-* |
| GenSecAI Shai-Hulud Detector | GitHub | 700+ packages Shai-Hulud |
| DataDog Security Labs | GitHub | IOCs consolidés de 7 vendors |
| OSSF Malicious Packages | API OSV | 8000+ rapports malware |
| Snyk Known Malware | Statique | Attaques historiques |
| Socket.dev / Phylum | Statique | Ajouts manuels |
L'extension VS Code scanne automatiquement vos projets npm.
Cherchez "MUAD'DIB" dans les Extensions VS Code, ou :
code --install-extension dnszlsk.muaddib-vscode
MUAD'DIB: Scan Project - Scanner tout le projetMUAD'DIB: Scan Current File - Scanner le fichier actuelmuaddib.autoScan - Scanner automatiquement à l'ouverture (défaut: true)muaddib.webhookUrl - URL webhook Discord/Slackmuaddib.failLevel - Niveau d'alerte (critical/high/medium/low)Utilisez l'action officielle MUAD'DIB depuis le GitHub Marketplace :
name: Security Scan
on: [push, pull_request]
jobs:
scan:
runs-on: ubuntu-latest
permissions:
security-events: write
contents: read
steps:
- uses: actions/checkout@v4
- uses: DNSZLSK/muad-dib@v1
with:
path: '.'
fail-on: 'high'
sarif: 'results.sarif'
| Input | Description | Défaut |
|---|---|---|
path | Chemin à scanner | . |
fail-on | Sévérité minimum pour échec (critical/high/medium/low) | high |
sarif | Chemin du fichier SARIF | `` |
paranoid | Activer détection ultra-stricte | false |
| Output | Description |
|---|---|
sarif-file | Chemin du fichier SARIF généré |
risk-score | Score de risque (0-100) |
threats-count | Nombre de menaces détectées |
exit-code | Code de sortie (0 = clean) |
Les alertes apparaissent dans Security > Code scanning alerts.
MUAD'DIB 2.11.179 Scanner
|
+-- IOC Match (225 000+ packages, JSON DB)
| +-- OSV.dev npm dump (200K+ entrées MAL-*)
| +-- OSV.dev PyPI dump (14K+ entrées MAL-*)
| +-- GenSecAI Shai-Hulud Detector
| +-- DataDog Consolidated IOCs
| +-- OSSF Malicious Packages (via OSV)
| +-- Snyk Known Malware
| +-- Static IOCs (Socket, Phylum)
|
+-- Pré-traitement Désobfuscation (v2.2.5, --no-deobfuscate pour désactiver)
| +-- String concat folding, reconstruction CharCode
| +-- Décodage Base64, résolution Hex array
| +-- Propagation de constantes (Phase 2)
|
+-- Dataflow Inter-module (v2.2.6, --no-module-graph pour désactiver)
| +-- Graphe de dépendances, annotation exports teintés
| +-- Chaînes re-export 3 hops, analyse méthodes de classe
| +-- Détection credential read → network sink cross-fichiers
|
+-- Graphe d'Intention (Intent Graph)
| +-- Analyse cross-scanner des intentions malveillantes
| +-- Corrélation entre signaux faibles de multiples scanners
| +-- Élévation de sévérité sur combinaisons suspectes
|
+-- 22 Scanners Parallèles (277 règles)
| +-- AST Parse (acorn) — eval/Function, credential CLI theft, binary droppers, prototype hooks
| +-- Pattern Matching (shell, scripts)
| +-- Typosquat Detection (npm + PyPI, Levenshtein)
| +-- Python Scanner (requirements.txt, setup.py, pyproject.toml)
| +-- Analyse Entropie Shannon
| +-- GitHub Actions Scanner
| +-- AI Config Scanner (.cursorrules, CLAUDE.md, copilot-instructions.md)
| +-- Package, Dependencies, Hash, Dataflow scanners
| +-- IOC Strings (YARA-style, intel-triage v2.11) — Axios 2026, TeamPCP, GlassWorm, CanisterSprawl
| +-- Anti-Forensic AST (intel-triage v2.11) — XOR loop + self-delete + decoy write (csec autodelete)
| +-- Stub Package (intel-triage v2.11) — main file < 500 octets + dep URL externe + lifecycle hook (ltidi chain)
|
+-- Détection d'Anomalies Supply Chain (v2.0)
| +-- Détection Lifecycle Script Temporelle (--temporal)
| +-- Diff AST Temporel (--temporal-ast)
| +-- Anomalie Fréquence de Publication (--temporal-publish)
| +-- Détection Changement Maintainer (--temporal-maintainer)
| +-- Canary Tokens / Honey Tokens (sandbox)
|
+-- Validation & Observabilité (v2.1)
| +-- Ground Truth Dataset (96 attaques réelles, 94 in-scope, 95.74% TPR@3 v2.11.48)
| +-- Logging Temps de Détection (first_seen, métriques lead time)
| +-- Suivi Taux FP (stats quotidiennes, taux faux positifs)
| +-- Décomposition Score (scoring explicable par règle)
| +-- API Threat Feed (serveur HTTP, flux JSON pour SIEM)
|
+-- Réduction FP Post-traitement (v2.2.8-v2.3.1, v2.5.7-v2.5.8, v2.5.15-v2.5.16)
| +-- Downgrade sévérité par comptage (dynamic_require, dataflow, module_compile, etc.)
| +-- Cap scoring prototype_hook MEDIUM + whitelist HTTP client
| +-- Obfuscation dans dist/build/.cjs/.mjs → LOW
| +-- Filtrage env vars safe + préfixes
| +-- Catégorisation source télémétrie dataflow (os.platform/arch → telemetry_read)
| +-- Whitelist DEP (es5-ext, bootstrap-sass) + skip alias npm
| +-- Audit IOC wildcards (v2.5.8) : FPR 10.8% → 6.0%
| +-- P5 precision heuristique (v2.5.15) : 7 corrections
| +-- P6 precision composes (v2.5.16) : 6 corrections
|
+-- Scoring Per-File Max (v2.2.11)
| +-- Score = max(scores_par_fichier) + score_package_level
| +-- Élimine l'accumulation de score sur de nombreux fichiers
| +-- Menaces package-level (lifecycle, typosquat, IOC) scorées séparément
|
+-- Sandbox Monkey-Patching Preload (v2.4.9)
| +-- Manipulation temps runtime (Date.now, setTimeout→0, setInterval→immédiat)
| +-- Interception réseau/fichiers/processus/env et logging
| +-- Multi-run [0h, 72h, 7j] pour détection time-bomb (T1497.003)
|
+-- Audit Sécurité (v2.5.0-v2.5.6)
| +-- 41 issues remédiées (14 CRITICAL, 18 HIGH, 9 MEDIUM)
|
+-- ML Classifier (v2.10.0-v2.10.5) — INACTIF depuis 2026-04-08
| +-- Jamais appele par `muaddib scan` (rules + FP caps uniquement)
| +-- `muaddib monitor` : LOG-ONLY (modele collapse, p≈0.002 pour tout input)
| +-- `muaddib evaluate` : seule commande qui execute encore le filtre (replay offline)
| +-- Historique: ML1 XGBoost (P=0.978/R=0.933) + ML2 Bundler (P=0.992/R=1.000)
|
+-- Webhook Triage P1/P2/P3 (v2.10.5)
| +-- P1 rouge : IOC, HC types, sandbox, canary tokens
| +-- P2 orange : score >= 50, compounds, lifecycle+intent
| +-- P3 jaune : reste (score 20-49 sans signal fort)
|
+-- Paranoid Mode (ultra-strict)
+-- Docker Sandbox (analyse comportementale, capture réseau, canary tokens, CI-aware, preload)
+-- Moniteur Zero-Day (interne : polling RSS npm + PyPI, alertes Discord, rapport quotidien)
|
v
Dataflow Analysis (credential read -> network send)
|
v
Threat Enrichment (rules, MITRE ATT&CK, playbooks)
|
v
Output (CLI, JSON, HTML, SARIF, Webhook, Threat Feed)
| Metrique | Resultat | Details |
|---|---|---|
| Wild TPR (Datadog 17K) | 92.8% (13 538/14 587 in-scope) | 17 922 packages. 3 335 sans JS (hors scope). Par categorie : compromised_lib 97.8%, malicious_intent 92.1% |
| TPR@3 (Ground Truth, mesure v2.11.48) | 95.74% (90/94 in-scope) | Re-mesure complete sur le GT enrichi. 96 attaques reelles (94 in-scope + 2 hors-scope : GT-005 colors, GT-009 faker, protestware min_threats=0). +22 samples 2026-05-25 (Track C synthetique PYSRC/PYAST/AST-092/AICONF-004/PKG-022, Track A 6 tarballs reels VPS, Track B 7 reconstructions du benchmark de revue). 13 samples PyPI (etait 0). |
| TPR@20 (Ground Truth, mesure v2.11.48) | 88.30% (83/94 in-scope) | Seuil alerte = 20 (threshold operationnel). +3.1pp vs v2.11.47 grace au compound Track D recon_exfil_direct_ip (MUADDIB-COMPOUND-016, sameFile) qui ferme la gap GT-095 (risk 3→50) et linux_fingerprint_exec (AST-093) qui boost GT-091 byvendors / GT-092 heloo131313. 2 samples tpr3-only restants par design (GT-072, GT-077). |
| FPR rules (Benign curated, mesure v2.11.48) | 1.10% (6/545 scannes, 548 total) | Inchange apres Track D — le compound + types nouveaux ont cree zero FP supplementaire (gate sameFile + filtre IP-publique-only). Chute depuis 15.6% (v2.10.95) attribuable aux FP caps F1-F14 (v2.10.97 → v2.11.31) compounded sur 11 versions. Les 6 FP restants sont reels (meteor, prisma, @prisma/client, drizzle-orm, scrypt, liquid). C'est le chiffre operationnel — ce qu'un operateur obtient via muaddib scan (rules + FP caps, sans ML). |
| FPR (Benign random, mesure v2.11.48) | 2.50% (5/200) | 200 packages npm aleatoires, echantillonnage stratifie. Baisse depuis 7.0% (v2.10.95). |
| FPR PyPI (mesure v2.11.48, premiere mesure honnete) | 9.68% (12/124 scannes, 132 total) | Track D a fixe le downloader PyPI — retrait du flag pip --no-binary :all: (forcait la compilation des packages wheel-only, timeout 38% des fois) + support .whl via extractArchive(). 42 packages massifs (numpy/pandas/django/matplotlib/scikit-learn/...) maintenant scannes. Les 12 FP sont TOUS au score 25-35 = signature du bug cap-PyPI-35 (Track E target), pas de nouveaux mis-fires. 8 fails residuels sur les geants >500MB (torch, tensorflow, scipy, opencv-python, ansible, playwright). |
Benchmark Datadog 17K (v2.10.21) — DataDog Malicious Software Packages Dataset, 17 922 packages malveillants npm. Wild TPR : 92.8% (13 538/14 587 in-scope). 3 335 packages sans fichiers JS exclus comme hors scope. Erreurs : 0.
| Metrique | Valeur |
|---|---|
| Total packages | 17 922 |
| Hors scope (pas de JS) | 3 335 |
| In-scope | 14 587 |
| Detectes | 13 538 |
| Misses (score=0, in-scope) | 1 049 |
Par categorie :
Voir Evaluation Methodology.
FPR par taille de package — Le FPR correle lineairement avec la taille du package. Le scoring per-file max (v2.2.11) reduit significativement les FP sur les packages moyens/gros :
| Categorie | Packages | FP | FPR |
|---|---|---|---|
| Petits (<10 fichiers JS) | 290 | 18 | 6.2% |
| Moyens (10-50 fichiers JS) | 135 | 16 | 11.9% |
| Gros (50-100 fichiers JS) | 40 | 10 | 25.0% |
| Tres gros (100+ fichiers JS) | 62 | 25 | 40.3% |
Progression FPR : 0% (invalide, dirs vides, v2.2.0-v2.2.6) → 38% (premiere vraie mesure, v2.2.7) → 19.4% (v2.2.8) → 17.5% (v2.2.9) → ~13% (v2.2.11, scoring per-file max) → 8.9% (v2.3.0, P2) → 7.4% (v2.3.1, P3) → 6.0% (v2.5.8, P4 + audit IOC wildcards) → ~13.6% (v2.5.14, hardening audit) → 12.3% (v2.5.16, P5+P6, 65/532) → 12.3% (v2.6.1, module-graph bounded path) → 12.1% (v2.6.2, P7) → 12.9% (v2.9.4, compound scoring + nouveaux detecteurs) → 10.8% (v2.10.1, audit v3 FP reduction, 57/529) → 11.0% (v2.10.5, ML + compounds, 58/529) → 10.6% (v2.10.21, dataflow graduation + SDK heuristic, 56/529) → 14.0% (v2.10.57, reconstruction corpus benin curate, 74/532) → estimee 6-9% (v2.10.74, fixes FP cluster P1-P4 basees sur audit forensique de 53 953 alertes) → 15.6% mesure (v2.10.95, 85/545 sur corpus reconstruit — la projection 6-9% ne s'est pas materialisee) → post-filtre F1-F14 contextuel (v2.10.97 → v2.11.31, dont F14 HARD/SOFT exfil split pour les 41/46 packages encore >=90 apres F1-F13) → 1.10% mesure (v2.11.47, 6/545 sur le corpus 548 packages — l'effet cumule de F1-F14 sur 11 versions a fait chuter le FPR de 15.6% a 1.10%. Filtre ML T1 en replay offline : 0.92% (5/545) — mais le ML est inactif en production depuis 2026-04-08, donc seul le 1.10% reflete ce qu'un operateur obtient. Les 6 FP restants sont meteor, prisma, @prisma/client, drizzle-orm, scrypt, liquid — tous des hits reels sur patterns legitimes, pas des artefacts de whitelist. Canonical : metrics/v2.11.47.json).
Note sur l'evolution du FPR : Le FPR historique de 6.0% (v2.5.8) reposait sur un
BENIGN_PACKAGE_WHITELISTqui excluait certains packages connus du scoring — un biais de data leakage supprime en v2.5.10. Le FPR canonical actuel est 1.10% (6/545 scannes de 548, mesure v2.11.47), une mesure honnete sans whitelisting. Contrairement au 6.0% de v2.5.8, le 1.10% vient d'une vraie reduction FP via les caps contextuels F1-F14 — pas de packages caches.
Progression holdout (scores pre-tuning, regles gelees) :
| Holdout | Score | Focus |
|---|---|---|
| v1 | 30% (3/10) | Patterns generaux |
| v2 | 40% (4/10) | Env charcode, lifecycle, prototype |
| v3 | 60% (6/10) | Require cache, DNS TXT, reverse shell |
| v4 | 80% (8/10) | Efficacite desobfuscation |
| v5 | 50% (5/10) | Dataflow inter-module (nouveau scanner) |
Datasets : 14 587 samples Datadog in-scope, 548 npm curated + 200 npm random + 132 PyPI packages benins, 107 samples adversariaux/holdout, 96 attaques ground-truth (94 in-scope + 2 hors-scope : GT-005 colors, GT-009 faker, protestware min_threats=0; 13 samples PyPI added 2026-05-25). 4545 tests, 152 fichiers.
Voir Evaluation Methodology pour le protocole experimental complet.
Le TPR ground-truth ci-dessus est mesure hors-ligne. Depuis v2.11.67, le moniteur suit aussi la couverture operationnelle sur l'ingestion npm/PyPI en direct :
data/scan-ledger.jsonl) enregistre l'issue de chaque package scanne ; computeLedgerRollup() produit un rollup 24h (alertRate, par ecosysteme). Note : alertRate est un signal de debit, pas un TPR de detection.data/ghsa-malware.jsonl), plus une alarme feed-health qui se declenche quand un feed IOC s'eteint silencieusement.scripts/coverage-audit.js, quotidien 05:00 UTC) joint ce denominateur aux issues du ledger + l'archive tarball pour calculer un TPR operationnel honnete denomine-GHSA (alerted / total), et remonte les miss scannedClean comme candidats ground-truth valides a la main.Ce TPR operationnel est le vrai taux de detection en production, distinct du TPR GT statique (non re-mesure depuis v2.11.48).
Statut (2026-04-08 → present) : Le classifier XGBoost (
src/ml/classifier.js) n'est pas cable dansmuaddib scandu tout, et dansmuaddib monitoril tourne en mode LOG-ONLY depuis 2026-04-08 — le modele entraine a collapse (predit p≈0.002 pour tout input, y compris des patterns clairement malveillants lifecycle+exec+staged_payload) et a ete desactive en attendant un re-entrainement sur des donnees JSONL balancees. Les metriques ci-dessous viennent du replaymuaddib evaluatesur un bench fige. Elles decrivent ce que le modele apporterait s'il fonctionnait, pas ce qu'un operateur obtient aujourd'hui.
Metrique (replay evaluate offline) | Resultat | Details |
|---|---|---|
| ML FPR | 2.85% (239/8 393 holdout) | XGBoost retraine sur 56 564 samples, 64 features, threshold=0.710 |
| ML TPR | 99.93% (2 918/2 920 holdout) | 377 confirmed_malicious via correlation OSSF/GHSA/npm |
| FPR after ML T1 (replay offline, v2.11.48) | 1.10% (6/545 scannes) | Le classifier ne retire aucun des 6 FP raw dans ce run (1 etait filtre en v2.11.47). Pas applique pendant un scan reel — muaddib scan n'invoque jamais le classifier. |
Methodologie de retrain (v2.10.51) :
- Ground truth : 377 confirmed_malicious via auto-labeler (OSSF malicious-packages, GitHub Advisory Database, correlation takedown npm registry)
- Dataset : 56 564 samples (14 602 malveillants, 41 962 propres). Split stratifie 80/20
- Grid search : depth=4, estimators=300, lr=0.05. AUC-ROC=0.999, F1=0.960
- Filtre features leaky : 23 features mortes/leaky retirees (proxies d'identite de source)
Le modele shadow continue de logger des predictions dans
muaddib monitorpour la validation de retraining. Quand le prochain modele passe la validation shadow, le guard LOG-ONLY danssrc/monitor/queue.js:660sera retire et les metriques ci-dessus reviendront dans le tableau operationnel.
Editez les fichiers YAML dans iocs/ :
- id: NEW-MALWARE-001
name: "malicious-package"
version: "*"
severity: critical
confidence: high
source: community
description: "Description de la menace"
references:
- https://example.com/article
mitre: T1195.002
git clone https://github.com/DNSZLSK/muad-dib
cd muad-dib
npm install
npm test
eslint-plugin-security avec 14 regles activeesMUAD'DIB est distribue sous licence GNU Affero General Public License v3.0 only (AGPL-3.0-only) — voir LICENSE et NOTICE.
Vous etes libre de l'utiliser, l'etudier, le modifier et le redistribuer — y compris via un reseau — a condition que les travaux derives et les versions deployees en service soient publies sous la meme licence.
Licence commerciale : pour integrer MUAD'DIB dans un produit proprietaire / ferme, ou le proposer en service heberge sans les obligations de divulgation du code de l'AGPL, une licence commerciale separee est disponible. Ouvrez une issue ou contactez l'auteur (DNSZLSK).
Copyright (C) 2026 DNSZLSK.
The spice must flow. The worms must die.
| T1140 |
| Pré-traitement AST |
| Dataflow cross-fichiers (exfiltration inter-module) | T1041 | Module graph |
| ADR (Adversarial + Holdout, v2.11.48) | 96.26% (103/107) | 67 adversariaux + 40 holdouts (107 disponibles), seuil global=20. Stable vs v2.10.95. |