@cyclonedx/cdxgen 12.2.1 → 12.3.0
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 +239 -90
- package/bin/audit.js +191 -0
- package/bin/cdxgen.js +513 -167
- package/bin/convert.js +99 -0
- package/bin/evinse.js +23 -0
- package/bin/repl.js +339 -8
- package/bin/sign.js +8 -0
- package/bin/validate.js +8 -0
- package/bin/verify.js +8 -0
- package/data/container-knowledge-index.json +125 -0
- package/data/gtfobins-index.json +6296 -0
- package/data/lolbas-index.json +150 -0
- package/data/queries-darwin.json +63 -3
- package/data/queries-win.json +45 -3
- package/data/queries.json +74 -2
- package/data/rules/chrome-extensions.yaml +240 -0
- package/data/rules/ci-permissions.yaml +478 -18
- package/data/rules/container-risk.yaml +270 -0
- package/data/rules/obom-runtime.yaml +891 -0
- package/data/rules/package-integrity.yaml +49 -0
- package/data/spdx-export.schema.json +6794 -0
- package/data/spdx-model-v3.0.1.jsonld +15999 -0
- package/lib/audit/index.js +1924 -0
- package/lib/audit/index.poku.js +1488 -0
- package/lib/audit/progress.js +137 -0
- package/lib/audit/progress.poku.js +188 -0
- package/lib/audit/reporters.js +618 -0
- package/lib/audit/scoring.js +310 -0
- package/lib/audit/scoring.poku.js +341 -0
- package/lib/audit/targets.js +260 -0
- package/lib/audit/targets.poku.js +331 -0
- package/lib/cli/index.js +154 -11
- package/lib/cli/index.poku.js +251 -0
- package/lib/helpers/analyzer.js +446 -2
- package/lib/helpers/analyzer.poku.js +72 -1
- package/lib/helpers/annotationFormatter.js +49 -0
- package/lib/helpers/annotationFormatter.poku.js +44 -0
- package/lib/helpers/bomUtils.js +36 -0
- package/lib/helpers/bomUtils.poku.js +51 -0
- package/lib/helpers/caxa.js +2 -2
- package/lib/helpers/chromextutils.js +1153 -0
- package/lib/helpers/chromextutils.poku.js +493 -0
- package/lib/helpers/ciParsers/githubActions.js +1632 -45
- package/lib/helpers/ciParsers/githubActions.poku.js +853 -1
- package/lib/helpers/containerRisk.js +186 -0
- package/lib/helpers/containerRisk.poku.js +52 -0
- package/lib/helpers/display.js +241 -59
- package/lib/helpers/display.poku.js +162 -2
- package/lib/helpers/exportUtils.js +123 -0
- package/lib/helpers/exportUtils.poku.js +60 -0
- package/lib/helpers/formulationParsers.js +69 -0
- package/lib/helpers/formulationParsers.poku.js +44 -0
- package/lib/helpers/gtfobins.js +189 -0
- package/lib/helpers/gtfobins.poku.js +49 -0
- package/lib/helpers/lolbas.js +267 -0
- package/lib/helpers/lolbas.poku.js +39 -0
- package/lib/helpers/osqueryTransform.js +84 -0
- package/lib/helpers/osqueryTransform.poku.js +49 -0
- package/lib/helpers/provenanceUtils.js +193 -0
- package/lib/helpers/provenanceUtils.poku.js +145 -0
- package/lib/helpers/pylockutils.js +281 -0
- package/lib/helpers/pylockutils.poku.js +48 -0
- package/lib/helpers/registryProvenance.js +793 -0
- package/lib/helpers/registryProvenance.poku.js +452 -0
- package/lib/helpers/source.js +1267 -0
- package/lib/helpers/source.poku.js +771 -0
- package/lib/helpers/spdxUtils.js +97 -0
- package/lib/helpers/spdxUtils.poku.js +70 -0
- package/lib/helpers/unicodeScan.js +147 -0
- package/lib/helpers/unicodeScan.poku.js +45 -0
- package/lib/helpers/utils.js +700 -128
- package/lib/helpers/utils.poku.js +877 -80
- package/lib/managers/binary.js +29 -5
- package/lib/managers/docker.js +179 -52
- package/lib/managers/docker.poku.js +327 -28
- package/lib/managers/oci.js +107 -23
- package/lib/managers/oci.poku.js +132 -0
- package/lib/server/openapi.yaml +17 -0
- package/lib/server/server.js +225 -336
- package/lib/server/server.poku.js +16 -10
- package/lib/stages/postgen/annotator.js +7 -0
- package/lib/stages/postgen/annotator.poku.js +40 -0
- package/lib/stages/postgen/auditBom.js +19 -3
- package/lib/stages/postgen/auditBom.poku.js +1729 -67
- package/lib/stages/postgen/postgen.js +40 -0
- package/lib/stages/postgen/postgen.poku.js +47 -0
- package/lib/stages/postgen/ruleEngine.js +80 -2
- package/lib/stages/postgen/spdxConverter.js +796 -0
- package/lib/stages/postgen/spdxConverter.poku.js +341 -0
- package/lib/validator/bomValidator.js +232 -0
- package/lib/validator/bomValidator.poku.js +70 -0
- package/lib/validator/complianceRules.js +70 -7
- package/lib/validator/complianceRules.poku.js +30 -0
- package/lib/validator/reporters/annotations.js +2 -2
- package/lib/validator/reporters/console.js +11 -0
- package/lib/validator/reporters.poku.js +13 -0
- package/package.json +10 -7
- package/types/bin/audit.d.ts +3 -0
- package/types/bin/audit.d.ts.map +1 -0
- package/types/bin/convert.d.ts +3 -0
- package/types/bin/convert.d.ts.map +1 -0
- package/types/bin/repl.d.ts.map +1 -1
- package/types/lib/audit/index.d.ts +115 -0
- package/types/lib/audit/index.d.ts.map +1 -0
- package/types/lib/audit/progress.d.ts +27 -0
- package/types/lib/audit/progress.d.ts.map +1 -0
- package/types/lib/audit/reporters.d.ts +35 -0
- package/types/lib/audit/reporters.d.ts.map +1 -0
- package/types/lib/audit/scoring.d.ts +35 -0
- package/types/lib/audit/scoring.d.ts.map +1 -0
- package/types/lib/audit/targets.d.ts +63 -0
- package/types/lib/audit/targets.d.ts.map +1 -0
- package/types/lib/cli/index.d.ts +8 -0
- package/types/lib/cli/index.d.ts.map +1 -1
- package/types/lib/helpers/analyzer.d.ts +13 -0
- package/types/lib/helpers/analyzer.d.ts.map +1 -1
- package/types/lib/helpers/annotationFormatter.d.ts +23 -0
- package/types/lib/helpers/annotationFormatter.d.ts.map +1 -0
- package/types/lib/helpers/bomUtils.d.ts +5 -0
- package/types/lib/helpers/bomUtils.d.ts.map +1 -0
- package/types/lib/helpers/chromextutils.d.ts +97 -0
- package/types/lib/helpers/chromextutils.d.ts.map +1 -0
- package/types/lib/helpers/ciParsers/githubActions.d.ts +3 -8
- package/types/lib/helpers/ciParsers/githubActions.d.ts.map +1 -1
- package/types/lib/helpers/containerRisk.d.ts +17 -0
- package/types/lib/helpers/containerRisk.d.ts.map +1 -0
- package/types/lib/helpers/display.d.ts +4 -1
- package/types/lib/helpers/display.d.ts.map +1 -1
- package/types/lib/helpers/exportUtils.d.ts +40 -0
- package/types/lib/helpers/exportUtils.d.ts.map +1 -0
- package/types/lib/helpers/formulationParsers.d.ts.map +1 -1
- package/types/lib/helpers/gtfobins.d.ts +17 -0
- package/types/lib/helpers/gtfobins.d.ts.map +1 -0
- package/types/lib/helpers/lolbas.d.ts +16 -0
- package/types/lib/helpers/lolbas.d.ts.map +1 -0
- package/types/lib/helpers/osqueryTransform.d.ts +7 -0
- package/types/lib/helpers/osqueryTransform.d.ts.map +1 -0
- package/types/lib/helpers/provenanceUtils.d.ts +90 -0
- package/types/lib/helpers/provenanceUtils.d.ts.map +1 -0
- package/types/lib/helpers/pylockutils.d.ts +51 -0
- package/types/lib/helpers/pylockutils.d.ts.map +1 -0
- package/types/lib/helpers/registryProvenance.d.ts +17 -0
- package/types/lib/helpers/registryProvenance.d.ts.map +1 -0
- package/types/lib/helpers/source.d.ts +141 -0
- package/types/lib/helpers/source.d.ts.map +1 -0
- package/types/lib/helpers/spdxUtils.d.ts +2 -0
- package/types/lib/helpers/spdxUtils.d.ts.map +1 -0
- package/types/lib/helpers/unicodeScan.d.ts +46 -0
- package/types/lib/helpers/unicodeScan.d.ts.map +1 -0
- package/types/lib/helpers/utils.d.ts +29 -11
- package/types/lib/helpers/utils.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/oci.d.ts.map +1 -1
- package/types/lib/server/server.d.ts +0 -36
- package/types/lib/server/server.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/postgen/spdxConverter.d.ts +11 -0
- package/types/lib/stages/postgen/spdxConverter.d.ts.map +1 -0
- package/types/lib/validator/bomValidator.d.ts +1 -0
- package/types/lib/validator/bomValidator.d.ts.map +1 -1
- package/types/lib/validator/complianceRules.d.ts.map +1 -1
- package/types/lib/validator/reporters/console.d.ts.map +1 -1
- package/types/bin/dependencies.d.ts +0 -3
- package/types/bin/dependencies.d.ts.map +0 -1
- package/types/bin/licenses.d.ts +0 -3
- package/types/bin/licenses.d.ts.map +0 -1
|
@@ -5,16 +5,14 @@ import esmock from "esmock";
|
|
|
5
5
|
import { afterEach, assert, beforeEach, describe, it } from "poku";
|
|
6
6
|
import sinon from "sinon";
|
|
7
7
|
|
|
8
|
-
import { isWin } from "../helpers/utils.js";
|
|
9
8
|
import {
|
|
10
|
-
getQueryParams,
|
|
11
9
|
isAllowedHost,
|
|
12
10
|
isAllowedPath,
|
|
13
11
|
isAllowedWinPath,
|
|
14
|
-
parseQueryString,
|
|
15
|
-
parseValue,
|
|
16
12
|
validateAndRejectGitSource,
|
|
17
|
-
} from "
|
|
13
|
+
} from "../helpers/source.js";
|
|
14
|
+
import { isWin } from "../helpers/utils.js";
|
|
15
|
+
import { getQueryParams, parseQueryString, parseValue } from "./server.js";
|
|
18
16
|
|
|
19
17
|
function nullProtoObj(obj) {
|
|
20
18
|
if (obj === null || typeof obj !== "object") {
|
|
@@ -130,6 +128,14 @@ describe("parseQueryString tests", () => {
|
|
|
130
128
|
checkEqual(result.autoCreate, false);
|
|
131
129
|
checkEqual(result.isLatest, true);
|
|
132
130
|
});
|
|
131
|
+
|
|
132
|
+
it("parses format for SPDX export requests", () => {
|
|
133
|
+
const q = {
|
|
134
|
+
format: "spdx",
|
|
135
|
+
};
|
|
136
|
+
const result = parseQueryString(q, {}, {});
|
|
137
|
+
checkEqual(result.format, "spdx");
|
|
138
|
+
});
|
|
133
139
|
});
|
|
134
140
|
|
|
135
141
|
describe("isAllowedHost()", () => {
|
|
@@ -619,7 +625,7 @@ describe("gitClone() hardening tests", () => {
|
|
|
619
625
|
.stub()
|
|
620
626
|
.returns(path.join(os.tmpdir(), "fake-repo"));
|
|
621
627
|
|
|
622
|
-
const { gitClone } = await esmock("
|
|
628
|
+
const { gitClone } = await esmock("../helpers/source.js", {
|
|
623
629
|
"../helpers/utils.js": {
|
|
624
630
|
safeSpawnSync: spawnStub,
|
|
625
631
|
isSecureMode: false,
|
|
@@ -663,7 +669,7 @@ describe("gitClone() hardening tests", () => {
|
|
|
663
669
|
.stub()
|
|
664
670
|
.returns(path.join(os.tmpdir(), "fake-repo"));
|
|
665
671
|
|
|
666
|
-
const { gitClone } = await esmock("
|
|
672
|
+
const { gitClone } = await esmock("../helpers/source.js", {
|
|
667
673
|
"../helpers/utils.js": {
|
|
668
674
|
safeSpawnSync: spawnStub,
|
|
669
675
|
isSecureMode: true,
|
|
@@ -707,7 +713,7 @@ describe("gitClone() hardening tests", () => {
|
|
|
707
713
|
.stub()
|
|
708
714
|
.returns(path.join(os.tmpdir(), "fake-repo"));
|
|
709
715
|
|
|
710
|
-
const { gitClone } = await esmock("
|
|
716
|
+
const { gitClone } = await esmock("../helpers/source.js", {
|
|
711
717
|
"../helpers/utils.js": {
|
|
712
718
|
safeSpawnSync: spawnStub,
|
|
713
719
|
isSecureMode: secureMode,
|
|
@@ -740,7 +746,7 @@ describe("gitClone() hardening tests", () => {
|
|
|
740
746
|
.stub()
|
|
741
747
|
.returns(path.join(os.tmpdir(), "fake-repo"));
|
|
742
748
|
|
|
743
|
-
const { gitClone } = await esmock("
|
|
749
|
+
const { gitClone } = await esmock("../helpers/source.js", {
|
|
744
750
|
"../helpers/utils.js": {
|
|
745
751
|
safeSpawnSync: spawnStub,
|
|
746
752
|
isSecureMode: false,
|
|
@@ -770,7 +776,7 @@ describe("gitClone() hardening tests", () => {
|
|
|
770
776
|
.stub()
|
|
771
777
|
.returns(path.join(os.tmpdir(), "fake-repo"));
|
|
772
778
|
|
|
773
|
-
const { gitClone } = await esmock("
|
|
779
|
+
const { gitClone } = await esmock("../helpers/source.js", {
|
|
774
780
|
"../helpers/utils.js": {
|
|
775
781
|
safeSpawnSync: spawnStub,
|
|
776
782
|
isSecureMode: false,
|
|
@@ -2,6 +2,7 @@ import { readFileSync } from "node:fs";
|
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
|
|
4
4
|
import { thoughtLog } from "../../helpers/logger.js";
|
|
5
|
+
import { getTrustedPublishingComponentCounts } from "../../helpers/provenanceUtils.js";
|
|
5
6
|
import { dirNameStr } from "../../helpers/utils.js";
|
|
6
7
|
|
|
7
8
|
// Tags per BOM type.
|
|
@@ -295,6 +296,9 @@ export function textualMetadata(bomJson) {
|
|
|
295
296
|
c?.purl?.startsWith("pkg:swid"),
|
|
296
297
|
).length;
|
|
297
298
|
const githubStats = getGitHubWorkflowStats(bomJson?.components);
|
|
299
|
+
const trustedPublishingCounts = getTrustedPublishingComponentCounts(
|
|
300
|
+
bomJson?.components,
|
|
301
|
+
);
|
|
298
302
|
const isGitHubBom = bomType === "SBOM";
|
|
299
303
|
if (metadata?.timestamp) {
|
|
300
304
|
text = `This ${bomTypeDescription} document was created on ${humanifyTimestamp(metadata.timestamp)}`;
|
|
@@ -469,6 +473,9 @@ export function textualMetadata(bomJson) {
|
|
|
469
473
|
if (!isGitHubBom) {
|
|
470
474
|
text = `${text} There are ${bomJson.components.length} components.`;
|
|
471
475
|
}
|
|
476
|
+
if (trustedPublishingCounts.total > 0) {
|
|
477
|
+
text = `${text} Trusted publishing metadata is present for ${trustedPublishingCounts.npm} npm component(s) and ${trustedPublishingCounts.pypi} PyPI component(s).`;
|
|
478
|
+
}
|
|
472
479
|
} else {
|
|
473
480
|
text = `${text} BOM file is empty without components.`;
|
|
474
481
|
thoughtLog(
|
|
@@ -263,6 +263,46 @@ it("textualMetadata tests", () => {
|
|
|
263
263
|
}),
|
|
264
264
|
"This Operations Bill-of-Materials (OBOM) document was created on Monday, November 11, 2024 with cdxgen. The lifecycles phases represented are: pre-build and operations. The document describes an operating system named 'Microsoft Windows 11 Pro' with version '22H2'. BOM file is empty without components. The OS uses the x64 architecture and has the build version '10.0.22621'.",
|
|
265
265
|
);
|
|
266
|
+
|
|
267
|
+
assert.ok(
|
|
268
|
+
textualMetadata({
|
|
269
|
+
metadata: {
|
|
270
|
+
component: {
|
|
271
|
+
name: "trusted-demo",
|
|
272
|
+
type: "application",
|
|
273
|
+
version: "1.0.0",
|
|
274
|
+
},
|
|
275
|
+
timestamp: "2026-01-01T00:00:00Z",
|
|
276
|
+
tools: {
|
|
277
|
+
components: [{ name: "cdxgen" }],
|
|
278
|
+
},
|
|
279
|
+
},
|
|
280
|
+
components: [
|
|
281
|
+
{
|
|
282
|
+
name: "left-pad",
|
|
283
|
+
properties: [
|
|
284
|
+
{
|
|
285
|
+
name: "cdx:npm:trustedPublishing",
|
|
286
|
+
value: "true",
|
|
287
|
+
},
|
|
288
|
+
],
|
|
289
|
+
type: "library",
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
name: "requests",
|
|
293
|
+
properties: [
|
|
294
|
+
{
|
|
295
|
+
name: "cdx:pypi:trustedPublishing",
|
|
296
|
+
value: "true",
|
|
297
|
+
},
|
|
298
|
+
],
|
|
299
|
+
type: "library",
|
|
300
|
+
},
|
|
301
|
+
],
|
|
302
|
+
}).includes(
|
|
303
|
+
"Trusted publishing metadata is present for 1 npm component(s) and 1 PyPI component(s).",
|
|
304
|
+
),
|
|
305
|
+
);
|
|
266
306
|
});
|
|
267
307
|
|
|
268
308
|
it("extractTags tests", () => {
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import { join, resolve } from "node:path";
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
7
|
|
|
8
|
+
import { buildAnnotationText } from "../../helpers/annotationFormatter.js";
|
|
8
9
|
import { table } from "../../helpers/table.js";
|
|
9
10
|
import {
|
|
10
11
|
DEBUG_MODE,
|
|
@@ -15,7 +16,6 @@ import { evaluateRules, loadRules } from "./ruleEngine.js";
|
|
|
15
16
|
|
|
16
17
|
const __dirname = fileURLToPath(new URL(".", import.meta.url));
|
|
17
18
|
const BUILTIN_RULES_DIR = join(__dirname, "..", "..", "..", "data", "rules");
|
|
18
|
-
const CODE_BLOCK = "```";
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* Audit BOM formulation section using JSONata-powered rule engine
|
|
@@ -89,6 +89,7 @@ export function formatConsoleOutput(findings) {
|
|
|
89
89
|
columnDefault: { wrapWord: true, width: 100 },
|
|
90
90
|
columns: [
|
|
91
91
|
{ width: 10 },
|
|
92
|
+
{ width: 26 },
|
|
92
93
|
{ width: 35 },
|
|
93
94
|
{ width: 50 },
|
|
94
95
|
{ width: 50 },
|
|
@@ -99,10 +100,13 @@ export function formatConsoleOutput(findings) {
|
|
|
99
100
|
content: "BOM Audit Findings\nGenerated with \u2665 by cdxgen",
|
|
100
101
|
},
|
|
101
102
|
};
|
|
102
|
-
const data = [["Rule", "Message", "Description", "Ref", "File"]];
|
|
103
|
+
const data = [["Rule", "ATT&CK", "Message", "Description", "Ref", "File"]];
|
|
103
104
|
for (const f of findings) {
|
|
104
105
|
const line = [];
|
|
105
106
|
line.push(f.ruleId);
|
|
107
|
+
line.push(
|
|
108
|
+
[...(f.attackTactics || []), ...(f.attackTechniques || [])].join(", "),
|
|
109
|
+
);
|
|
106
110
|
line.push(f.message);
|
|
107
111
|
line.push(f.description || "");
|
|
108
112
|
line.push(f.location?.purl || f.location?.bomRef || "");
|
|
@@ -143,6 +147,18 @@ export function formatAnnotations(findings, bomJson) {
|
|
|
143
147
|
if (f.mitigation) {
|
|
144
148
|
properties.push({ name: "cdx:audit:mitigation", value: f.mitigation });
|
|
145
149
|
}
|
|
150
|
+
if (f.attackTactics?.length) {
|
|
151
|
+
properties.push({
|
|
152
|
+
name: "cdx:audit:attack:tactics",
|
|
153
|
+
value: f.attackTactics.join(","),
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
if (f.attackTechniques?.length) {
|
|
157
|
+
properties.push({
|
|
158
|
+
name: "cdx:audit:attack:techniques",
|
|
159
|
+
value: f.attackTechniques.join(","),
|
|
160
|
+
});
|
|
161
|
+
}
|
|
146
162
|
if (f?.location?.purl) {
|
|
147
163
|
properties.push({
|
|
148
164
|
name: "cdx:audit:location:purl",
|
|
@@ -177,7 +193,7 @@ export function formatAnnotations(findings, bomJson) {
|
|
|
177
193
|
component: cdxgenAnnotator[0],
|
|
178
194
|
},
|
|
179
195
|
timestamp: getTimestamp(),
|
|
180
|
-
text:
|
|
196
|
+
text: buildAnnotationText(f.message, properties),
|
|
181
197
|
};
|
|
182
198
|
});
|
|
183
199
|
}
|