@cyclonedx/cdxgen 12.3.1 → 12.3.3

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 (87) hide show
  1. package/README.md +6 -0
  2. package/bin/cdxgen.js +1 -2
  3. package/data/rules/ai-agent-governance.yaml +43 -0
  4. package/data/rules/ci-permissions.yaml +132 -0
  5. package/data/rules/dependency-sources.yaml +65 -5
  6. package/data/rules/mcp-servers.yaml +36 -2
  7. package/data/rules/package-integrity.yaml +22 -0
  8. package/lib/cli/index.js +436 -56
  9. package/lib/cli/index.poku.js +875 -2
  10. package/lib/helpers/agentFormulationParser.js +10 -3
  11. package/lib/helpers/agentFormulationParser.poku.js +42 -0
  12. package/lib/helpers/aiInventory.js +262 -0
  13. package/lib/helpers/aiInventory.poku.js +111 -0
  14. package/lib/helpers/analyzer.js +413 -54
  15. package/lib/helpers/analyzer.poku.js +117 -0
  16. package/lib/helpers/auditCategories.js +76 -0
  17. package/lib/helpers/chromextutils.js +25 -3
  18. package/lib/helpers/chromextutils.poku.js +68 -0
  19. package/lib/helpers/ciParsers/githubActions.js +79 -0
  20. package/lib/helpers/ciParsers/githubActions.poku.js +103 -0
  21. package/lib/helpers/communityAiConfigParser.js +15 -5
  22. package/lib/helpers/communityAiConfigParser.poku.js +71 -0
  23. package/lib/helpers/depsUtils.js +5 -0
  24. package/lib/helpers/depsUtils.poku.js +55 -0
  25. package/lib/helpers/display.js +50 -24
  26. package/lib/helpers/display.poku.js +70 -58
  27. package/lib/helpers/formulationParsers.js +26 -6
  28. package/lib/helpers/jsonLike.js +21 -20
  29. package/lib/helpers/jsonLike.poku.js +34 -0
  30. package/lib/helpers/mcpConfigParser.js +32 -16
  31. package/lib/helpers/mcpConfigParser.poku.js +104 -0
  32. package/lib/helpers/mcpDiscovery.js +13 -23
  33. package/lib/helpers/mcpDiscovery.poku.js +21 -0
  34. package/lib/helpers/propertySanitizer.js +121 -0
  35. package/lib/helpers/utils.js +953 -41
  36. package/lib/helpers/utils.poku.js +901 -1
  37. package/lib/managers/binary.js +16 -0
  38. package/lib/managers/binary.poku.js +1 -0
  39. package/lib/managers/docker.js +240 -16
  40. package/lib/managers/docker.poku.js +1142 -2
  41. package/lib/server/server.js +7 -4
  42. package/lib/server/server.poku.js +36 -1
  43. package/lib/stages/postgen/annotator.js +2 -1
  44. package/lib/stages/postgen/annotator.poku.js +15 -0
  45. package/lib/stages/postgen/auditBom.js +12 -6
  46. package/lib/stages/postgen/auditBom.poku.js +755 -6
  47. package/lib/stages/postgen/postgen.js +229 -6
  48. package/lib/stages/postgen/postgen.poku.js +180 -0
  49. package/package.json +2 -1
  50. package/types/lib/cli/index.d.ts +1 -0
  51. package/types/lib/cli/index.d.ts.map +1 -1
  52. package/types/lib/helpers/agentFormulationParser.d.ts +19 -0
  53. package/types/lib/helpers/agentFormulationParser.d.ts.map +1 -0
  54. package/types/lib/helpers/aiInventory.d.ts +23 -0
  55. package/types/lib/helpers/aiInventory.d.ts.map +1 -0
  56. package/types/lib/helpers/analyzer.d.ts +5 -0
  57. package/types/lib/helpers/analyzer.d.ts.map +1 -1
  58. package/types/lib/helpers/auditCategories.d.ts +12 -0
  59. package/types/lib/helpers/auditCategories.d.ts.map +1 -0
  60. package/types/lib/helpers/chromextutils.d.ts.map +1 -1
  61. package/types/lib/helpers/ciParsers/githubActions.d.ts.map +1 -1
  62. package/types/lib/helpers/communityAiConfigParser.d.ts +29 -0
  63. package/types/lib/helpers/communityAiConfigParser.d.ts.map +1 -0
  64. package/types/lib/helpers/depsUtils.d.ts.map +1 -1
  65. package/types/lib/helpers/display.d.ts +1 -0
  66. package/types/lib/helpers/display.d.ts.map +1 -1
  67. package/types/lib/helpers/formulationParsers.d.ts.map +1 -1
  68. package/types/lib/helpers/jsonLike.d.ts +4 -0
  69. package/types/lib/helpers/jsonLike.d.ts.map +1 -0
  70. package/types/lib/helpers/mcp.d.ts +29 -0
  71. package/types/lib/helpers/mcp.d.ts.map +1 -0
  72. package/types/lib/helpers/mcpConfigParser.d.ts +30 -0
  73. package/types/lib/helpers/mcpConfigParser.d.ts.map +1 -0
  74. package/types/lib/helpers/mcpDiscovery.d.ts +5 -0
  75. package/types/lib/helpers/mcpDiscovery.d.ts.map +1 -0
  76. package/types/lib/helpers/propertySanitizer.d.ts +3 -0
  77. package/types/lib/helpers/propertySanitizer.d.ts.map +1 -0
  78. package/types/lib/helpers/utils.d.ts +31 -0
  79. package/types/lib/helpers/utils.d.ts.map +1 -1
  80. package/types/lib/managers/binary.d.ts.map +1 -1
  81. package/types/lib/managers/docker.d.ts +3 -0
  82. package/types/lib/managers/docker.d.ts.map +1 -1
  83. package/types/lib/server/server.d.ts +1 -0
  84. package/types/lib/server/server.d.ts.map +1 -1
  85. package/types/lib/stages/postgen/annotator.d.ts.map +1 -1
  86. package/types/lib/stages/postgen/auditBom.d.ts.map +1 -1
  87. package/types/lib/stages/postgen/postgen.d.ts.map +1 -1
@@ -17,30 +17,20 @@ const INLINE_CREDENTIAL_PATTERNS = [
17
17
  ];
18
18
 
19
19
  export function sanitizeMcpRefToken(value) {
20
- const input = String(value || "").toLowerCase();
21
- const tokens = [];
22
- let previousWasSeparator = false;
23
- for (const char of input) {
24
- const isAlphaNumeric =
25
- (char >= "a" && char <= "z") || (char >= "0" && char <= "9");
26
- const isAllowedPunctuation = [".", "_", "-"].includes(char);
27
- if (isAlphaNumeric || isAllowedPunctuation) {
28
- tokens.push(char);
29
- previousWasSeparator = false;
30
- continue;
31
- }
32
- if (!previousWasSeparator && tokens.length) {
33
- tokens.push("-");
34
- previousWasSeparator = true;
35
- }
20
+ const input = String(value || "")
21
+ .normalize("NFKC")
22
+ .trim()
23
+ .toLowerCase();
24
+ const normalized = input
25
+ .replaceAll(/[/\\:]/gu, "-")
26
+ .replaceAll(/[^a-z0-9._-]+/gu, "-")
27
+ .replaceAll(/[._-]{2,}/gu, "-")
28
+ .replaceAll(/^\.+|\.+$/gu, "")
29
+ .replaceAll(/^[._-]+|[._-]+$/gu, "");
30
+ if (!normalized || normalized === "." || normalized === "..") {
31
+ return "unknown";
36
32
  }
37
- while (tokens[0] === "-") {
38
- tokens.shift();
39
- }
40
- while (tokens[tokens.length - 1] === "-") {
41
- tokens.pop();
42
- }
43
- return tokens.join("") || "unknown";
33
+ return normalized.slice(0, 128);
44
34
  }
45
35
 
46
36
  export function isLocalHost(hostname) {
@@ -0,0 +1,21 @@
1
+ import { assert, describe, it } from "poku";
2
+
3
+ import { sanitizeMcpRefToken } from "./mcpDiscovery.js";
4
+
5
+ describe("sanitizeMcpRefToken()", () => {
6
+ it("normalizes path traversal and punctuation-heavy input into safe tokens", () => {
7
+ assert.strictEqual(
8
+ sanitizeMcpRefToken("../Secrets/Prod Token"),
9
+ "secrets-prod-token",
10
+ );
11
+ assert.strictEqual(
12
+ sanitizeMcpRefToken("..\\..\\etc\\passwd"),
13
+ "etc-passwd",
14
+ );
15
+ });
16
+
17
+ it("returns unknown for empty or separator-only input", () => {
18
+ assert.strictEqual(sanitizeMcpRefToken("..."), "unknown");
19
+ assert.strictEqual(sanitizeMcpRefToken("///"), "unknown");
20
+ });
21
+ });
@@ -0,0 +1,121 @@
1
+ import path from "node:path";
2
+
3
+ const DANGEROUS_OBJECT_KEYS = new Set([
4
+ "__proto__",
5
+ "constructor",
6
+ "prototype",
7
+ ]);
8
+ const INLINE_CREDENTIAL_PATTERNS = [
9
+ /\bAKIA[0-9A-Z]{16}\b/gu,
10
+ /\bbearer\s+[a-z0-9._-]{16,}\b/giu,
11
+ /\b(?:sk|rk|pk)_[a-z0-9_-]{8,}\b/giu,
12
+ /\bgh[pousr]_[a-z0-9]{20,}\b/giu,
13
+ /\bAIza[0-9A-Za-z_-]{20,}\b/gu,
14
+ ];
15
+ const JSON_PROPERTY_NAMES = new Set([
16
+ "cdx:agent:permission",
17
+ "cdx:mcp:toolAnnotations",
18
+ "cdx:skill:metadata",
19
+ ]);
20
+ const URL_PATTERN = /https?:\/\/[^\s<>"'),\]}]+/giu;
21
+
22
+ function sanitizeUrlForBom(value) {
23
+ const input = String(value || "").trim();
24
+ if (!input) {
25
+ return input;
26
+ }
27
+ try {
28
+ const parsed = new URL(input);
29
+ parsed.username = "";
30
+ parsed.password = "";
31
+ parsed.search = "";
32
+ parsed.hash = "";
33
+ return parsed.toString();
34
+ } catch {
35
+ return input;
36
+ }
37
+ }
38
+
39
+ function sanitizeTextForBom(value) {
40
+ let sanitized = String(value ?? "");
41
+ sanitized = sanitized.replace(URL_PATTERN, (match) =>
42
+ sanitizeUrlForBom(match),
43
+ );
44
+ for (const pattern of INLINE_CREDENTIAL_PATTERNS) {
45
+ sanitized = sanitized.replace(pattern, "[redacted]");
46
+ }
47
+ return sanitized;
48
+ }
49
+
50
+ function sanitizeStructuredValueForBom(value) {
51
+ if (typeof value === "string") {
52
+ return sanitizeTextForBom(value);
53
+ }
54
+ if (Array.isArray(value)) {
55
+ return value.map((entry) => sanitizeStructuredValueForBom(entry));
56
+ }
57
+ if (value && typeof value === "object") {
58
+ const sanitized = {};
59
+ for (const [key, entryValue] of Object.entries(value)) {
60
+ if (DANGEROUS_OBJECT_KEYS.has(key)) {
61
+ continue;
62
+ }
63
+ sanitized[key] = sanitizeStructuredValueForBom(entryValue);
64
+ }
65
+ return sanitized;
66
+ }
67
+ return value;
68
+ }
69
+
70
+ function extractCommandExecutable(command) {
71
+ const trimmedCommand = String(command || "").trim();
72
+ if (!trimmedCommand) {
73
+ return "";
74
+ }
75
+ const quotedMatch = trimmedCommand.match(/^(['"])(.*?)\1/u);
76
+ if (quotedMatch?.[2]) {
77
+ return quotedMatch[2];
78
+ }
79
+ const absolutePathMatch = trimmedCommand.match(
80
+ /^((?:[A-Za-z]:\\|\/).*?\.(?:bat|bin|cjs|cmd|com|exe|jar|js|mjs|ps1|py|rb|sh|ts|tsx))(?=\s|$)/iu,
81
+ );
82
+ if (absolutePathMatch?.[1]) {
83
+ return absolutePathMatch[1];
84
+ }
85
+ return trimmedCommand.split(/\s+/u)[0];
86
+ }
87
+
88
+ function summarizeExecutable(command) {
89
+ const executable = extractCommandExecutable(command);
90
+ if (!executable) {
91
+ return "configured";
92
+ }
93
+ if (executable.includes("\\")) {
94
+ return path.win32.basename(executable) || "configured";
95
+ }
96
+ return path.posix.basename(executable) || "configured";
97
+ }
98
+
99
+ export function sanitizeBomUrl(value) {
100
+ return sanitizeUrlForBom(value);
101
+ }
102
+
103
+ export function sanitizeBomPropertyValue(name, value) {
104
+ if (value === undefined || value === null || value === "") {
105
+ return value;
106
+ }
107
+ if (name === "cdx:mcp:command") {
108
+ const sanitizedCommand = sanitizeTextForBom(value).trim();
109
+ if (!sanitizedCommand) {
110
+ return sanitizedCommand;
111
+ }
112
+ return summarizeExecutable(sanitizedCommand);
113
+ }
114
+ if (JSON_PROPERTY_NAMES.has(name) || typeof value === "object") {
115
+ return JSON.stringify(sanitizeStructuredValueForBom(value));
116
+ }
117
+ if (typeof value === "string") {
118
+ return sanitizeTextForBom(value);
119
+ }
120
+ return value;
121
+ }