muaddib-scanner 2.7.7 → 2.7.8

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.7.7",
3
+ "version": "2.7.8",
4
4
  "description": "Supply-chain threat detection & response for npm & PyPI/Python",
5
5
  "main": "src/index.js",
6
6
  "bin": {
package/src/index.js CHANGED
@@ -555,18 +555,21 @@ async function run(targetPath, options = {}) {
555
555
  }
556
556
  }
557
557
 
558
- // Read package name for benign package whitelist
558
+ // Read package name and dependencies for FP reduction heuristics
559
559
  let packageName = null;
560
+ let packageDeps = null;
560
561
  try {
561
562
  const pkgPath = path.join(targetPath, 'package.json');
562
563
  if (fs.existsSync(pkgPath)) {
563
- packageName = JSON.parse(fs.readFileSync(pkgPath, 'utf8')).name || null;
564
+ const pkgData = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
565
+ packageName = pkgData.name || null;
566
+ packageDeps = pkgData.dependencies || null;
564
567
  }
565
568
  } catch { /* graceful fallback */ }
566
569
 
567
570
  // FP reduction: legitimate frameworks produce high volumes of certain threat types.
568
571
  // A malware package typically has 1-3 occurrences, not dozens.
569
- applyFPReductions(deduped, reachableFiles, packageName);
572
+ applyFPReductions(deduped, reachableFiles, packageName, packageDeps);
570
573
 
571
574
  // Intent coherence analysis: detect source→sink pairs within files
572
575
  // Pass targetPath for destination-aware SDK pattern detection
package/src/scoring.js CHANGED
@@ -197,7 +197,7 @@ const FRAMEWORK_PROTO_RE = new RegExp(
197
197
  '^(' + FRAMEWORK_PROTOTYPES.join('|') + ')\\.prototype\\.'
198
198
  );
199
199
 
200
- function applyFPReductions(threats, reachableFiles, packageName) {
200
+ function applyFPReductions(threats, reachableFiles, packageName, packageDeps) {
201
201
  // Count occurrences of each threat type (package-level, across all files)
202
202
  const typeCounts = {};
203
203
  for (const t of threats) {
@@ -304,6 +304,17 @@ function applyFPReductions(threats, reachableFiles, packageName) {
304
304
  t.unreachable = true;
305
305
  }
306
306
  }
307
+
308
+ // C2: MCP server awareness — legitimate MCP servers write to MCP config files.
309
+ // Downgrade mcp_config_injection to MEDIUM when @modelcontextprotocol/sdk is in dependencies.
310
+ // Only dependencies (not devDependencies) — a real MCP server must ship the SDK.
311
+ // High-confidence compound types stay untouched (lifecycle_shell_pipe, fetch_decrypt_exec, etc.)
312
+ if (t.type === 'mcp_config_injection' && t.severity === 'CRITICAL' &&
313
+ packageDeps && typeof packageDeps === 'object' &&
314
+ packageDeps['@modelcontextprotocol/sdk']) {
315
+ t.severity = 'MEDIUM';
316
+ t.mcpSdkDowngrade = true;
317
+ }
307
318
  }
308
319
  }
309
320