muaddib-scanner 2.5.16 → 2.5.17
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 +32 -20
- package/package.json +1 -1
- package/src/rules/index.js +2 -2
- package/src/scanner/ast-detectors.js +4 -2
- package/src/scanner/dataflow.js +15 -2
- package/src/scanner/obfuscation.js +4 -1
- package/src/scoring.js +10 -6
package/README.md
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
|
|
31
31
|
npm and PyPI supply-chain attacks are exploding. Shai-Hulud compromised 25K+ repos in 2025. Existing tools detect threats but don't help you respond.
|
|
32
32
|
|
|
33
|
-
MUAD'DIB combines static analysis + **deobfuscation engine** (v2.2.5) + **inter-module dataflow** (v2.2.6) + **per-file max scoring** (v2.2.11) + dynamic analysis (Docker sandbox with **monkey-patching preload** for time-bomb detection, v2.4.9) + **behavioral anomaly detection** (v2.0) + **ground truth validation** (v2.1) + **security audit** (41 issues remediated, v2.5.0–v2.5.6) to detect threats AND guide your response — even before they appear in any IOC database.
|
|
33
|
+
MUAD'DIB combines static analysis + **deobfuscation engine** (v2.2.5) + **inter-module dataflow** (v2.2.6) + **per-file max scoring** (v2.2.11) + dynamic analysis (Docker sandbox with **monkey-patching preload** for time-bomb detection, v2.4.9) + **behavioral anomaly detection** (v2.0) + **ground truth validation** (v2.1) + **security audit** (41 issues remediated, v2.5.0–v2.5.6) + **audit hardening** (v2.5.13–v2.5.14) + **FP reduction P5/P6** (v2.5.15–v2.5.16) to detect threats AND guide your response — even before they appear in any IOC database.
|
|
34
34
|
|
|
35
35
|
---
|
|
36
36
|
|
|
@@ -286,7 +286,7 @@ Add to `.pre-commit-config.yaml`:
|
|
|
286
286
|
```yaml
|
|
287
287
|
repos:
|
|
288
288
|
- repo: https://github.com/DNSZLSK/muad-dib
|
|
289
|
-
rev: v2.5.
|
|
289
|
+
rev: v2.5.17
|
|
290
290
|
hooks:
|
|
291
291
|
- id: muaddib-scan # Scan all threats
|
|
292
292
|
# - id: muaddib-diff # Or: only new threats
|
|
@@ -335,7 +335,7 @@ muaddib replay
|
|
|
335
335
|
muaddib ground-truth
|
|
336
336
|
```
|
|
337
337
|
|
|
338
|
-
Replay real-world supply-chain attacks against the scanner to validate detection coverage. Current results: **
|
|
338
|
+
Replay real-world supply-chain attacks against the scanner to validate detection coverage. Current results: **46/49 detected (93.9% TPR)** from 51 samples (49 active).
|
|
339
339
|
|
|
340
340
|
4 out-of-scope misses: lottie-player, polyfill-io, trojanized-jquery (browser-only DOM attacks), websocket-rat (FP-risky pattern).
|
|
341
341
|
|
|
@@ -642,7 +642,7 @@ Alerts appear in Security > Code scanning alerts.
|
|
|
642
642
|
## Architecture
|
|
643
643
|
|
|
644
644
|
```
|
|
645
|
-
MUAD'DIB 2.5.
|
|
645
|
+
MUAD'DIB 2.5.17 Scanner
|
|
646
646
|
|
|
|
647
647
|
+-- IOC Match (225,000+ packages, JSON DB)
|
|
648
648
|
| +-- OSV.dev npm dump (200K+ MAL-* entries)
|
|
@@ -664,7 +664,7 @@ MUAD'DIB 2.5.8 Scanner
|
|
|
664
664
|
| +-- 3-hop re-export chains, class method analysis
|
|
665
665
|
| +-- Cross-file credential read -> network sink detection
|
|
666
666
|
|
|
|
667
|
-
+-- 14 Parallel Scanners (
|
|
667
|
+
+-- 14 Parallel Scanners (121 rules)
|
|
668
668
|
| +-- AST Parse (acorn) — eval/Function, credential CLI theft, binary droppers, prototype hooks
|
|
669
669
|
| +-- Pattern Matching (shell, scripts)
|
|
670
670
|
| +-- Obfuscation Detection (skip .min.js, ignore hex/unicode alone)
|
|
@@ -685,20 +685,22 @@ MUAD'DIB 2.5.8 Scanner
|
|
|
685
685
|
|
|
|
686
686
|
+-- Validation & Observability (v2.1)
|
|
687
687
|
| +-- Datadog 17K Benchmark (88.2% raw, ~100% JS/Node.js adjusted)
|
|
688
|
-
| +-- Ground Truth Dataset (51 real-world attacks,
|
|
688
|
+
| +-- Ground Truth Dataset (51 real-world attacks, 93.9% TPR)
|
|
689
689
|
| +-- Detection Time Logging (first_seen tracking, lead time metrics)
|
|
690
690
|
| +-- FP Rate Tracking (daily stats, false positive rate)
|
|
691
691
|
| +-- Score Breakdown (explainable per-rule scoring)
|
|
692
692
|
| +-- Threat Feed API (HTTP server, JSON feed for SIEM)
|
|
693
693
|
|
|
|
694
|
-
+-- FP Reduction Post-processing (v2.2.8-v2.
|
|
694
|
+
+-- FP Reduction Post-processing (v2.2.8-v2.3.1, v2.5.7-v2.5.8, v2.5.15-v2.5.16)
|
|
695
695
|
| +-- Count-based severity downgrade (dynamic_require, dataflow, module_compile, etc.)
|
|
696
696
|
| +-- Framework prototype scoring cap + HTTP client whitelist
|
|
697
|
-
| +-- Obfuscation in dist/build/.cjs/.mjs → LOW
|
|
698
|
-
| +-- Safe env var + prefix filtering
|
|
697
|
+
| +-- Obfuscation in dist/build/.cjs/.mjs/.js >100KB → LOW
|
|
698
|
+
| +-- Safe env var + prefix filtering + DATAFLOW_SAFE_ENV_VARS
|
|
699
699
|
| +-- Dataflow telemetry source categorization (os.platform/arch → telemetry_read)
|
|
700
700
|
| +-- DEP whitelist (es5-ext, bootstrap-sass) + npm alias skip
|
|
701
701
|
| +-- IOC wildcard audit (v2.5.8): FPR 10.8% → 6.0%
|
|
702
|
+
| +-- P5 heuristic precision (v2.5.15): 7 fixes
|
|
703
|
+
| +-- P6 compound detection precision (v2.5.16): 6 fixes
|
|
702
704
|
|
|
|
703
705
|
+-- Per-File Max Scoring (v2.2.11)
|
|
704
706
|
| +-- Score = max(file_scores) + package_level_score
|
|
@@ -714,6 +716,14 @@ MUAD'DIB 2.5.8 Scanner
|
|
|
714
716
|
| +-- 41 issues remediated (14 CRITICAL, 18 HIGH, 9 MEDIUM)
|
|
715
717
|
| +-- Native addon path traversal, atomic writes, AST bypasses
|
|
716
718
|
|
|
|
719
|
+
+-- Audit Hardening (v2.5.13-v2.5.14)
|
|
720
|
+
| +-- Scoring: plugin loader threshold, lifecycle CRITICAL floor, percentage guard 40%
|
|
721
|
+
| +-- AST: eval alias, globalThis indirect, require(obj.prop), variable reassignment
|
|
722
|
+
| +-- Dataflow: Promise .then() tainting, JSON taint propagation
|
|
723
|
+
| +-- Shell: mkfifo+nc, base64|bash, wget+base64 (3 new patterns)
|
|
724
|
+
| +-- Entropy: fragment cluster, windowed analysis
|
|
725
|
+
| +-- 8 new rules (SHELL-013 to 015, ENTROPY-004, +4 audit fixes)
|
|
726
|
+
|
|
|
717
727
|
+-- Paranoid Mode (ultra-strict)
|
|
718
728
|
+-- Docker Sandbox (behavioral analysis, network capture, canary tokens, CI-aware, preload)
|
|
719
729
|
+-- Zero-Day Monitor (internal: npm + PyPI RSS polling, Discord alerts, daily report)
|
|
@@ -735,9 +745,9 @@ Output (CLI, JSON, HTML, SARIF, Webhook, Threat Feed)
|
|
|
735
745
|
| Metric | Result | Details |
|
|
736
746
|
|--------|--------|---------|
|
|
737
747
|
| **Wild TPR** (Datadog 17K) | **88.2%** raw · **~100%** adjusted | 17,922 real malware samples. 2,077 misses are all out-of-scope (see below) |
|
|
738
|
-
| **TPR** (Ground Truth) | **
|
|
739
|
-
| **FPR** (Benign, global) | **
|
|
740
|
-
| **ADR** (Adversarial + Holdout) | **
|
|
748
|
+
| **TPR** (Ground Truth) | **93.9%** (46/49) | 51 real-world attacks (49 active). 3 out-of-scope: browser-only (3) |
|
|
749
|
+
| **FPR** (Benign, global) | **12.3%** (65/529) | 529 npm packages, real source code via `npm pack`, threshold > 20 |
|
|
750
|
+
| **ADR** (Adversarial + Holdout) | **94.0%** (63/67) | 62 adversarial + 40 holdout evasive samples. 4 misses: `require-cache-poison` (P3 trade-off), `getter-defineProperty-exfil`, `setTimeout-eval-chain`, `setter-trap-exfil` |
|
|
741
751
|
|
|
742
752
|
**Datadog 17K benchmark** — [DataDog Malicious Software Packages Dataset](https://github.com/DataDog/malicious-software-packages-dataset), 17,922 real malware samples (npm). Raw TPR: 88.2% (15,810/17,922). The 2,077 misses (score=0) were manually categorized:
|
|
743
753
|
|
|
@@ -758,7 +768,9 @@ All 2,077 misses lack Node.js malware patterns. MUAD'DIB performs AST-based Node
|
|
|
758
768
|
| Large (50-100 JS files) | 40 | 10 | 25.0% |
|
|
759
769
|
| Very large (100+ JS files) | 62 | 25 | 40.3% |
|
|
760
770
|
|
|
761
|
-
**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) →
|
|
771
|
+
**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) → 6.0% (v2.5.8, P4 + IOC wildcard audit) → ~13.6% (v2.5.14, audit hardening added stricter detection) → **12.3%** (v2.5.16, P5 + P6)
|
|
772
|
+
|
|
773
|
+
> **Note on FPR evolution:** The historic 6.0% FPR (v2.5.8) relied on a `BENIGN_PACKAGE_WHITELIST` that excluded certain known packages from scoring — a data leakage bias removed in v2.5.10. The current 12.3% FPR is an honest measurement without whitelisting, against 529 real benign packages. The P5/P6 reductions (setTimeout precision, dist/ two-notch downgrade, credential_regex count-based, env segment matching, etc.) are detector precision improvements, not whitelisting.
|
|
762
774
|
|
|
763
775
|
**Holdout progression** (pre-tuning scores, rules frozen):
|
|
764
776
|
|
|
@@ -771,12 +783,12 @@ All 2,077 misses lack Node.js malware patterns. MUAD'DIB performs AST-based Node
|
|
|
771
783
|
| v5 | 50% (5/10) | Inter-module dataflow (new scanner) |
|
|
772
784
|
|
|
773
785
|
- **Wild TPR** (Datadog Benchmark): detection rate on 17,922 real malware packages from the [DataDog Malicious Software Packages Dataset](https://github.com/DataDog/malicious-software-packages-dataset). Raw 88.2% (15,810/17,922). Adjusted ~100% on JS/Node.js malware when excluding out-of-scope samples (1,233 phishing HTML pages, 824 native binaries, 20 corrected libraries). See [Evaluation Methodology](docs/EVALUATION_METHODOLOGY.md#14-datadog-17k-benchmark).
|
|
774
|
-
- **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).
|
|
786
|
+
- **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). 3 misses are browser-only (lottie-player, polyfill-io, trojanized-jquery) — see [Threat Model](docs/threat-model.md).
|
|
775
787
|
- **FPR** (False Positive Rate): packages scoring > 20 out of 529 real npm packages (source code scanned, not empty dirs).
|
|
776
|
-
- **ADR** (Adversarial Detection Rate): detection rate on
|
|
788
|
+
- **ADR** (Adversarial Detection Rate): detection rate on 102 evasive malicious samples — 62 adversarial + 40 holdout (5 adversarial waves + 4 holdout batches). 4 misses on available samples: `require-cache-poison` (P3 trade-off), `getter-defineProperty-exfil`, `setTimeout-eval-chain`, `setter-trap-exfil`.
|
|
777
789
|
- **Holdout** (pre-tuning): detection rate on 10 unseen samples with rules frozen (measures generalization)
|
|
778
790
|
|
|
779
|
-
Datasets: 17,922 Datadog malware samples, 529 npm + 132 PyPI benign packages,
|
|
791
|
+
Datasets: 17,922 Datadog malware samples, 529 npm + 132 PyPI benign packages, 102 adversarial/holdout samples, 51 ground-truth attacks (65 documented malware packages). **1869 tests**, 86% code coverage.
|
|
780
792
|
|
|
781
793
|
See [Evaluation Methodology](docs/EVALUATION_METHODOLOGY.md) for the full experimental protocol.
|
|
782
794
|
|
|
@@ -812,12 +824,12 @@ npm test
|
|
|
812
824
|
|
|
813
825
|
### Testing
|
|
814
826
|
|
|
815
|
-
- **
|
|
827
|
+
- **1869 unit/integration tests** across 43 modular test files - 86% code coverage via [Codecov](https://codecov.io/gh/DNSZLSK/muad-dib)
|
|
816
828
|
- **56 fuzz tests** - Malformed YAML, invalid JSON, binary files, ReDoS, unicode, 10MB inputs
|
|
817
829
|
- **Datadog 17K benchmark** - 17,922 real malware samples, 88.2% raw TPR, ~100% on JS/Node.js malware (2,077 out-of-scope misses: phishing, binaries, corrected libs)
|
|
818
|
-
- **
|
|
819
|
-
- **Ground truth validation** - 51 real-world attacks (
|
|
820
|
-
- **False positive validation** -
|
|
830
|
+
- **102 adversarial/holdout samples** - 62 adversarial + 40 holdout, 63/67 detection rate on available samples (94.0% ADR). 4 misses: `require-cache-poison` (P3 trade-off), `getter-defineProperty-exfil`, `setTimeout-eval-chain`, `setter-trap-exfil`
|
|
831
|
+
- **Ground truth validation** - 51 real-world attacks (46/49 detected = 93.9% TPR). 3 out-of-scope: browser-only (lottie-player, polyfill-io, trojanized-jquery)
|
|
832
|
+
- **False positive validation** - 12.3% FPR global (65/529) on real npm source code via `npm pack`
|
|
821
833
|
- **ESLint security audit** - `eslint-plugin-security` with 14 rules enabled
|
|
822
834
|
|
|
823
835
|
---
|
package/package.json
CHANGED
package/src/rules/index.js
CHANGED
|
@@ -703,7 +703,7 @@ const RULES = {
|
|
|
703
703
|
module_compile: {
|
|
704
704
|
id: 'MUADDIB-AST-023',
|
|
705
705
|
name: 'Module Compile Execution',
|
|
706
|
-
severity: '
|
|
706
|
+
severity: 'HIGH',
|
|
707
707
|
confidence: 'high',
|
|
708
708
|
description: 'module._compile() detecte. Execution de code arbitraire a partir d\'une chaine dans le contexte module. Technique cle de flatmap-stream.',
|
|
709
709
|
references: [
|
|
@@ -729,7 +729,7 @@ const RULES = {
|
|
|
729
729
|
module_compile_dynamic: {
|
|
730
730
|
id: 'MUADDIB-AST-025',
|
|
731
731
|
name: 'Dynamic Module Compile Execution',
|
|
732
|
-
severity: '
|
|
732
|
+
severity: 'HIGH',
|
|
733
733
|
confidence: 'high',
|
|
734
734
|
description: 'Module._compile() avec argument dynamique (non-literal). Execution de code en memoire sans ecriture sur disque. Technique d\'evasion malware courante.',
|
|
735
735
|
references: [
|
|
@@ -1294,7 +1294,9 @@ function handleCallExpression(node, ctx) {
|
|
|
1294
1294
|
ctx.hasDynamicExec = true;
|
|
1295
1295
|
ctx.threats.push({
|
|
1296
1296
|
type: 'module_compile',
|
|
1297
|
-
|
|
1297
|
+
// P6: Baseline HIGH — single module._compile() in build tools (@babel/core, art-template)
|
|
1298
|
+
// is framework behavior. Compound detections (zlib_inflate_eval, fetch_decrypt_exec) stay CRITICAL.
|
|
1299
|
+
severity: 'HIGH',
|
|
1298
1300
|
message: 'module._compile() detected — executes arbitrary code from string in module context (flatmap-stream pattern).',
|
|
1299
1301
|
file: ctx.relFile
|
|
1300
1302
|
});
|
|
@@ -1302,7 +1304,7 @@ function handleCallExpression(node, ctx) {
|
|
|
1302
1304
|
if (node.arguments.length >= 1 && !hasOnlyStringLiteralArgs(node)) {
|
|
1303
1305
|
ctx.threats.push({
|
|
1304
1306
|
type: 'module_compile_dynamic',
|
|
1305
|
-
severity: '
|
|
1307
|
+
severity: 'HIGH',
|
|
1306
1308
|
message: 'In-memory code execution via Module._compile(). Common malware evasion technique.',
|
|
1307
1309
|
file: ctx.relFile
|
|
1308
1310
|
});
|
package/src/scanner/dataflow.js
CHANGED
|
@@ -740,8 +740,9 @@ const SENSITIVE_PATH_PATTERNS = [
|
|
|
740
740
|
'.ethereum', '.electrum', '.config/solana', '.exodus',
|
|
741
741
|
'.atomic', '.metamask', '.ledger-live', '.trezor',
|
|
742
742
|
'.bitcoin', '.monero', '.gnupg',
|
|
743
|
-
'_cacache', '.cache/yarn', '.cache/pip'
|
|
744
|
-
|
|
743
|
+
'_cacache', '.cache/yarn', '.cache/pip'
|
|
744
|
+
// P6: Removed discord, leveldb — data directories, not credential paths.
|
|
745
|
+
// _cacache/.cache kept — real cache poisoning vectors (T1195.002).
|
|
745
746
|
];
|
|
746
747
|
|
|
747
748
|
function isSensitivePath(val) {
|
|
@@ -816,8 +817,20 @@ const SYSTEM_IDENTITY_ENVS = new Set([
|
|
|
816
817
|
// Env var prefixes for tool-internal configuration (not external credentials)
|
|
817
818
|
const SAFE_ENV_PREFIXES = ['MUADDIB_', 'npm_config_', 'npm_lifecycle_', 'npm_package_'];
|
|
818
819
|
|
|
820
|
+
// P6: Node.js runtime config env vars that are not credentials.
|
|
821
|
+
// NODE_TLS_REJECT_UNAUTHORIZED matches "AUTH" in "UNAUTHORIZED" → false positive.
|
|
822
|
+
// Real credential exfiltration targets API_KEY, TOKEN, SECRET, PASSWORD.
|
|
823
|
+
const DATAFLOW_SAFE_ENV_VARS = new Set([
|
|
824
|
+
'NODE_TLS_REJECT_UNAUTHORIZED', 'NODE_OPTIONS', 'NODE_EXTRA_CA_CERTS',
|
|
825
|
+
'NODE_ENV', 'NODE_PATH', 'NODE_DEBUG',
|
|
826
|
+
'DEBUG', 'CI', 'HTTPS_PROXY', 'HTTP_PROXY', 'NO_PROXY',
|
|
827
|
+
'LANG', 'TZ', 'PORT', 'HOST'
|
|
828
|
+
// Note: HOME, USER, HOSTNAME stay sensitive — fingerprint exfiltration detection.
|
|
829
|
+
]);
|
|
830
|
+
|
|
819
831
|
function isSensitiveEnv(name) {
|
|
820
832
|
const upper = name.toUpperCase();
|
|
833
|
+
if (DATAFLOW_SAFE_ENV_VARS.has(upper)) return false;
|
|
821
834
|
if (SYSTEM_IDENTITY_ENVS.has(upper)) return true;
|
|
822
835
|
if (SAFE_ENV_PREFIXES.some(p => upper.startsWith(p))) return false;
|
|
823
836
|
const sensitive = ['TOKEN', 'SECRET', 'KEY', 'PASSWORD', 'CREDENTIAL', 'AUTH', 'NPM', 'AWS', 'AZURE', 'GCP'];
|
|
@@ -20,7 +20,10 @@ function detectObfuscation(targetPath) {
|
|
|
20
20
|
const pathParts = relativePath.split(path.sep);
|
|
21
21
|
const isInDistOrBuild = pathParts.some(p => p === 'dist' || p === 'build');
|
|
22
22
|
const isLargeCjsMjs = (basename.endsWith('.cjs') || basename.endsWith('.mjs')) && content.length > 100 * 1024;
|
|
23
|
-
|
|
23
|
+
// P6: Any JS file > 100KB is overwhelmingly bundled output regardless of directory name.
|
|
24
|
+
// Real obfuscated malware is typically small (<50KB). Catches prettier plugins/, svelte compiler/, etc.
|
|
25
|
+
const isLargeJs = basename.endsWith('.js') && content.length > 100 * 1024;
|
|
26
|
+
const isPackageOutput = isMinified || isBundled || isInDistOrBuild || isLargeCjsMjs || isLargeJs;
|
|
24
27
|
|
|
25
28
|
// 1. Ratio code sur une seule ligne (skip .min.js — minification, not obfuscation)
|
|
26
29
|
if (!isMinified) {
|
package/src/scoring.js
CHANGED
|
@@ -108,8 +108,8 @@ const FP_COUNT_THRESHOLDS = {
|
|
|
108
108
|
require_cache_poison: { maxCount: 3, from: 'CRITICAL', to: 'LOW' },
|
|
109
109
|
suspicious_dataflow: { maxCount: 3, to: 'LOW' },
|
|
110
110
|
obfuscation_detected: { maxCount: 3, to: 'LOW' },
|
|
111
|
-
module_compile_dynamic: { maxCount: 3, from: '
|
|
112
|
-
module_compile: { maxCount: 3, from: '
|
|
111
|
+
module_compile_dynamic: { maxCount: 3, from: 'HIGH', to: 'LOW' },
|
|
112
|
+
module_compile: { maxCount: 3, from: 'HIGH', to: 'LOW' },
|
|
113
113
|
zlib_inflate_eval: { maxCount: 2, from: 'CRITICAL', to: 'LOW' },
|
|
114
114
|
// Build tools (webpack, jest) legitimately use vm.runInThisContext for module evaluation
|
|
115
115
|
vm_code_execution: { maxCount: 3, from: 'HIGH', to: 'LOW' },
|
|
@@ -120,7 +120,10 @@ const FP_COUNT_THRESHOLDS = {
|
|
|
120
120
|
// P4: bundled credential_tampering from minified alias resolution (jspdf, lerna)
|
|
121
121
|
credential_tampering: { maxCount: 5, to: 'LOW' },
|
|
122
122
|
// B1 FP reduction: bundled code aliases eval/Function (sinon, storybook, vitest)
|
|
123
|
-
dangerous_call_eval: { maxCount: 3, from: 'MEDIUM', to: 'LOW' }
|
|
123
|
+
dangerous_call_eval: { maxCount: 3, from: 'MEDIUM', to: 'LOW' },
|
|
124
|
+
// P6: HTTP client libraries (undici, aws-sdk, nodemailer, jsdom) parse Authorization/Bearer headers
|
|
125
|
+
// with 5+ credential regexes. Real harvesters use 1-2 targeted regexes.
|
|
126
|
+
credential_regex_harvest: { maxCount: 4, from: 'HIGH', to: 'LOW' }
|
|
124
127
|
};
|
|
125
128
|
|
|
126
129
|
// Types exempt from dist/ downgrade — IOC matches, lifecycle scripts, and
|
|
@@ -135,9 +138,10 @@ const DIST_EXEMPT_TYPES = new Set([
|
|
|
135
138
|
'download_exec_binary', // download + chmod + exec (binary dropper)
|
|
136
139
|
'cross_file_dataflow', // credential read → network exfil across files
|
|
137
140
|
'staged_eval_decode', // eval(atob(...)) (explicit payload staging)
|
|
138
|
-
'reverse_shell'
|
|
139
|
-
|
|
140
|
-
|
|
141
|
+
'reverse_shell' // net.Socket + connect + pipe (always malicious)
|
|
142
|
+
// P6: remote_code_load and proxy_data_intercept removed — in bundled dist/ files,
|
|
143
|
+
// fetch + eval co-occurrence is coincidental (bundler combines HTTP client + template compilation).
|
|
144
|
+
// fetch_decrypt_exec (fetch+decrypt+eval triple) remains exempt — never coincidental.
|
|
141
145
|
]);
|
|
142
146
|
|
|
143
147
|
// Regex matching dist/build/minified/bundled file paths
|