muaddib-scanner 2.7.4 → 2.7.6
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 +3 -3
- package/package.json +1 -1
- package/src/response/playbooks.js +3 -0
- package/src/rules/index.js +9 -0
- package/src/scanner/ast-detectors.js +13 -0
- package/src/scanner/npm-registry.js +3 -1
package/README.md
CHANGED
|
@@ -286,7 +286,7 @@ repos:
|
|
|
286
286
|
| **FPR** (Benign) | **12.1%** (64/529) | 529 npm packages, real source via `npm pack` |
|
|
287
287
|
| **ADR** (Adversarial + Holdout) | **92.2%** (71/77) | 53 adversarial + 40 holdout (77 available on disk), global threshold=20 |
|
|
288
288
|
|
|
289
|
-
**
|
|
289
|
+
**2093 tests** across 49 files. **134 rules** (129 RULES + 5 PARANOID).
|
|
290
290
|
|
|
291
291
|
> **Methodology caveats:**
|
|
292
292
|
> - TPR measured on 49 Node.js attack samples (3 browser-only excluded from 51 total)
|
|
@@ -327,7 +327,7 @@ npm test
|
|
|
327
327
|
|
|
328
328
|
### Testing
|
|
329
329
|
|
|
330
|
-
- **
|
|
330
|
+
- **2093 tests** across 49 modular test files
|
|
331
331
|
- **56 fuzz tests** - Malformed inputs, ReDoS, unicode, binary
|
|
332
332
|
- **Datadog 17K benchmark** - 17,922 real malware samples
|
|
333
333
|
- **Ground truth validation** - 51 real-world attacks (93.9% TPR)
|
|
@@ -347,7 +347,7 @@ npm test
|
|
|
347
347
|
- [Evaluation Methodology](docs/EVALUATION_METHODOLOGY.md) - Experimental protocol, holdout scores
|
|
348
348
|
- [Threat Model](docs/threat-model.md) - What MUAD'DIB detects and doesn't detect
|
|
349
349
|
- [Adversarial Evaluation](ADVERSARIAL.md) - Red team samples and ADR results
|
|
350
|
-
- [Security Policy](SECURITY.md) - Detection rules reference (
|
|
350
|
+
- [Security Policy](SECURITY.md) - Detection rules reference (134 rules)
|
|
351
351
|
- [Security Audit](docs/SECURITY_AUDIT.md) - Bypass validation report
|
|
352
352
|
- [FP Analysis](docs/EVALUATION.md) - Historical false positive analysis
|
|
353
353
|
|
package/package.json
CHANGED
|
@@ -478,6 +478,9 @@ const PLAYBOOKS = {
|
|
|
478
478
|
'CRITIQUE: Module WebAssembly charge avec des imports host contenant des sinks reseau. Le flux de controle est cache dans le binaire WASM, ' +
|
|
479
479
|
'rendant l\'analyse statique impossible. Le WASM peut lire des fichiers sensibles et exfiltrer via les callbacks host. ' +
|
|
480
480
|
'Supprimer le package immediatement. Analyser le fichier WASM avec wasm2wat pour comprendre le flux. Regenerer tous les secrets.',
|
|
481
|
+
wasm_standalone:
|
|
482
|
+
'Module WebAssembly charge sans sink reseau apparent. Usage potentiellement legitime (crypto, image, codecs video). ' +
|
|
483
|
+
'Verifier le fichier .wasm avec wasm2wat. Si le package n\'a aucune raison d\'utiliser du WASM, considerer comme suspect.',
|
|
481
484
|
credential_regex_harvest:
|
|
482
485
|
'Code contient des regex de detection de credentials (Bearer, password, token, API key) combine avec un appel reseau. ' +
|
|
483
486
|
'Technique de harvesting: scanne les donnees en transit (streams HTTP, fichiers) pour extraire des secrets et les exfiltrer. ' +
|
package/src/rules/index.js
CHANGED
|
@@ -1309,6 +1309,15 @@ const RULES = {
|
|
|
1309
1309
|
],
|
|
1310
1310
|
mitre: 'T1059'
|
|
1311
1311
|
},
|
|
1312
|
+
wasm_standalone: {
|
|
1313
|
+
id: 'MUADDIB-AST-046',
|
|
1314
|
+
name: 'WASM Module Load (Standalone)',
|
|
1315
|
+
severity: 'MEDIUM',
|
|
1316
|
+
confidence: 'medium',
|
|
1317
|
+
description: 'Module WebAssembly charge sans sink reseau detectable. Usage legitime frequent (cryptographie, traitement d\'image, codecs). Le WASM cache le flux de controle — verifier le fichier .wasm manuellement.',
|
|
1318
|
+
references: ['https://attack.mitre.org/techniques/T1027/'],
|
|
1319
|
+
mitre: 'T1027'
|
|
1320
|
+
},
|
|
1312
1321
|
credential_regex_harvest: {
|
|
1313
1322
|
id: 'MUADDIB-AST-041',
|
|
1314
1323
|
name: 'Credential Regex Harvesting',
|
|
@@ -2094,6 +2094,19 @@ function handlePostWalk(ctx) {
|
|
|
2094
2094
|
});
|
|
2095
2095
|
}
|
|
2096
2096
|
|
|
2097
|
+
// WASM standalone: WebAssembly.compile/instantiate WITHOUT network sinks.
|
|
2098
|
+
// Legitimate: crypto, image processing, codecs. Still warrants investigation
|
|
2099
|
+
// because WASM hides control flow from static analysis.
|
|
2100
|
+
// Compound WASM + network → wasm_host_sink (CRITICAL) takes priority (mutually exclusive).
|
|
2101
|
+
if (ctx.hasWasmLoad && !ctx.hasNetworkCallInFile) {
|
|
2102
|
+
ctx.threats.push({
|
|
2103
|
+
type: 'wasm_standalone',
|
|
2104
|
+
severity: 'MEDIUM',
|
|
2105
|
+
message: 'WebAssembly module loaded without detectable network sinks. WASM hides control flow — verify .wasm file purpose.',
|
|
2106
|
+
file: ctx.relFile
|
|
2107
|
+
});
|
|
2108
|
+
}
|
|
2109
|
+
|
|
2097
2110
|
// Credential regex harvesting: credential-matching regex + network call in same file
|
|
2098
2111
|
// Real-world pattern: Transform/stream that scans data for tokens/passwords and exfiltrates
|
|
2099
2112
|
if (ctx.hasCredentialRegex && ctx.hasNetworkCallInFile) {
|
|
@@ -114,6 +114,7 @@ async function getPackageMetadata(packageName) {
|
|
|
114
114
|
|
|
115
115
|
const weeklyDownloads = downloadsData?.downloads ?? 0;
|
|
116
116
|
const authorPackageCount = authorData?.total ?? 0;
|
|
117
|
+
const versionCount = meta.versions ? Object.keys(meta.versions).length : 0;
|
|
117
118
|
|
|
118
119
|
return {
|
|
119
120
|
created_at: createdAt,
|
|
@@ -121,7 +122,8 @@ async function getPackageMetadata(packageName) {
|
|
|
121
122
|
weekly_downloads: weeklyDownloads,
|
|
122
123
|
author_package_count: authorPackageCount,
|
|
123
124
|
has_readme: hasReadme,
|
|
124
|
-
has_repository: hasRepository
|
|
125
|
+
has_repository: hasRepository,
|
|
126
|
+
version_count: versionCount
|
|
125
127
|
};
|
|
126
128
|
}
|
|
127
129
|
|