muaddib-scanner 2.11.146 → 2.11.147

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "muaddib-scanner",
3
- "version": "2.11.146",
3
+ "version": "2.11.147",
4
4
  "description": "Supply-chain threat detection & response for npm & PyPI/Python",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "target": "node_modules",
3
- "timestamp": "2026-07-02T08:08:45.257Z",
3
+ "timestamp": "2026-07-02T09:19:55.784Z",
4
4
  "threats": [
5
5
  {
6
6
  "type": "string_mutation_obfuscation",
@@ -1148,7 +1148,7 @@ const RULES = {
1148
1148
  severity: 'CRITICAL',
1149
1149
  confidence: 'high',
1150
1150
  domain: 'malware',
1151
- description: 'Reference dissimulee (charcode/base64/hex) OU enumeration de process.env cherchant un prefix marqueur MUADDIB (marker-agnostique), vers un marqueur d\'environnement d\'analyse — marqueur de sandbox MUAD\'DIB (MUADDIB_GVISOR), marqueur d\'un analyseur pair, ou nom de poison-token. Seules les formes obfusquees/enumerees sont matchees : le code de sandbox de MUAD\'DIB lui-meme et l\'outillage securite legitime referencent ces marqueurs en clair sans risque. Aucun package legitime n\'encode ni n\'enumere un check pour ces tripwires. Le marqueur est un honeytoken plante : garde public et stable pour que tout verificateur s\'auto-incrimine.',
1151
+ description: 'Reference dissimulee (charcode/base64/hex) OU enumeration de process.env (JS) / os.environ (Python) cherchant un prefix marqueur MUADDIB (marker-agnostique), vers un marqueur d\'environnement d\'analyse — marqueur de sandbox MUAD\'DIB (MUADDIB_GVISOR), marqueur d\'un analyseur pair, ou nom de poison-token. Seules les formes obfusquees/enumerees sont matchees : le code de sandbox de MUAD\'DIB lui-meme et l\'outillage securite legitime referencent ces marqueurs en clair sans risque. Aucun package legitime n\'encode ni n\'enumere un check pour ces tripwires. Le marqueur est un honeytoken plante : garde public et stable pour que tout verificateur s\'auto-incrimine.',
1152
1152
  references: [
1153
1153
  'https://attack.mitre.org/techniques/T1497/',
1154
1154
  'https://attack.mitre.org/techniques/T1480/'
@@ -31,6 +31,7 @@
31
31
  const fs = require('fs');
32
32
  const path = require('path');
33
33
  const { countInvisibleUnicode, stripInvisibleUnicode } = require('../shared/unicode-invisibles.js');
34
+ const { detectAnalyzerHoneytoken } = require('./ast-detectors/anti-evasion.js');
34
35
 
35
36
  const MAX_FILE_SIZE = 1024 * 1024; // 1 MB cap, cohérent avec ai-config.js
36
37
 
@@ -216,6 +217,38 @@ function detectForkExecInlineInterpreter(content) {
216
217
  return FORK_EXEC_INLINE_INTERPRETER_RE.test(content);
217
218
  }
218
219
 
220
+ // ── Python anti-evasion (M2 follow-up, 2026-07): PyPI parity for AST-096 ──
221
+ // analyzer_honeytoken_reference. Two FP-safe forms mirroring the JS side
222
+ // (ast-detectors/anti-evasion.js), BOTH reusing the existing CRITICAL AST-096
223
+ // rule (no new rule → rule count unchanged):
224
+ // 1. os.environ ENUMERATION (for-in / .keys() / .items()) coupled with a
225
+ // MUADDIB-prefix key test (.startswith / == / in). NOT a direct read:
226
+ // MUAD'DIB tooling reads specific MUADDIB_* config vars directly (verified
227
+ // across the repo), while evasion enumerates the whole env looking for our
228
+ // sandbox tripwire prefix. FP-safe by the distinctive marker + enumeration.
229
+ // 2. base64 / hex / charcode-encoded analyzer marker — handled by REUSING the
230
+ // shared detectAnalyzerHoneytoken() (language-agnostic decoder; it already
231
+ // matches Python byte-array, base64 and hex-escape encodings of the marker).
232
+ // Deliberately NOT covered (honest blind spots): plaintext direct reads of the
233
+ // honeytoken (legit security tooling references markers in the clear — same
234
+ // stance as the JS side); /proc fingerprinting such as reading the kernel
235
+ // version file (legit container-detection reads it — the Python equivalent of
236
+ // the gVisor FP); and shell/bash install hooks (this scanner only reads .py).
237
+ const PY_ENV_ENUM_RE = /\bfor\s+\w+\s+in\s+os\.environ\b|\bos\.environ\.(?:keys|items)\s*\(\s*\)/;
238
+ const PY_ENV_MARKER_TEST_RE = /\.startswith\s*\(\s*['"]MUADDIB|['"]MUADDIB\w*['"]\s*(?:==|!=)|(?:==|!=)\s*['"]MUADDIB|['"]MUADDIB\w*['"]\s+in\b/;
239
+
240
+ /**
241
+ * Python parity for the JS detectEnvMarkerEnumeration. Returns 'MUADDIB' if the
242
+ * file enumerates os.environ AND tests keys against the distinctive MUADDIB
243
+ * prefix, else null. FP-safe: MUAD'DIB reads its own MUADDIB_* vars directly
244
+ * (os.environ.get), never via enumerate+startswith (verified across the repo).
245
+ */
246
+ function detectPythonEnvMarkerEnumeration(content) {
247
+ if (!content || content.indexOf('os.environ') === -1) return null;
248
+ if (!PY_ENV_ENUM_RE.test(content)) return null;
249
+ return PY_ENV_MARKER_TEST_RE.test(content) ? 'MUADDIB' : null;
250
+ }
251
+
219
252
  /**
220
253
  * Scan Python source files under targetPath for import-time / install-time RCE.
221
254
  *
@@ -347,6 +380,21 @@ function scanPythonSource(targetPath) {
347
380
  file: relPath
348
381
  });
349
382
  }
383
+
384
+ // Anti-evasion (AST-096 reused) — Python parity. Runs on cleaned content so
385
+ // a base64 example inside a stripped docstring/comment cannot fire.
386
+ const honeytokenMarker = detectAnalyzerHoneytoken(cleaned);
387
+ const envEnumMarker = honeytokenMarker ? null : detectPythonEnvMarkerEnumeration(cleaned);
388
+ if (honeytokenMarker || envEnumMarker) {
389
+ threats.push({
390
+ type: 'analyzer_honeytoken_reference',
391
+ severity: 'CRITICAL',
392
+ message: honeytokenMarker
393
+ ? `${relPath}: obfuscated (base64/hex/charcode) reference to the analysis-environment honeytoken '${honeytokenMarker}' — sandbox-evasion reconnaissance. No legitimate PyPI package encodes a check for this tripwire.`
394
+ : `${relPath}: os.environ enumeration testing keys against a MUADDIB prefix (marker-agnostic) — sandbox/analyzer evasion. No legitimate package scans the environment for this tripwire.`,
395
+ file: relPath
396
+ });
397
+ }
350
398
  }
351
399
 
352
400
  return threats;
@@ -366,6 +414,7 @@ module.exports = {
366
414
  detectBase64Decode,
367
415
  detectDeserialization,
368
416
  detectDynamicDangerousImport,
369
- detectForkExecInlineInterpreter
417
+ detectForkExecInlineInterpreter,
418
+ detectPythonEnvMarkerEnumeration
370
419
  }
371
420
  };