muaddib-scanner 2.3.1 → 2.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -21,7 +21,7 @@
21
21
  </p>
22
22
 
23
23
  <p align="center">
24
- <a href="README.fr.md">Version francaise</a>
24
+ <a href="docs/README.fr.md">Version francaise</a>
25
25
  </p>
26
26
 
27
27
  ---
@@ -285,7 +285,7 @@ Add to `.pre-commit-config.yaml`:
285
285
  ```yaml
286
286
  repos:
287
287
  - repo: https://github.com/DNSZLSK/muad-dib
288
- rev: v2.2.24
288
+ rev: v2.3.1
289
289
  hooks:
290
290
  - id: muaddib-scan # Scan all threats
291
291
  # - id: muaddib-diff # Or: only new threats
@@ -641,7 +641,7 @@ Alerts appear in Security > Code scanning alerts.
641
641
  ## Architecture
642
642
 
643
643
  ```
644
- MUAD'DIB 2.2.24 Scanner
644
+ MUAD'DIB 2.3.1 Scanner
645
645
  |
646
646
  +-- IOC Match (225,000+ packages, JSON DB)
647
647
  | +-- OSV.dev npm dump (200K+ MAL-* entries)
@@ -663,7 +663,7 @@ MUAD'DIB 2.2.24 Scanner
663
663
  | +-- 3-hop re-export chains, class method analysis
664
664
  | +-- Cross-file credential read -> network sink detection
665
665
  |
666
- +-- 14 Parallel Scanners (94 rules)
666
+ +-- 14 Parallel Scanners (102 rules)
667
667
  | +-- AST Parse (acorn) — eval/Function, credential CLI theft, binary droppers, prototype hooks
668
668
  | +-- Pattern Matching (shell, scripts)
669
669
  | +-- Obfuscation Detection (skip .min.js, ignore hex/unicode alone)
@@ -689,11 +689,13 @@ MUAD'DIB 2.2.24 Scanner
689
689
  | +-- Score Breakdown (explainable per-rule scoring)
690
690
  | +-- Threat Feed API (HTTP server, JSON feed for SIEM)
691
691
  |
692
- +-- FP Reduction Post-processing (v2.2.8-v2.2.9)
693
- | +-- Count-based severity downgrade (dynamic_require, dataflow, etc.)
694
- | +-- Framework prototype scoring cap
695
- | +-- Obfuscation in dist/build → LOW
692
+ +-- FP Reduction Post-processing (v2.2.8-v2.2.9, v2.3.0-v2.3.1)
693
+ | +-- Count-based severity downgrade (dynamic_require, dataflow, module_compile, etc.)
694
+ | +-- Framework prototype scoring cap + HTTP client whitelist
695
+ | +-- Obfuscation in dist/build/.cjs/.mjs → LOW
696
696
  | +-- Safe env var + prefix filtering
697
+ | +-- Dataflow telemetry source categorization (os.platform/arch → telemetry_read)
698
+ | +-- DEP whitelist (es5-ext, bootstrap-sass) + npm alias skip
697
699
  |
698
700
  +-- Per-File Max Scoring (v2.2.11)
699
701
  | +-- Score = max(file_scores) + package_level_score
@@ -721,9 +723,8 @@ Output (CLI, JSON, HTML, SARIF, Webhook, Threat Feed)
721
723
  | Metric | Result | Details |
722
724
  |--------|--------|---------|
723
725
  | **TPR** (Ground Truth) | **91.8%** (45/49) | 51 real-world attacks (49 active). 4 out-of-scope: browser-only (3) + FP-risky (1) |
724
- | **FPR** (Standard packages) | **6.2%** (18/290) | Packages with <10 JS files typical libraries and tools |
725
- | **FPR** (Benign, global) | **~13%** (69/527) | 529 npm packages, real source code via `npm pack`, threshold > 20 |
726
- | **ADR** (Adversarial + Holdout) | **100%** (78/78) | 38 adversarial + 40 holdout evasive samples across 5 red-team waves |
726
+ | **FPR** (Benign, global) | **7.4%** (39/525) | 529 npm packages (525 scanned), real source code via `npm pack`, threshold > 20 |
727
+ | **ADR** (Adversarial + Holdout) | **98.7%** (77/78) | 38 adversarial + 40 holdout evasive samples. 1 documented miss: `require-cache-poison` (accepted trade-off) |
727
728
 
728
729
  **FPR by package size** — FPR correlates linearly with package size. Per-file max scoring (v2.2.11) significantly reduces FP on medium/large packages:
729
730
 
@@ -734,7 +735,7 @@ Output (CLI, JSON, HTML, SARIF, Webhook, Threat Feed)
734
735
  | Large (50-100 JS files) | 40 | 10 | 25.0% |
735
736
  | Very large (100+ JS files) | 62 | 25 | 40.3% |
736
737
 
737
- **FPR progression**: 0% (invalid, empty dirs, v2.2.0-v2.2.6) → 38% (first real measurement, v2.2.7) → 19.4% (v2.2.8) → 17.5% (v2.2.9) → **~13%** (v2.2.11, per-file max scoring)
738
+ **FPR progression**: 0% (invalid, empty dirs, v2.2.0-v2.2.6) → 38% (first real measurement, v2.2.7) → 19.4% (v2.2.8) → 17.5% (v2.2.9) → ~13% (v2.2.11, per-file max scoring) → 8.9% (v2.3.0, P2) → **7.4%** (v2.3.1, P3)
738
739
 
739
740
  **Holdout progression** (pre-tuning scores, rules frozen):
740
741
 
@@ -748,10 +749,10 @@ Output (CLI, JSON, HTML, SARIF, Webhook, Threat Feed)
748
749
 
749
750
  - **TPR** (True Positive Rate): detection rate on 49 real-world supply-chain attacks (event-stream, ua-parser-js, coa, flatmap-stream, eslint-scope, solana-web3js, and 43 more). 4 misses are browser-only (lottie-player, polyfill-io, trojanized-jquery) or risky to fix (websocket-rat) — see [Threat Model](docs/threat-model.md).
750
751
  - **FPR** (False Positive Rate): packages scoring > 20 out of 529 real npm packages (source code scanned, not empty dirs). The 6.2% on standard packages (<10 JS files, 290 packages) is the most representative metric for typical use — most npm packages are small.
751
- - **ADR** (Adversarial Detection Rate): detection rate on 75 evasive malicious samples — 35 adversarial (4 red-team waves) + 40 holdout (5 batches of 10, testing obfuscation, inter-module dataflow, etc.)
752
+ - **ADR** (Adversarial Detection Rate): detection rate on 78 evasive malicious samples — 38 adversarial + 40 holdout (5 batches of 10, testing obfuscation, inter-module dataflow, etc.). 1 documented miss: `require-cache-poison` (score 10 < threshold 20, accepted trade-off from FP reduction P3).
752
753
  - **Holdout** (pre-tuning): detection rate on 10 unseen samples with rules frozen (measures generalization)
753
754
 
754
- Datasets: 529 npm + 132 PyPI benign packages, 78 adversarial/holdout samples, 51 ground-truth attacks (65 documented malware packages). **1317 tests**, 86% code coverage.
755
+ Datasets: 529 npm + 132 PyPI benign packages, 78 adversarial/holdout samples, 51 ground-truth attacks (65 documented malware packages). **1387 tests**, 86% code coverage.
755
756
 
756
757
  See [Evaluation Methodology](docs/EVALUATION_METHODOLOGY.md) for the full experimental protocol.
757
758
 
@@ -787,11 +788,11 @@ npm test
787
788
 
788
789
  ### Testing
789
790
 
790
- - **1317 unit/integration tests** across 20 modular test files - 86% code coverage via [Codecov](https://codecov.io/gh/DNSZLSK/muad-dib)
791
+ - **1387 unit/integration tests** across 20 modular test files - 86% code coverage via [Codecov](https://codecov.io/gh/DNSZLSK/muad-dib)
791
792
  - **56 fuzz tests** - Malformed YAML, invalid JSON, binary files, ReDoS, unicode, 10MB inputs
792
- - **78 adversarial/holdout samples** - 38 adversarial + 40 holdout, 78/78 detection rate (100% ADR)
793
+ - **78 adversarial/holdout samples** - 38 adversarial + 40 holdout, 77/78 detection rate (98.7% ADR). 1 documented miss: `require-cache-poison` (accepted trade-off)
793
794
  - **Ground truth validation** - 51 real-world attacks (45/49 detected = 91.8% TPR). 4 out-of-scope: browser-only (3) + FP-risky (1)
794
- - **False positive validation** - 6.2% FPR on standard packages (18/290), ~13% global (69/527) on real npm source code via `npm pack`
795
+ - **False positive validation** - 7.4% FPR global (39/525) on real npm source code via `npm pack`
795
796
  - **ESLint security audit** - `eslint-plugin-security` with 14 rules enabled
796
797
 
797
798
  ---
package/bin/muaddib.js CHANGED
@@ -3,7 +3,6 @@ const { exec } = require('child_process');
3
3
  const { run } = require('../src/index.js');
4
4
  const { updateIOCs } = require('../src/ioc/updater.js');
5
5
  const { watch } = require('../src/watch.js');
6
- const { startDaemon } = require('../src/daemon.js');
7
6
  const { runScraper } = require('../src/ioc/scraper.js');
8
7
  const { safeInstall } = require('../src/safe-install.js');
9
8
  const { buildSandboxImage, runSandbox, generateNetworkReport } = require('../src/sandbox.js');
@@ -279,6 +278,7 @@ async function interactiveMenu() {
279
278
  message: 'Webhook URL:'
280
279
  });
281
280
  }
281
+ const { startDaemon } = require('../src/daemon.js');
282
282
  startDaemon({ webhook });
283
283
  }
284
284
 
@@ -593,6 +593,7 @@ if (command === 'version' || command === '--version' || command === '-v') {
593
593
  });
594
594
  }
595
595
  } else if (command === 'daemon') {
596
+ const { startDaemon } = require('../src/daemon.js');
596
597
  startDaemon({ webhook: webhookUrl });
597
598
  } else if (command === 'install' || command === 'i') {
598
599
  const packages = options.filter(o => !o.startsWith('-'));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "muaddib-scanner",
3
- "version": "2.3.1",
3
+ "version": "2.3.3",
4
4
  "description": "Supply-chain threat detection & response for npm & PyPI/Python",
5
5
  "main": "src/index.js",
6
6
  "bin": {