muaddib-scanner 2.11.84 → 2.11.85

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.84",
3
+ "version": "2.11.85",
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-06-10T20:04:48.914Z",
3
+ "timestamp": "2026-06-10T23:09:20.823Z",
4
4
  "threats": [
5
5
  {
6
6
  "type": "string_mutation_obfuscation",
@@ -468,13 +468,20 @@ function findDependencyBoundarySquat(name) {
468
468
  if (!extra.includes('-') && LEGIT_BOUNDARY_TOKENS.has(extra)) continue;
469
469
  return { original: POPULAR_PACKAGES[i], type: 'boundary_squat', distance: extra.length, extra };
470
470
  } else {
471
- // Single-token popular: must appear as a full hyphen-bounded token in name
471
+ // Single-token popular. A SQUAT impersonates by putting the popular name as the
472
+ // TRAILING token (`<deceptive-prefix>-<popular>`, e.g. evil-lodash). The
473
+ // npm-dominant `<popular>-<feature>` convention (react-native-gesture-handler,
474
+ // redux-thunk, glob-parent, async-mutex) is legitimate and must NOT be flagged.
475
+ // FPR audit (2026-06, 200-pkg adjudication): matching the popular token in PREFIX
476
+ // or MIDDLE position made dependency_typosquat ~100% FP on the React-Native and
477
+ // Redux ecosystems — so we only match the SUFFIX position. A genuinely malicious
478
+ // `<popular>-<evil>` is caught by its code (exfil/RCE) + the Track-R malice floor,
479
+ // not by name shape. Supersedes the earlier react-prefix heuristic.
472
480
  const tokens = lower.split('-');
473
- const idx = tokens.indexOf(popular);
474
- if (idx === -1) continue;
475
481
  if (tokens.length === 1) continue;
476
- const siblings = tokens.filter((_, j) => j !== idx);
477
- // If all siblings are legit boundary tokens → benign variant (e.g. react-router)
482
+ if (tokens[tokens.length - 1] !== popular) continue; // popular must be the trailing token
483
+ const siblings = tokens.slice(0, -1);
484
+ // Benign ecosystem variant if every prefix token is a legit qualifier (ts-jest, babel-jest).
478
485
  if (siblings.every(t => LEGIT_BOUNDARY_TOKENS.has(t) || isLegitimateVariant(t))) continue;
479
486
  const extra = siblings.join('-');
480
487
  return { original: POPULAR_PACKAGES[i], type: 'boundary_squat', distance: extra.length, extra };