muaddib-scanner 2.10.71 → 2.10.72
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
package/src/monitor/classify.js
CHANGED
|
@@ -179,8 +179,21 @@ function isSuspectClassification(result) {
|
|
|
179
179
|
return { suspect: true, tier: 3 };
|
|
180
180
|
}
|
|
181
181
|
|
|
182
|
-
// 2+ distinct types with non-passive types not in tier 2 active list
|
|
183
|
-
|
|
182
|
+
// Fallback: 2+ distinct types with non-passive types not in tier 2 active list.
|
|
183
|
+
// Previously this returned tier 2 unconditionally, but that was permissive —
|
|
184
|
+
// packages with 2 LOW findings in uncategorized types (e.g., @eeacms/* with
|
|
185
|
+
// score 2 observed 2026-04-11) landed in tier 2 and flooded the deferred
|
|
186
|
+
// sandbox queue, starving legitimate T1b/T2 candidates of the dedicated
|
|
187
|
+
// deferred slot.
|
|
188
|
+
//
|
|
189
|
+
// A sandbox slot is only justified when there is real signal. Require at
|
|
190
|
+
// least one non-LOW finding to reach tier 2 via this fallback — otherwise
|
|
191
|
+
// downgrade to tier 3 (log only, no sandbox consumption).
|
|
192
|
+
const hasNonLowFinding = result.threats.some(t => t.severity !== 'LOW');
|
|
193
|
+
if (hasNonLowFinding) {
|
|
194
|
+
return { suspect: true, tier: 2 };
|
|
195
|
+
}
|
|
196
|
+
return { suspect: true, tier: 3 };
|
|
184
197
|
}
|
|
185
198
|
|
|
186
199
|
/**
|
|
@@ -26,6 +26,12 @@ const DEFERRED_TTL_MS = 24 * 60 * 60 * 1000; // 24h
|
|
|
26
26
|
const DEFERRED_MAX_RETRIES = 2;
|
|
27
27
|
const DEFERRED_WORKER_INTERVAL_MS = 30_000; // 30s
|
|
28
28
|
const DEFERRED_STATE_FILE = path.join(__dirname, '..', '..', 'data', 'deferred-queue.json');
|
|
29
|
+
// Defense-in-depth: sandbox slot is precious. A T1b/T2 below this score
|
|
30
|
+
// threshold is almost certainly a classification fallback false positive
|
|
31
|
+
// (cf. classify.js:183 remediation) and should never consume the deferred
|
|
32
|
+
// slot. HIGH=10 pts is the intended T1b floor — values below 5 are LOW-only
|
|
33
|
+
// aggregates which carry no actionable sandbox signal.
|
|
34
|
+
const DEFERRED_MIN_SCORE = 5;
|
|
29
35
|
|
|
30
36
|
// ── Mutable state ──
|
|
31
37
|
const _deferredQueue = [];
|
|
@@ -51,6 +57,16 @@ function enqueueDeferred(item) {
|
|
|
51
57
|
return false;
|
|
52
58
|
}
|
|
53
59
|
|
|
60
|
+
// Defense-in-depth: block low-score items regardless of tier. With the
|
|
61
|
+
// classify.js:183 fallback fix in place, no legitimate enqueue should
|
|
62
|
+
// reach this function with score < DEFERRED_MIN_SCORE. Logging with
|
|
63
|
+
// console.error makes a future regression (new classification path that
|
|
64
|
+
// leaks low-score items) loud in operator logs.
|
|
65
|
+
if ((item.riskScore || 0) < DEFERRED_MIN_SCORE) {
|
|
66
|
+
console.error(`[DEFERRED] REJECTED: ${item.name}@${item.version} — score=${item.riskScore || 0} below minimum ${DEFERRED_MIN_SCORE} (possible classification regression)`);
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
|
|
54
70
|
const key = `${item.name}@${item.version}`;
|
|
55
71
|
|
|
56
72
|
// Dedup
|