@cyclonedx/cdxgen 12.3.0 → 12.3.2
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 +15 -5
- package/bin/audit.js +7 -0
- package/bin/cdxgen.js +241 -81
- package/bin/repl.js +138 -0
- package/data/rules/ai-agent-governance.yaml +249 -0
- package/data/rules/dependency-sources.yaml +41 -0
- package/data/rules/mcp-servers.yaml +304 -0
- package/data/rules/package-integrity.yaml +123 -0
- package/lib/audit/index.js +353 -29
- package/lib/audit/index.poku.js +247 -7
- package/lib/audit/reporters.js +26 -0
- package/lib/audit/scoring.js +262 -13
- package/lib/audit/scoring.poku.js +179 -0
- package/lib/audit/targets.js +391 -2
- package/lib/audit/targets.poku.js +416 -3
- package/lib/cli/index.js +588 -45
- package/lib/cli/index.poku.js +735 -1
- package/lib/evinser/evinser.js +8 -5
- package/lib/helpers/agentFormulationParser.js +318 -0
- package/lib/helpers/aiInventory.js +262 -0
- package/lib/helpers/aiInventory.poku.js +111 -0
- package/lib/helpers/analyzer.js +1769 -0
- package/lib/helpers/analyzer.poku.js +284 -3
- package/lib/helpers/auditCategories.js +76 -0
- package/lib/helpers/ciParsers/githubActions.js +140 -16
- package/lib/helpers/ciParsers/githubActions.poku.js +110 -0
- package/lib/helpers/communityAiConfigParser.js +672 -0
- package/lib/helpers/communityAiConfigParser.poku.js +63 -0
- package/lib/helpers/depsUtils.js +108 -0
- package/lib/helpers/depsUtils.poku.js +72 -1
- package/lib/helpers/display.js +325 -3
- package/lib/helpers/display.poku.js +301 -0
- package/lib/helpers/formulationParsers.js +28 -0
- package/lib/helpers/formulationParsers.poku.js +504 -1
- package/lib/helpers/jsonLike.js +102 -0
- package/lib/helpers/jsonLike.poku.js +34 -0
- package/lib/helpers/mcp.js +248 -0
- package/lib/helpers/mcp.poku.js +101 -0
- package/lib/helpers/mcpConfigParser.js +656 -0
- package/lib/helpers/mcpConfigParser.poku.js +126 -0
- package/lib/helpers/mcpDiscovery.js +84 -0
- package/lib/helpers/mcpDiscovery.poku.js +21 -0
- package/lib/helpers/protobom.js +3 -3
- package/lib/helpers/provenanceUtils.js +29 -4
- package/lib/helpers/provenanceUtils.poku.js +29 -3
- package/lib/helpers/registryProvenance.js +210 -0
- package/lib/helpers/registryProvenance.poku.js +144 -0
- package/lib/helpers/rustFormulationParser.js +330 -0
- package/lib/helpers/source.js +21 -2
- package/lib/helpers/source.poku.js +38 -0
- package/lib/helpers/utils.js +1331 -83
- package/lib/helpers/utils.poku.js +599 -188
- package/lib/helpers/vsixutils.js +12 -4
- package/lib/helpers/vsixutils.poku.js +34 -0
- package/lib/managers/binary.js +36 -12
- package/lib/managers/binary.poku.js +68 -0
- package/lib/managers/docker.js +59 -9
- package/lib/managers/docker.poku.js +61 -0
- package/lib/managers/piptree.js +12 -7
- package/lib/managers/piptree.poku.js +44 -0
- package/lib/stages/postgen/annotator.js +2 -1
- package/lib/stages/postgen/annotator.poku.js +15 -0
- package/lib/stages/postgen/auditBom.js +20 -6
- package/lib/stages/postgen/auditBom.poku.js +694 -1
- package/lib/stages/postgen/postgen.js +262 -11
- package/lib/stages/postgen/postgen.poku.js +306 -2
- package/lib/stages/postgen/ruleEngine.js +49 -1
- package/lib/stages/postgen/spdxConverter.poku.js +70 -0
- package/lib/stages/pregen/pregen.js +6 -4
- package/package.json +1 -1
- package/types/bin/repl.d.ts.map +1 -1
- package/types/lib/audit/index.d.ts.map +1 -1
- package/types/lib/audit/reporters.d.ts.map +1 -1
- package/types/lib/audit/scoring.d.ts.map +1 -1
- package/types/lib/audit/targets.d.ts +12 -0
- package/types/lib/audit/targets.d.ts.map +1 -1
- package/types/lib/cli/index.d.ts +2 -8
- package/types/lib/cli/index.d.ts.map +1 -1
- package/types/lib/evinser/evinser.d.ts.map +1 -1
- package/types/lib/helpers/agentFormulationParser.d.ts +19 -0
- package/types/lib/helpers/agentFormulationParser.d.ts.map +1 -0
- package/types/lib/helpers/aiInventory.d.ts +23 -0
- package/types/lib/helpers/aiInventory.d.ts.map +1 -0
- package/types/lib/helpers/analyzer.d.ts +10 -0
- package/types/lib/helpers/analyzer.d.ts.map +1 -1
- package/types/lib/helpers/auditCategories.d.ts +12 -0
- package/types/lib/helpers/auditCategories.d.ts.map +1 -0
- package/types/lib/helpers/ciParsers/githubActions.d.ts.map +1 -1
- package/types/lib/helpers/communityAiConfigParser.d.ts +29 -0
- package/types/lib/helpers/communityAiConfigParser.d.ts.map +1 -0
- package/types/lib/helpers/depsUtils.d.ts +8 -0
- package/types/lib/helpers/depsUtils.d.ts.map +1 -1
- package/types/lib/helpers/display.d.ts +17 -1
- package/types/lib/helpers/display.d.ts.map +1 -1
- package/types/lib/helpers/formulationParsers.d.ts.map +1 -1
- package/types/lib/helpers/jsonLike.d.ts +4 -0
- package/types/lib/helpers/jsonLike.d.ts.map +1 -0
- package/types/lib/helpers/mcp.d.ts +29 -0
- package/types/lib/helpers/mcp.d.ts.map +1 -0
- package/types/lib/helpers/mcpConfigParser.d.ts +30 -0
- package/types/lib/helpers/mcpConfigParser.d.ts.map +1 -0
- package/types/lib/helpers/mcpDiscovery.d.ts +5 -0
- package/types/lib/helpers/mcpDiscovery.d.ts.map +1 -0
- package/types/lib/helpers/provenanceUtils.d.ts +5 -3
- package/types/lib/helpers/provenanceUtils.d.ts.map +1 -1
- package/types/lib/helpers/registryProvenance.d.ts +9 -0
- package/types/lib/helpers/registryProvenance.d.ts.map +1 -1
- package/types/lib/helpers/rustFormulationParser.d.ts +17 -0
- package/types/lib/helpers/rustFormulationParser.d.ts.map +1 -0
- package/types/lib/helpers/source.d.ts.map +1 -1
- package/types/lib/helpers/utils.d.ts +31 -1
- package/types/lib/helpers/utils.d.ts.map +1 -1
- package/types/lib/helpers/vsixutils.d.ts.map +1 -1
- package/types/lib/managers/binary.d.ts.map +1 -1
- package/types/lib/managers/docker.d.ts.map +1 -1
- package/types/lib/managers/piptree.d.ts.map +1 -1
- package/types/lib/stages/postgen/annotator.d.ts.map +1 -1
- package/types/lib/stages/postgen/auditBom.d.ts.map +1 -1
- package/types/lib/stages/postgen/postgen.d.ts.map +1 -1
- package/types/lib/stages/postgen/ruleEngine.d.ts.map +1 -1
- package/types/lib/stages/pregen/pregen.d.ts.map +1 -1
package/lib/audit/index.poku.js
CHANGED
|
@@ -170,6 +170,7 @@ describe("runAuditFromBoms()", () => {
|
|
|
170
170
|
{
|
|
171
171
|
maxTargets: 50,
|
|
172
172
|
onProgress: (event) => progressEvents.push(event),
|
|
173
|
+
prioritizeDirectRuntime: true,
|
|
173
174
|
scope: "required",
|
|
174
175
|
trustedSelectionHelp:
|
|
175
176
|
"Use --include-trusted to include them or --only-trusted to audit just those packages.",
|
|
@@ -179,6 +180,7 @@ describe("runAuditFromBoms()", () => {
|
|
|
179
180
|
assert.strictEqual(report.summary.totalTargets, 1);
|
|
180
181
|
assert.deepStrictEqual(collectAuditTargetsStub.firstCall.args[1], {
|
|
181
182
|
maxTargets: 50,
|
|
183
|
+
prioritizeDirectRuntime: true,
|
|
182
184
|
scope: "required",
|
|
183
185
|
trusted: undefined,
|
|
184
186
|
});
|
|
@@ -318,6 +320,43 @@ describe("finalizeAuditReport()", () => {
|
|
|
318
320
|
assert.match(finalized.output, /@npmcli/);
|
|
319
321
|
});
|
|
320
322
|
|
|
323
|
+
it("does not treat target analysis errors as fail-threshold hits on their own", () => {
|
|
324
|
+
const finalized = finalizeAuditReport(
|
|
325
|
+
{
|
|
326
|
+
results: [
|
|
327
|
+
{
|
|
328
|
+
assessment: {
|
|
329
|
+
severity: "critical",
|
|
330
|
+
},
|
|
331
|
+
error: "Unable to clone repository.",
|
|
332
|
+
findings: [],
|
|
333
|
+
status: "error",
|
|
334
|
+
target: {
|
|
335
|
+
name: "left-pad",
|
|
336
|
+
type: "npm",
|
|
337
|
+
},
|
|
338
|
+
},
|
|
339
|
+
],
|
|
340
|
+
summary: {
|
|
341
|
+
analysisErrorCounts: { clone: 1 },
|
|
342
|
+
erroredTargets: 1,
|
|
343
|
+
inputBomCount: 1,
|
|
344
|
+
scannedTargets: 0,
|
|
345
|
+
skippedTargets: 0,
|
|
346
|
+
totalTargets: 1,
|
|
347
|
+
},
|
|
348
|
+
},
|
|
349
|
+
{
|
|
350
|
+
failSeverity: "high",
|
|
351
|
+
minSeverity: "low",
|
|
352
|
+
report: "console",
|
|
353
|
+
},
|
|
354
|
+
);
|
|
355
|
+
|
|
356
|
+
assert.strictEqual(finalized.exitCode, 0);
|
|
357
|
+
assert.match(finalized.output, /analysis error types: clone: 1/i);
|
|
358
|
+
});
|
|
359
|
+
|
|
321
360
|
it("renders grouped predictive findings as SARIF 2.1.0 output", () => {
|
|
322
361
|
const finalized = finalizeAuditReport(
|
|
323
362
|
{
|
|
@@ -363,7 +402,7 @@ describe("finalizeAuditReport()", () => {
|
|
|
363
402
|
},
|
|
364
403
|
tool: {
|
|
365
404
|
name: "cdx-audit",
|
|
366
|
-
version: "12.3.
|
|
405
|
+
version: "12.3.1",
|
|
367
406
|
},
|
|
368
407
|
},
|
|
369
408
|
{
|
|
@@ -377,7 +416,7 @@ describe("finalizeAuditReport()", () => {
|
|
|
377
416
|
assert.strictEqual(finalized.exitCode, 0);
|
|
378
417
|
assert.strictEqual(parsed.version, "2.1.0");
|
|
379
418
|
assert.strictEqual(parsed.runs[0].tool.driver.name, "cdx-audit");
|
|
380
|
-
assert.strictEqual(parsed.runs[0].tool.driver.version, "12.3.
|
|
419
|
+
assert.strictEqual(parsed.runs[0].tool.driver.version, "12.3.1");
|
|
381
420
|
assert.strictEqual(parsed.runs[0].results.length, 1);
|
|
382
421
|
assert.strictEqual(parsed.runs[0].results[0].ruleId, "PROV-001");
|
|
383
422
|
assert.strictEqual(
|
|
@@ -421,7 +460,7 @@ describe("finalizeAuditReport()", () => {
|
|
|
421
460
|
},
|
|
422
461
|
tool: {
|
|
423
462
|
name: "cdx-audit",
|
|
424
|
-
version: "12.3.
|
|
463
|
+
version: "12.3.1",
|
|
425
464
|
},
|
|
426
465
|
},
|
|
427
466
|
{
|
|
@@ -483,7 +522,7 @@ describe("finalizeAuditReport()", () => {
|
|
|
483
522
|
},
|
|
484
523
|
tool: {
|
|
485
524
|
name: "cdx-audit",
|
|
486
|
-
version: "12.3.
|
|
525
|
+
version: "12.3.1",
|
|
487
526
|
},
|
|
488
527
|
},
|
|
489
528
|
{
|
|
@@ -750,6 +789,165 @@ describe("groupAuditResults()", () => {
|
|
|
750
789
|
assert.strictEqual(groupedResults[0].grouping?.memberCount, 2);
|
|
751
790
|
assert.strictEqual(groupedResults[1].target.name, "string-locale-compare");
|
|
752
791
|
});
|
|
792
|
+
|
|
793
|
+
it("consolidates shared-repository CI findings across multiple packages", () => {
|
|
794
|
+
const groupedResults = groupAuditResults([
|
|
795
|
+
{
|
|
796
|
+
assessment: {
|
|
797
|
+
categoryCounts: {
|
|
798
|
+
"ci-permission": 2,
|
|
799
|
+
},
|
|
800
|
+
confidenceLabel: "high",
|
|
801
|
+
reasons: ["CI hygiene signals were observed."],
|
|
802
|
+
score: 42,
|
|
803
|
+
severity: "medium",
|
|
804
|
+
},
|
|
805
|
+
findings: [
|
|
806
|
+
{
|
|
807
|
+
category: "ci-permission",
|
|
808
|
+
location: {
|
|
809
|
+
file: ".github/workflows/release.yml",
|
|
810
|
+
},
|
|
811
|
+
message: "Unpinned privileged action",
|
|
812
|
+
ruleId: "CI-001",
|
|
813
|
+
},
|
|
814
|
+
],
|
|
815
|
+
repoUrl: "https://github.com/example/mono.git",
|
|
816
|
+
status: "audited",
|
|
817
|
+
target: {
|
|
818
|
+
bomRefs: ["pkg:npm/pkg-a@1.0.0"],
|
|
819
|
+
name: "pkg-a",
|
|
820
|
+
namespace: "@acme",
|
|
821
|
+
purl: "pkg:npm/%40acme/pkg-a@1.0.0",
|
|
822
|
+
type: "npm",
|
|
823
|
+
version: "1.0.0",
|
|
824
|
+
},
|
|
825
|
+
},
|
|
826
|
+
{
|
|
827
|
+
assessment: {
|
|
828
|
+
categoryCounts: {
|
|
829
|
+
"ci-permission": 2,
|
|
830
|
+
},
|
|
831
|
+
confidenceLabel: "high",
|
|
832
|
+
reasons: ["CI hygiene signals were observed."],
|
|
833
|
+
score: 42,
|
|
834
|
+
severity: "medium",
|
|
835
|
+
},
|
|
836
|
+
findings: [
|
|
837
|
+
{
|
|
838
|
+
category: "ci-permission",
|
|
839
|
+
location: {
|
|
840
|
+
file: ".github/workflows/release.yml",
|
|
841
|
+
},
|
|
842
|
+
message: "Unpinned privileged action",
|
|
843
|
+
ruleId: "CI-001",
|
|
844
|
+
},
|
|
845
|
+
],
|
|
846
|
+
repoUrl: "https://github.com/example/mono",
|
|
847
|
+
status: "audited",
|
|
848
|
+
target: {
|
|
849
|
+
bomRefs: ["pkg:npm/pkg-b@1.0.0"],
|
|
850
|
+
name: "pkg-b",
|
|
851
|
+
namespace: "@acme",
|
|
852
|
+
purl: "pkg:npm/%40acme/pkg-b@1.0.0",
|
|
853
|
+
type: "npm",
|
|
854
|
+
version: "1.0.0",
|
|
855
|
+
},
|
|
856
|
+
},
|
|
857
|
+
]);
|
|
858
|
+
|
|
859
|
+
assert.strictEqual(groupedResults.length, 1);
|
|
860
|
+
assert.strictEqual(groupedResults[0].grouping?.kind, "shared-repo-ci");
|
|
861
|
+
assert.strictEqual(groupedResults[0].grouping?.memberCount, 2);
|
|
862
|
+
assert.strictEqual(groupedResults[0].findings.length, 1);
|
|
863
|
+
assert.match(
|
|
864
|
+
groupedResults[0].assessment.reasons.join(" "),
|
|
865
|
+
/same repository/i,
|
|
866
|
+
);
|
|
867
|
+
});
|
|
868
|
+
|
|
869
|
+
it("consolidates Cargo repository findings with the same predictive pattern", () => {
|
|
870
|
+
const groupedResults = groupAuditResults([
|
|
871
|
+
{
|
|
872
|
+
assessment: {
|
|
873
|
+
categoryCounts: {
|
|
874
|
+
"dependency-source": 1,
|
|
875
|
+
"package-integrity": 1,
|
|
876
|
+
},
|
|
877
|
+
confidenceLabel: "high",
|
|
878
|
+
reasons: ["Cargo build-surface signals increased review priority."],
|
|
879
|
+
score: 61,
|
|
880
|
+
severity: "high",
|
|
881
|
+
},
|
|
882
|
+
findings: [
|
|
883
|
+
{
|
|
884
|
+
category: "dependency-source",
|
|
885
|
+
message: "Mutable source for workspace build dependency",
|
|
886
|
+
ruleId: "PKG-001",
|
|
887
|
+
},
|
|
888
|
+
{
|
|
889
|
+
category: "package-integrity",
|
|
890
|
+
message: "Crate was yanked from the registry",
|
|
891
|
+
ruleId: "PROV-015",
|
|
892
|
+
},
|
|
893
|
+
],
|
|
894
|
+
repoUrl: "https://github.com/example/rust-mono.git",
|
|
895
|
+
status: "audited",
|
|
896
|
+
target: {
|
|
897
|
+
bomRefs: ["pkg:cargo/core-crate@1.2.3"],
|
|
898
|
+
name: "core-crate",
|
|
899
|
+
purl: "pkg:cargo/core-crate@1.2.3",
|
|
900
|
+
type: "cargo",
|
|
901
|
+
version: "1.2.3",
|
|
902
|
+
},
|
|
903
|
+
},
|
|
904
|
+
{
|
|
905
|
+
assessment: {
|
|
906
|
+
categoryCounts: {
|
|
907
|
+
"dependency-source": 1,
|
|
908
|
+
"package-integrity": 1,
|
|
909
|
+
},
|
|
910
|
+
confidenceLabel: "high",
|
|
911
|
+
reasons: ["Cargo build-surface signals increased review priority."],
|
|
912
|
+
score: 59,
|
|
913
|
+
severity: "high",
|
|
914
|
+
},
|
|
915
|
+
findings: [
|
|
916
|
+
{
|
|
917
|
+
category: "dependency-source",
|
|
918
|
+
message: "Mutable source for workspace build dependency",
|
|
919
|
+
ruleId: "PKG-001",
|
|
920
|
+
},
|
|
921
|
+
{
|
|
922
|
+
category: "package-integrity",
|
|
923
|
+
message: "Crate was yanked from the registry",
|
|
924
|
+
ruleId: "PROV-015",
|
|
925
|
+
},
|
|
926
|
+
],
|
|
927
|
+
repoUrl: "https://github.com/example/rust-mono",
|
|
928
|
+
status: "audited",
|
|
929
|
+
target: {
|
|
930
|
+
bomRefs: ["pkg:cargo/cli-crate@1.2.3"],
|
|
931
|
+
name: "cli-crate",
|
|
932
|
+
purl: "pkg:cargo/cli-crate@1.2.3",
|
|
933
|
+
type: "cargo",
|
|
934
|
+
version: "1.2.3",
|
|
935
|
+
},
|
|
936
|
+
},
|
|
937
|
+
]);
|
|
938
|
+
|
|
939
|
+
assert.strictEqual(groupedResults.length, 1);
|
|
940
|
+
assert.strictEqual(groupedResults[0].grouping?.kind, "cargo-repository");
|
|
941
|
+
assert.strictEqual(groupedResults[0].grouping?.memberCount, 2);
|
|
942
|
+
assert.match(
|
|
943
|
+
groupedResults[0].grouping?.label,
|
|
944
|
+
/^cargo:https:\/\/github.com/,
|
|
945
|
+
);
|
|
946
|
+
assert.match(
|
|
947
|
+
groupedResults[0].assessment.reasons.join(" "),
|
|
948
|
+
/Cargo packages resolved to the same repository/i,
|
|
949
|
+
);
|
|
950
|
+
});
|
|
753
951
|
});
|
|
754
952
|
|
|
755
953
|
describe("buildTargetContextFindings()", () => {
|
|
@@ -1083,6 +1281,48 @@ describe("buildTargetContextFindings()", () => {
|
|
|
1083
1281
|
assert.ok(findings.some((finding) => finding.ruleId === "PROV-014"));
|
|
1084
1282
|
assert.ok(!findings.some((finding) => finding.ruleId === "PROV-009"));
|
|
1085
1283
|
});
|
|
1284
|
+
|
|
1285
|
+
it("creates yanked and provenance-aware drift detectors for Cargo packages", () => {
|
|
1286
|
+
const recentTimestamp = new Date(
|
|
1287
|
+
Date.now() - 1000 * 60 * 60 * 12,
|
|
1288
|
+
).toISOString();
|
|
1289
|
+
const oldTimestamp = new Date(
|
|
1290
|
+
Date.now() - 1000 * 60 * 60 * 24 * 120,
|
|
1291
|
+
).toISOString();
|
|
1292
|
+
const findings = buildTargetContextFindings({
|
|
1293
|
+
bomRefs: ["pkg:cargo/serde@1.0.217"],
|
|
1294
|
+
name: "serde",
|
|
1295
|
+
purl: "pkg:cargo/serde@1.0.217",
|
|
1296
|
+
properties: [
|
|
1297
|
+
{
|
|
1298
|
+
name: "cdx:cargo:yanked",
|
|
1299
|
+
value: "true",
|
|
1300
|
+
},
|
|
1301
|
+
{
|
|
1302
|
+
name: "cdx:cargo:publishTime",
|
|
1303
|
+
value: recentTimestamp,
|
|
1304
|
+
},
|
|
1305
|
+
{
|
|
1306
|
+
name: "cdx:cargo:packageCreatedTime",
|
|
1307
|
+
value: oldTimestamp,
|
|
1308
|
+
},
|
|
1309
|
+
{
|
|
1310
|
+
name: "cdx:cargo:versionCount",
|
|
1311
|
+
value: "10",
|
|
1312
|
+
},
|
|
1313
|
+
{
|
|
1314
|
+
name: "cdx:cargo:publisherDrift",
|
|
1315
|
+
value: "true",
|
|
1316
|
+
},
|
|
1317
|
+
],
|
|
1318
|
+
type: "cargo",
|
|
1319
|
+
version: "1.0.217",
|
|
1320
|
+
});
|
|
1321
|
+
|
|
1322
|
+
assert.ok(findings.some((finding) => finding.ruleId === "PROV-015"));
|
|
1323
|
+
assert.ok(findings.some((finding) => finding.ruleId === "PROV-016"));
|
|
1324
|
+
assert.ok(findings.some((finding) => finding.ruleId === "PROV-017"));
|
|
1325
|
+
});
|
|
1086
1326
|
});
|
|
1087
1327
|
|
|
1088
1328
|
describe("buildPythonSourceHeuristicFindings()", () => {
|
|
@@ -1242,7 +1482,7 @@ describe("formatPredictiveAnnotations()", () => {
|
|
|
1242
1482
|
{
|
|
1243
1483
|
name: "cdxgen",
|
|
1244
1484
|
type: "application",
|
|
1245
|
-
version: "12.3.
|
|
1485
|
+
version: "12.3.1",
|
|
1246
1486
|
},
|
|
1247
1487
|
],
|
|
1248
1488
|
},
|
|
@@ -1306,7 +1546,7 @@ describe("formatPredictiveAnnotations()", () => {
|
|
|
1306
1546
|
{
|
|
1307
1547
|
name: "cdxgen",
|
|
1308
1548
|
type: "application",
|
|
1309
|
-
version: "12.3.
|
|
1549
|
+
version: "12.3.1",
|
|
1310
1550
|
},
|
|
1311
1551
|
],
|
|
1312
1552
|
},
|
|
@@ -1380,7 +1620,7 @@ describe("audit reporters", () => {
|
|
|
1380
1620
|
},
|
|
1381
1621
|
tool: {
|
|
1382
1622
|
name: "cdx-audit",
|
|
1383
|
-
version: "12.3.
|
|
1623
|
+
version: "12.3.1",
|
|
1384
1624
|
},
|
|
1385
1625
|
};
|
|
1386
1626
|
|
package/lib/audit/reporters.js
CHANGED
|
@@ -27,6 +27,17 @@ function effectiveResults(report) {
|
|
|
27
27
|
: report.results || [];
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
function formatAnalysisErrorCounts(summary) {
|
|
31
|
+
const entries = Object.entries(summary?.analysisErrorCounts || {});
|
|
32
|
+
if (!entries.length) {
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
return entries
|
|
36
|
+
.sort(([left], [right]) => left.localeCompare(right))
|
|
37
|
+
.map(([errorType, count]) => `${errorType}: ${count}`)
|
|
38
|
+
.join(", ");
|
|
39
|
+
}
|
|
40
|
+
|
|
30
41
|
function severityToSarifLevel(severity) {
|
|
31
42
|
switch (severity) {
|
|
32
43
|
case "critical":
|
|
@@ -488,6 +499,10 @@ export function renderConsoleReport(report, options = {}) {
|
|
|
488
499
|
lines.push(`Scanned targets: ${report.summary.scannedTargets}`);
|
|
489
500
|
lines.push(`Errored targets: ${report.summary.erroredTargets}`);
|
|
490
501
|
lines.push(`Skipped targets: ${report.summary.skippedTargets}`);
|
|
502
|
+
const analysisErrorSummary = formatAnalysisErrorCounts(report.summary);
|
|
503
|
+
if (analysisErrorSummary) {
|
|
504
|
+
lines.push(`Analysis error types: ${analysisErrorSummary}`);
|
|
505
|
+
}
|
|
491
506
|
if (report.summary.groupedResultCount) {
|
|
492
507
|
lines.push(
|
|
493
508
|
`Consolidated alert groups: ${report.summary.groupedResultCount}`,
|
|
@@ -499,12 +514,23 @@ export function renderConsoleReport(report, options = {}) {
|
|
|
499
514
|
lines.push(
|
|
500
515
|
`No predictive findings met or exceeded the configured severity threshold ('${minSeverity}').`,
|
|
501
516
|
);
|
|
517
|
+
if (report.summary.erroredTargets > 0) {
|
|
518
|
+
lines.push(
|
|
519
|
+
"Some targets could not be fully analyzed, so review the recorded analysis errors before treating this rollup as complete.",
|
|
520
|
+
);
|
|
521
|
+
}
|
|
502
522
|
return `${lines.join("\n")}\n`;
|
|
503
523
|
}
|
|
504
524
|
lines.push("Dependencies requiring your attention:");
|
|
505
525
|
lines.push("");
|
|
506
526
|
lines.push(renderActionTable(visibleResults));
|
|
507
527
|
lines.push("");
|
|
528
|
+
if (report.summary.erroredTargets > 0) {
|
|
529
|
+
lines.push(
|
|
530
|
+
"Note: one or more targets could not be fully analyzed, so the final rollup may be incomplete until those analysis errors are resolved.",
|
|
531
|
+
);
|
|
532
|
+
lines.push("");
|
|
533
|
+
}
|
|
508
534
|
lines.push(
|
|
509
535
|
"Next step: review the file, repository, or package listed in 'What to do next'. If you maintain it, make the remediation directly; otherwise, open an upstream issue or discussion with the relevant maintainers, then re-run cdx-audit or cdxgen --bom-audit.",
|
|
510
536
|
);
|