supply-chain-guard 5.2.23 → 5.2.24
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 +25 -0
- package/dist/cli.js +1 -1
- package/dist/reporter.js +4 -4
- package/dist/risk-forecast.d.ts.map +1 -1
- package/dist/risk-forecast.js +48 -3
- package/dist/risk-forecast.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -342,6 +342,31 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines. The most impactful contri
|
|
|
342
342
|
|
|
343
343
|
## Changelog
|
|
344
344
|
|
|
345
|
+
### v5.2.24 (2026-05-24)
|
|
346
|
+
**`RISK_TRAJECTORY_UNSTABLE` no longer flags monotone improvement as instability**
|
|
347
|
+
|
|
348
|
+
The risk-forecast engine used `Math.abs(slope) > 5` to detect "volatile risk", which conflated two opposite situations:
|
|
349
|
+
|
|
350
|
+
- Score rising fast (real degradation) → should fire
|
|
351
|
+
- Score falling fast (active remediation) → should NOT fire, that is exactly what we want
|
|
352
|
+
- Score bouncing back and forth (true volatility) → should fire
|
|
353
|
+
|
|
354
|
+
The v5.2.23 self-scan reported "slope -13.9/scan, highly volatile" after six consecutive releases each fixing real bugs - a strict monotone decrease being labelled as instability.
|
|
355
|
+
|
|
356
|
+
The detection is now split into orthogonal concerns:
|
|
357
|
+
|
|
358
|
+
- `RISK_TRAJECTORY_DEGRADING` (severity high): `slope > +5`, score consistently rising
|
|
359
|
+
- `RISK_TRAJECTORY_UNSTABLE` (severity medium): high stdev around the linear-fit trend **and** at least 2 direction reversals in the sequence (true oscillation, not just non-linear improvement)
|
|
360
|
+
- Fast improvement (`slope < -5` with no oscillation): silent, surfaced in the score itself
|
|
361
|
+
|
|
362
|
+
5 new tests in `bugfix-v5_2_24.test.ts` verify:
|
|
363
|
+
- Strict monotone decrease (including the v5.2.18-v5.2.23 release trajectory) does NOT fire UNSTABLE
|
|
364
|
+
- Fast-rising score DOES fire DEGRADING
|
|
365
|
+
- Real oscillation (e.g. `[20, 80, 25, 75, 30, 70]`) DOES fire UNSTABLE
|
|
366
|
+
- Stable flat trajectory fires neither
|
|
367
|
+
|
|
368
|
+
Expected impact on the self-scan: drops the spurious `RISK_TRAJECTORY_UNSTABLE` finding. Score should fall from 17/MEDIUM to roughly 5-10/LOW.
|
|
369
|
+
|
|
345
370
|
### v5.2.23 (2026-05-24)
|
|
346
371
|
**Fix `WORKFLOW_UNTRUSTED_ACTION_IN_RELEASE_PATH` false positive on `npm@latest`**
|
|
347
372
|
|
package/dist/cli.js
CHANGED
|
@@ -20,7 +20,7 @@ const program = new commander_1.Command();
|
|
|
20
20
|
program
|
|
21
21
|
.name("supply-chain-guard")
|
|
22
22
|
.description("Open-source supply-chain security scanner. Detects GlassWorm and similar malware campaigns in npm packages, PyPI packages, code repos, VS Code extensions, and project dependencies.")
|
|
23
|
-
.version("5.2.
|
|
23
|
+
.version("5.2.24");
|
|
24
24
|
// ── scan command ────────────────────────────────────────────────────
|
|
25
25
|
program
|
|
26
26
|
.command("scan")
|
package/dist/reporter.js
CHANGED
|
@@ -55,7 +55,7 @@ function formatJson(report) {
|
|
|
55
55
|
function formatText(report) {
|
|
56
56
|
const lines = [];
|
|
57
57
|
// ── layout constants ───────────────────────────────────────────────────────
|
|
58
|
-
const VERSION = "5.2.
|
|
58
|
+
const VERSION = "5.2.24";
|
|
59
59
|
const W = 76; // visible chars between "│ " and " │" (total line = 80)
|
|
60
60
|
// ── ANSI helpers ───────────────────────────────────────────────────────────
|
|
61
61
|
const stripAnsi = (s) => s.replace(/\x1b\[[0-9;]*m/g, "");
|
|
@@ -462,7 +462,7 @@ function formatSarif(report) {
|
|
|
462
462
|
tool: {
|
|
463
463
|
driver: {
|
|
464
464
|
name: "supply-chain-guard",
|
|
465
|
-
version: "5.2.
|
|
465
|
+
version: "5.2.24",
|
|
466
466
|
informationUri: "https://github.com/homeofe/supply-chain-guard",
|
|
467
467
|
rules,
|
|
468
468
|
},
|
|
@@ -524,7 +524,7 @@ function formatSbom(report) {
|
|
|
524
524
|
timestamp: report.timestamp,
|
|
525
525
|
tools: {
|
|
526
526
|
components: [
|
|
527
|
-
{ type: "application", name: "supply-chain-guard", version: "5.2.
|
|
527
|
+
{ type: "application", name: "supply-chain-guard", version: "5.2.24" },
|
|
528
528
|
],
|
|
529
529
|
},
|
|
530
530
|
component: {
|
|
@@ -676,7 +676,7 @@ footer{text-align:center;padding:24px;color:#94a3b8;font-size:13px}
|
|
|
676
676
|
` : ""}
|
|
677
677
|
|
|
678
678
|
<footer>
|
|
679
|
-
Generated by <a href="https://github.com/homeofe/supply-chain-guard">supply-chain-guard</a> v5.2.
|
|
679
|
+
Generated by <a href="https://github.com/homeofe/supply-chain-guard">supply-chain-guard</a> v5.2.24
|
|
680
680
|
</footer>
|
|
681
681
|
</div>
|
|
682
682
|
<script>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"risk-forecast.d.ts","sourceRoot":"","sources":["../src/risk-forecast.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE5D;;GAEG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,gBAAgB,EAAE,EAC3B,YAAY,EAAE,MAAM,GACnB,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"risk-forecast.d.ts","sourceRoot":"","sources":["../src/risk-forecast.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE5D;;GAEG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,gBAAgB,EAAE,EAC3B,YAAY,EAAE,MAAM,GACnB,OAAO,EAAE,CA6FX"}
|
package/dist/risk-forecast.js
CHANGED
|
@@ -38,14 +38,59 @@ function forecastRisk(history, currentScore) {
|
|
|
38
38
|
recommendation: "Risk trajectory is heading toward critical. Proactive remediation recommended now.",
|
|
39
39
|
});
|
|
40
40
|
}
|
|
41
|
-
|
|
41
|
+
// v5.2.24: split trajectory analysis into direction (slope sign) and
|
|
42
|
+
// volatility (residuals from the linear fit). Previously a single
|
|
43
|
+
// |slope| > 5 check flagged "unstable" both for runaway-bad trends and
|
|
44
|
+
// for fast-improving trends - the latter is the opposite of unstable.
|
|
45
|
+
// The self-scan on v5.2.23 reported -13.9/scan as "highly volatile"
|
|
46
|
+
// even though every release that day strictly improved the score.
|
|
47
|
+
// Compute stdev of residuals from the linear regression line.
|
|
48
|
+
// High stdev means the score bounces unpredictably around the trend.
|
|
49
|
+
let sumSq = 0;
|
|
50
|
+
for (let i = 0; i < n; i++) {
|
|
51
|
+
const predicted = yMean + slope * (i - xMean);
|
|
52
|
+
const residual = recent[i].score - predicted;
|
|
53
|
+
sumSq += residual * residual;
|
|
54
|
+
}
|
|
55
|
+
const stdev = Math.sqrt(sumSq / n);
|
|
56
|
+
if (slope > 5) {
|
|
57
|
+
// Getting worse fast - real degradation worth flagging.
|
|
58
|
+
findings.push({
|
|
59
|
+
rule: "RISK_TRAJECTORY_DEGRADING",
|
|
60
|
+
description: `Risk score is rising fast (slope: +${slope.toFixed(1)}/scan). Security posture is worsening over the last ${n} scans.`,
|
|
61
|
+
severity: "high",
|
|
62
|
+
confidence: 0.6,
|
|
63
|
+
category: "trust",
|
|
64
|
+
recommendation: "Investigate the cause of the upward trend. Recent commits, dependency updates, or new findings should be triaged immediately.",
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
// Fast-improving trend (slope < -5) emits no finding - it is the
|
|
68
|
+
// outcome we want, surfaced silently in the score itself.
|
|
69
|
+
// Count direction changes in the sequence. A monotonic sequence (always
|
|
70
|
+
// dropping or always rising) has 0 direction changes even if the rate is
|
|
71
|
+
// non-linear (e.g. flat then a knee). True volatility requires the score
|
|
72
|
+
// to actually reverse direction, not just decelerate or accelerate.
|
|
73
|
+
let directionChanges = 0;
|
|
74
|
+
let lastDelta = 0;
|
|
75
|
+
for (let i = 1; i < n; i++) {
|
|
76
|
+
const delta = recent[i].score - recent[i - 1].score;
|
|
77
|
+
if (lastDelta !== 0 && delta !== 0 && Math.sign(delta) !== Math.sign(lastDelta)) {
|
|
78
|
+
directionChanges++;
|
|
79
|
+
}
|
|
80
|
+
if (delta !== 0)
|
|
81
|
+
lastDelta = delta;
|
|
82
|
+
}
|
|
83
|
+
if (stdev > 10 && directionChanges >= 2) {
|
|
84
|
+
// True volatility: high residuals AND multiple direction reversals.
|
|
85
|
+
// The score bounces back and forth instead of moving consistently
|
|
86
|
+
// in one direction. This is what "unstable" was meant to detect.
|
|
42
87
|
findings.push({
|
|
43
88
|
rule: "RISK_TRAJECTORY_UNSTABLE",
|
|
44
|
-
description: `Risk score is
|
|
89
|
+
description: `Risk score is volatile (stdev ${stdev.toFixed(1)} around trend, ${directionChanges} direction reversals). Score bounces unpredictably across scans.`,
|
|
45
90
|
severity: "medium",
|
|
46
91
|
confidence: 0.5,
|
|
47
92
|
category: "trust",
|
|
48
|
-
recommendation: "Stabilize risk by implementing consistent policies and baseline enforcement.",
|
|
93
|
+
recommendation: "Stabilize risk by implementing consistent policies and baseline enforcement. Investigate why scores fluctuate.",
|
|
49
94
|
});
|
|
50
95
|
}
|
|
51
96
|
return findings;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"risk-forecast.js","sourceRoot":"","sources":["../src/risk-forecast.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;AAOH,
|
|
1
|
+
{"version":3,"file":"risk-forecast.js","sourceRoot":"","sources":["../src/risk-forecast.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "supply-chain-guard",
|
|
3
|
-
"version": "5.2.
|
|
3
|
+
"version": "5.2.24",
|
|
4
4
|
"description": "Open-source supply-chain security scanner for npm, PyPI, Cargo, Go, Docker, VS Code extensions, GitHub Actions, IaC and Solana C2. Detects GlassWorm, Shai-Hulud, PPE attacks, dependency confusion and 120+ malware indicators. Generates CycloneDX 1.6 SBOMs and verifies SLSA provenance.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|