@cyclonedx/cdxgen 12.1.5 → 12.2.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 (193) hide show
  1. package/README.md +51 -40
  2. package/bin/cdxgen.js +194 -97
  3. package/bin/evinse.js +4 -4
  4. package/bin/repl.js +1 -1
  5. package/bin/sign.js +102 -0
  6. package/bin/validate.js +233 -0
  7. package/bin/verify.js +69 -28
  8. package/data/queries.json +1 -1
  9. package/data/rules/ci-permissions.yaml +186 -0
  10. package/data/rules/dependency-sources.yaml +123 -0
  11. package/data/rules/package-integrity.yaml +135 -0
  12. package/data/rules/vscode-extensions.yaml +228 -0
  13. package/lib/cli/index.js +449 -429
  14. package/lib/cli/index.poku.js +117 -0
  15. package/lib/evinser/db.js +137 -0
  16. package/lib/{helpers → evinser}/db.poku.js +2 -6
  17. package/lib/evinser/evinser.js +2 -14
  18. package/lib/helpers/analyzer.js +606 -3
  19. package/lib/helpers/analyzer.poku.js +230 -0
  20. package/lib/helpers/bomSigner.js +312 -0
  21. package/lib/helpers/bomSigner.poku.js +156 -0
  22. package/lib/helpers/ciParsers/azurePipelines.js +295 -0
  23. package/lib/helpers/ciParsers/azurePipelines.poku.js +253 -0
  24. package/lib/helpers/ciParsers/circleCi.js +286 -0
  25. package/lib/helpers/ciParsers/circleCi.poku.js +230 -0
  26. package/lib/helpers/ciParsers/common.js +24 -0
  27. package/lib/helpers/ciParsers/githubActions.js +636 -0
  28. package/lib/helpers/ciParsers/githubActions.poku.js +802 -0
  29. package/lib/helpers/ciParsers/gitlabCi.js +213 -0
  30. package/lib/helpers/ciParsers/gitlabCi.poku.js +247 -0
  31. package/lib/helpers/ciParsers/jenkins.js +181 -0
  32. package/lib/helpers/ciParsers/jenkins.poku.js +197 -0
  33. package/lib/helpers/depsUtils.js +219 -0
  34. package/lib/helpers/depsUtils.poku.js +207 -0
  35. package/lib/helpers/display.js +426 -5
  36. package/lib/helpers/envcontext.js +18 -3
  37. package/lib/helpers/formulationParsers.js +351 -0
  38. package/lib/helpers/logger.js +14 -0
  39. package/lib/helpers/protobom.js +9 -9
  40. package/lib/helpers/pythonutils.js +9 -0
  41. package/lib/helpers/remote/dependency-track.js +84 -0
  42. package/lib/helpers/remote/dependency-track.poku.js +119 -0
  43. package/lib/helpers/table.js +384 -0
  44. package/lib/helpers/table.poku.js +186 -0
  45. package/lib/helpers/utils.js +865 -416
  46. package/lib/helpers/utils.poku.js +172 -265
  47. package/lib/helpers/versutils.js +202 -0
  48. package/lib/helpers/versutils.poku.js +315 -0
  49. package/lib/helpers/vsixutils.js +1061 -0
  50. package/lib/helpers/vsixutils.poku.js +2247 -0
  51. package/lib/managers/binary.js +19 -19
  52. package/lib/managers/docker.js +108 -1
  53. package/lib/managers/oci.js +10 -0
  54. package/lib/managers/piptree.js +3 -9
  55. package/lib/parsers/npmrc.js +17 -13
  56. package/lib/parsers/npmrc.poku.js +41 -5
  57. package/lib/server/openapi.yaml +34 -1
  58. package/lib/server/server.js +50 -13
  59. package/lib/server/server.poku.js +332 -144
  60. package/lib/stages/postgen/annotator.js +1 -1
  61. package/lib/stages/postgen/auditBom.js +196 -0
  62. package/lib/stages/postgen/auditBom.poku.js +378 -0
  63. package/lib/stages/postgen/postgen.js +54 -1
  64. package/lib/stages/postgen/postgen.poku.js +90 -1
  65. package/lib/stages/postgen/ruleEngine.js +369 -0
  66. package/lib/stages/pregen/envAudit.js +299 -0
  67. package/lib/stages/pregen/envAudit.poku.js +572 -0
  68. package/lib/stages/pregen/pregen.js +12 -8
  69. package/lib/{helpers/validator.js → validator/bomValidator.js} +107 -47
  70. package/lib/validator/complianceEngine.js +241 -0
  71. package/lib/validator/complianceEngine.poku.js +168 -0
  72. package/lib/validator/complianceRules.js +1610 -0
  73. package/lib/validator/complianceRules.poku.js +328 -0
  74. package/lib/validator/index.js +222 -0
  75. package/lib/validator/index.poku.js +144 -0
  76. package/lib/validator/reporters/annotations.js +121 -0
  77. package/lib/validator/reporters/console.js +149 -0
  78. package/lib/validator/reporters/index.js +41 -0
  79. package/lib/validator/reporters/json.js +37 -0
  80. package/lib/validator/reporters/sarif.js +184 -0
  81. package/lib/validator/reporters.poku.js +150 -0
  82. package/package.json +8 -9
  83. package/types/bin/sign.d.ts +3 -0
  84. package/types/bin/sign.d.ts.map +1 -0
  85. package/types/bin/validate.d.ts +3 -0
  86. package/types/bin/validate.d.ts.map +1 -0
  87. package/types/helpers/utils.d.ts +0 -1
  88. package/types/lib/cli/index.d.ts +49 -52
  89. package/types/lib/cli/index.d.ts.map +1 -1
  90. package/types/lib/evinser/db.d.ts +34 -0
  91. package/types/lib/evinser/db.d.ts.map +1 -0
  92. package/types/lib/evinser/evinser.d.ts +63 -16
  93. package/types/lib/evinser/evinser.d.ts.map +1 -1
  94. package/types/lib/helpers/analyzer.d.ts.map +1 -1
  95. package/types/lib/helpers/bomSigner.d.ts +27 -0
  96. package/types/lib/helpers/bomSigner.d.ts.map +1 -0
  97. package/types/lib/helpers/ciParsers/azurePipelines.d.ts +17 -0
  98. package/types/lib/helpers/ciParsers/azurePipelines.d.ts.map +1 -0
  99. package/types/lib/helpers/ciParsers/circleCi.d.ts +17 -0
  100. package/types/lib/helpers/ciParsers/circleCi.d.ts.map +1 -0
  101. package/types/lib/helpers/ciParsers/common.d.ts +11 -0
  102. package/types/lib/helpers/ciParsers/common.d.ts.map +1 -0
  103. package/types/lib/helpers/ciParsers/githubActions.d.ts +34 -0
  104. package/types/lib/helpers/ciParsers/githubActions.d.ts.map +1 -0
  105. package/types/lib/helpers/ciParsers/gitlabCi.d.ts +17 -0
  106. package/types/lib/helpers/ciParsers/gitlabCi.d.ts.map +1 -0
  107. package/types/lib/helpers/ciParsers/jenkins.d.ts +17 -0
  108. package/types/lib/helpers/ciParsers/jenkins.d.ts.map +1 -0
  109. package/types/lib/helpers/depsUtils.d.ts +21 -0
  110. package/types/lib/helpers/depsUtils.d.ts.map +1 -0
  111. package/types/lib/helpers/display.d.ts +111 -11
  112. package/types/lib/helpers/display.d.ts.map +1 -1
  113. package/types/lib/helpers/envcontext.d.ts +19 -7
  114. package/types/lib/helpers/envcontext.d.ts.map +1 -1
  115. package/types/lib/helpers/formulationParsers.d.ts +50 -0
  116. package/types/lib/helpers/formulationParsers.d.ts.map +1 -0
  117. package/types/lib/helpers/logger.d.ts +15 -1
  118. package/types/lib/helpers/logger.d.ts.map +1 -1
  119. package/types/lib/helpers/protobom.d.ts +2 -2
  120. package/types/lib/helpers/pythonutils.d.ts +10 -1
  121. package/types/lib/helpers/pythonutils.d.ts.map +1 -1
  122. package/types/lib/helpers/remote/dependency-track.d.ts +16 -0
  123. package/types/lib/helpers/remote/dependency-track.d.ts.map +1 -0
  124. package/types/lib/helpers/table.d.ts +6 -0
  125. package/types/lib/helpers/table.d.ts.map +1 -0
  126. package/types/lib/helpers/utils.d.ts +533 -128
  127. package/types/lib/helpers/utils.d.ts.map +1 -1
  128. package/types/lib/helpers/versutils.d.ts +8 -0
  129. package/types/lib/helpers/versutils.d.ts.map +1 -0
  130. package/types/lib/helpers/vsixutils.d.ts +130 -0
  131. package/types/lib/helpers/vsixutils.d.ts.map +1 -0
  132. package/types/lib/managers/docker.d.ts +12 -31
  133. package/types/lib/managers/docker.d.ts.map +1 -1
  134. package/types/lib/managers/oci.d.ts +11 -1
  135. package/types/lib/managers/oci.d.ts.map +1 -1
  136. package/types/lib/managers/piptree.d.ts.map +1 -1
  137. package/types/lib/parsers/npmrc.d.ts +4 -1
  138. package/types/lib/parsers/npmrc.d.ts.map +1 -1
  139. package/types/lib/server/server.d.ts +22 -2
  140. package/types/lib/server/server.d.ts.map +1 -1
  141. package/types/lib/stages/postgen/auditBom.d.ts +20 -0
  142. package/types/lib/stages/postgen/auditBom.d.ts.map +1 -0
  143. package/types/lib/stages/postgen/postgen.d.ts +8 -1
  144. package/types/lib/stages/postgen/postgen.d.ts.map +1 -1
  145. package/types/lib/stages/postgen/ruleEngine.d.ts +18 -0
  146. package/types/lib/stages/postgen/ruleEngine.d.ts.map +1 -0
  147. package/types/lib/stages/pregen/envAudit.d.ts +8 -0
  148. package/types/lib/stages/pregen/envAudit.d.ts.map +1 -0
  149. package/types/lib/stages/pregen/pregen.d.ts.map +1 -1
  150. package/types/lib/{helpers/validator.d.ts → validator/bomValidator.d.ts} +1 -1
  151. package/types/lib/validator/bomValidator.d.ts.map +1 -0
  152. package/types/lib/validator/complianceEngine.d.ts +66 -0
  153. package/types/lib/validator/complianceEngine.d.ts.map +1 -0
  154. package/types/lib/validator/complianceRules.d.ts +70 -0
  155. package/types/lib/validator/complianceRules.d.ts.map +1 -0
  156. package/types/lib/validator/index.d.ts +70 -0
  157. package/types/lib/validator/index.d.ts.map +1 -0
  158. package/types/lib/validator/reporters/annotations.d.ts +31 -0
  159. package/types/lib/validator/reporters/annotations.d.ts.map +1 -0
  160. package/types/lib/validator/reporters/console.d.ts +30 -0
  161. package/types/lib/validator/reporters/console.d.ts.map +1 -0
  162. package/types/lib/validator/reporters/index.d.ts +21 -0
  163. package/types/lib/validator/reporters/index.d.ts.map +1 -0
  164. package/types/lib/validator/reporters/json.d.ts +11 -0
  165. package/types/lib/validator/reporters/json.d.ts.map +1 -0
  166. package/types/lib/validator/reporters/sarif.d.ts +16 -0
  167. package/types/lib/validator/reporters/sarif.d.ts.map +1 -0
  168. package/lib/helpers/db.js +0 -162
  169. package/lib/stages/pregen/env-audit.js +0 -34
  170. package/lib/stages/pregen/env-audit.poku.js +0 -290
  171. package/types/helpers/db.d.ts +0 -35
  172. package/types/helpers/db.d.ts.map +0 -1
  173. package/types/lib/helpers/db.d.ts +0 -35
  174. package/types/lib/helpers/db.d.ts.map +0 -1
  175. package/types/lib/helpers/validator.d.ts.map +0 -1
  176. package/types/lib/stages/pregen/env-audit.d.ts +0 -2
  177. package/types/lib/stages/pregen/env-audit.d.ts.map +0 -1
  178. package/types/managers/binary.d.ts +0 -37
  179. package/types/managers/binary.d.ts.map +0 -1
  180. package/types/managers/docker.d.ts +0 -56
  181. package/types/managers/docker.d.ts.map +0 -1
  182. package/types/managers/oci.d.ts +0 -2
  183. package/types/managers/oci.d.ts.map +0 -1
  184. package/types/managers/piptree.d.ts +0 -2
  185. package/types/managers/piptree.d.ts.map +0 -1
  186. package/types/server/server.d.ts +0 -34
  187. package/types/server/server.d.ts.map +0 -1
  188. package/types/stages/postgen/annotator.d.ts +0 -27
  189. package/types/stages/postgen/annotator.d.ts.map +0 -1
  190. package/types/stages/postgen/postgen.d.ts +0 -51
  191. package/types/stages/postgen/postgen.d.ts.map +0 -1
  192. package/types/stages/pregen/pregen.d.ts +0 -59
  193. package/types/stages/pregen/pregen.d.ts.map +0 -1
@@ -0,0 +1,186 @@
1
+ # CI/CD Permission Security Rules
2
+ # Category: ci-permission
3
+ # Evaluates GitHub Actions, GitLab CI, Azure Pipelines, etc. for privilege risks
4
+
5
+ - id: CI-001
6
+ name: "Unpinned action in write-permission workflow"
7
+ description: "GitHub Actions referenced by tag/branch in workflows with write permissions pose supply chain risk"
8
+ severity: high
9
+ category: ci-permission
10
+ condition: |
11
+ components[
12
+ $prop($, 'cdx:github:action:isShaPinned') = 'false'
13
+ and (
14
+ $prop($, 'cdx:github:workflow:hasWritePermissions') = 'true'
15
+ or $prop($, 'cdx:github:job:hasWritePermissions') = 'true'
16
+ )
17
+ ]
18
+ location: |
19
+ {
20
+ "bomRef": $."bom-ref",
21
+ "purl": purl,
22
+ "file": $prop($, 'cdx:github:workflow:file')
23
+ }
24
+ message: "Unpinned GitHub Action '{{ $prop($, 'cdx:github:action:uses') }}' in workflow with write permissions"
25
+ mitigation: "Pin action to full SHA: actions/setup-node@abc123def456..."
26
+ evidence: |
27
+ {
28
+ "pinningType": $prop($, 'cdx:github:action:versionPinningType'),
29
+ "workflowTriggers": $prop($, 'cdx:github:workflow:triggers'),
30
+ "jobName": $prop($, 'cdx:github:job:name')
31
+ }
32
+ - id: CI-002
33
+ name: "OIDC token issuance to non-official action"
34
+ description: "Workflows granting id-token:write to third-party actions may enable token exfiltration"
35
+ severity: high
36
+ category: ci-permission
37
+ condition: |
38
+ components[
39
+ $prop($, 'cdx:github:workflow:hasIdTokenWrite') = 'true'
40
+ and $prop($, 'cdx:actions:isOfficial') = 'false'
41
+ ]
42
+ location: |
43
+ { "bomRef": $."bom-ref", "purl": purl }
44
+ message: "Workflow grants OIDC token access to non-official action '{{ $prop($, 'cdx:github:action:uses') }}'"
45
+ mitigation: "Restrict id-token scope or use only verified/official actions for OIDC operations"
46
+ evidence: |
47
+ {
48
+ "isVerified": $prop($, 'cdx:actions:isVerified'),
49
+ "actionGroup": group
50
+ }
51
+ - id: CI-003
52
+ name: "Action pinned to mutable tag"
53
+ description: "GitHub Actions pinned to tags (vs SHA) can change behavior unexpectedly if tag is moved"
54
+ severity: medium
55
+ category: ci-permission
56
+ condition: |
57
+ components[
58
+ $prop($, 'cdx:github:action:versionPinningType') = 'tag'
59
+ ]
60
+ location: |
61
+ { "bomRef": $."bom-ref", "purl": purl }
62
+ message: "GitHub Action '{{ $prop($, 'cdx:github:action:uses') }}' pinned to mutable tag (not SHA)"
63
+ mitigation: "Consider pinning to full commit SHA for immutability: actions/setup-node@<full-sha>"
64
+ evidence: |
65
+ {
66
+ "currentVersion": version,
67
+ "isOfficial": $prop($, 'cdx:actions:isOfficial')
68
+ }
69
+ - id: CI-004
70
+ name: "Workflow uses pull_request_target trigger"
71
+ description: "pull_request_target can execute code in the context of the base branch, risking secret exposure"
72
+ severity: medium
73
+ category: ci-permission
74
+ # Check workflows (not components) for this trigger pattern
75
+ condition: |
76
+ formulation.workflows[
77
+ $hasProp($, 'cdx:github:workflow:triggers')
78
+ and $nullSafeProp($, 'cdx:github:workflow:triggers') ~> $trim() ~> $contains('pull_request_target')
79
+ ]
80
+ location: |
81
+ {
82
+ "bomRef": $."bom-ref",
83
+ "file": $prop($, 'cdx:github:workflow:file')
84
+ }
85
+ message: "Workflow '{{ $prop($, 'cdx:github:workflow:name') }}' uses pull_request_target trigger"
86
+ mitigation: "Ensure workflow does not checkout or run code from the PR head; use pull_request with careful permissions"
87
+ evidence: |
88
+ {
89
+ "triggers": $prop($, 'cdx:github:workflow:triggers'),
90
+ "hasWritePermissions": $prop($, 'cdx:github:workflow:hasWritePermissions')
91
+ }
92
+ - id: CI-005
93
+ name: "Checkout step persists credentials unnecessarily"
94
+ description: "actions/checkout with persist-credentials=true (default) exposes GITHUB_TOKEN to subsequent steps"
95
+ severity: medium
96
+ category: ci-permission
97
+ condition: |
98
+ components[
99
+ $contains($nullSafeProp($, 'cdx:github:action:uses'), 'actions/checkout')
100
+ and $propBool($, 'cdx:github:checkout:persistCredentials') != false
101
+ and (
102
+ $propBool($, 'cdx:github:workflow:hasWritePermissions') = true
103
+ or $propBool($, 'cdx:github:job:hasWritePermissions') = true
104
+ )
105
+ ]
106
+ location: |
107
+ {
108
+ "bomRef": $."bom-ref",
109
+ "purl": purl,
110
+ "file": $prop($, 'cdx:github:workflow:file')
111
+ }
112
+ message: "Checkout step uses persist-credentials=true in privileged workflow; consider persist-credentials: false;"
113
+ mitigation: "Add persist-credentials: false to checkout steps that don't require git push operations"
114
+ evidence: |
115
+ {
116
+ "persistCredentials": $prop($, 'cdx:github:checkout:persistCredentials'),
117
+ "workflowPermissions": $prop($, 'cdx:github:workflow:hasWritePermissions')
118
+ }
119
+ - id: CI-006
120
+ name: "Cache usage in untrusted trigger context"
121
+ description: "GitHub Actions cache can be poisoned when used in workflows triggered by untrusted input (e.g., pull_request from forks)"
122
+ severity: high
123
+ category: ci-permission
124
+ condition: |
125
+ components[
126
+ $nullSafeProp($, 'cdx:github:action:uses') ~> $contains('actions/cache')
127
+ and $nullSafeProp($, 'cdx:github:workflow:triggers') ~> $contains('pull_request')
128
+ ]
129
+ location: |
130
+ {
131
+ "bomRef": $."bom-ref",
132
+ "purl": purl,
133
+ "file": $prop($, 'cdx:github:workflow:file')
134
+ }
135
+ message: "Cache action used in pull_request-triggered workflow; cache key '{{ $prop($, 'cdx:github:cache:key') }}' may be writable by untrusted code"
136
+ mitigation: "Scope cache keys to PR-specific values, validate restored cache contents, or avoid caching in untrusted workflows"
137
+ evidence: |
138
+ {
139
+ "cacheKey": $prop($, 'cdx:github:cache:key'),
140
+ "cachePath": $prop($, 'cdx:github:cache:path'),
141
+ "triggers": $prop($, 'cdx:github:workflow:triggers')
142
+ }
143
+ - id: CI-007
144
+ name: "Script injection via untrusted context interpolation"
145
+ description: "Direct interpolation of github.event.* or inputs.* into run: blocks enables command injection"
146
+ severity: critical
147
+ category: ci-permission
148
+ condition: |
149
+ formulation.components[
150
+ $prop($, 'cdx:github:step:hasUntrustedInterpolation') = 'true'
151
+ and $prop($, 'cdx:github:step:type') = 'run'
152
+ ]
153
+ location: |
154
+ {
155
+ "bomRef": $."bom-ref",
156
+ "file": $prop($, 'cdx:github:workflow:file')
157
+ }
158
+ message: "Untrusted input interpolated into shell command: variables '{{ $prop($, 'cdx:github:step:interpolatedVars') }}'"
159
+ mitigation: "Use intermediate environment variables: env: TITLE: ${{ github.event.pull_request.title }} then reference $TITLE in run:"
160
+ evidence: |
161
+ {
162
+ "interpolatedVars": $prop($, 'cdx:github:step:interpolatedVars'),
163
+ "stepCommand": $prop($, 'cdx:github:step:command')
164
+ }
165
+ - id: CI-008
166
+ name: "High-risk trigger with write permissions"
167
+ description: "Triggers like pull_request_target, issue_comment, or workflow_run combined with write permissions enable privilege escalation"
168
+ severity: high
169
+ category: ci-permission
170
+ condition: |
171
+ formulation.workflows[
172
+ $prop($, 'cdx:github:workflow:hasHighRiskTrigger') = 'true'
173
+ and $prop($, 'cdx:github:workflow:hasWritePermissions') = 'true'
174
+ ]
175
+ location: |
176
+ {
177
+ "bomRef": $."bom-ref",
178
+ "file": $prop($, 'cdx:github:workflow:file')
179
+ }
180
+ message: "Workflow '{{ $prop($, 'cdx:github:workflow:name') }}' uses high-risk trigger with write permissions"
181
+ mitigation: "Use pull_request instead of pull_request_target; require manual approval for issue_comment triggers; restrict permissions per job"
182
+ evidence: |
183
+ {
184
+ "triggers": $prop($, 'cdx:github:workflow:triggers'),
185
+ "hasWritePermissions": $prop($, 'cdx:github:workflow:hasWritePermissions')
186
+ }
@@ -0,0 +1,123 @@
1
+ # Dependency Source Integrity Rules
2
+ # Category: dependency-source
3
+ # Evaluates package manager data for non-registry, local, or mutable sources
4
+ - id: PKG-001
5
+ name: "Install script from non-registry source"
6
+ description: "npm packages with install scripts from git/file/local sources increase supply chain attack surface"
7
+ severity: high
8
+ category: dependency-source
9
+ condition: |
10
+ components[
11
+ $prop($, 'cdx:npm:hasInstallScript') = 'true'
12
+ and $prop($, 'cdx:npm:isRegistryDependency') = 'false'
13
+ ]
14
+ location: |
15
+ { "bomRef": $."bom-ref", "purl": purl }
16
+ message: "npm package '{{ name }}@{{ version }}' executes install script from non-registry source"
17
+ mitigation: "Avoid git/file dependencies with lifecycle hooks; use registry dependencies or vendor explicitly"
18
+ evidence: |
19
+ {
20
+ "riskyScripts": $prop($, 'cdx:npm:risky_scripts'),
21
+ "resolvedPath": $prop($, 'cdx:npm:resolvedPath'),
22
+ "isLink": $prop($, 'cdx:npm:isLink')
23
+ }
24
+ - id: PKG-002
25
+ name: "Go module uses local replacement"
26
+ description: "Go modules with local_dir replacements are non-hermetic and may not be reproducible"
27
+ severity: high
28
+ category: dependency-source
29
+ condition: |
30
+ components[
31
+ $hasProp($, 'cdx:go:local_dir')
32
+ ]
33
+ location: |
34
+ { "bomRef": $."bom-ref", "purl": purl }
35
+ message: "Go module '{{ name }}' uses local replacement: {{ $prop($, 'cdx:go:local_dir') }}"
36
+ mitigation: "Use published module versions or vendor dependencies explicitly for reproducible builds"
37
+ evidence: |
38
+ {
39
+ "localDir": $prop($, 'cdx:go:local_dir'),
40
+ "toolchain": $prop($, 'cdx:go:toolchain')
41
+ }
42
+ - id: PKG-003
43
+ name: "Swift local checkout in build"
44
+ description: "Swift packages with localCheckoutPath indicate developer-only dependencies not suitable for release"
45
+ severity: high
46
+ category: dependency-source
47
+ condition: |
48
+ components[
49
+ $hasProp($, 'cdx:swift:localCheckoutPath')
50
+ ]
51
+ location: |
52
+ { "bomRef": $."bom-ref", "purl": purl }
53
+ message: "Swift package '{{ name }}' uses local checkout: {{ $prop($, 'cdx:swift:localCheckoutPath') }}"
54
+ mitigation: "Use remote package references (URL or registry) for release artifacts"
55
+ evidence: |
56
+ {
57
+ "checkoutPath": $prop($, 'cdx:swift:localCheckoutPath'),
58
+ "packageName": $prop($, 'cdx:swift:packageName')
59
+ }
60
+ - id: PKG-004
61
+ name: "Nix flake missing reproducibility metadata"
62
+ description: "Nix dependencies without revision or nar_hash cannot be verified for content integrity"
63
+ severity: high
64
+ category: dependency-source
65
+ condition: |
66
+ components[
67
+ $startsWith(purl, 'pkg:nix/')
68
+ and (
69
+ $prop($, 'cdx:nix:revision') = null
70
+ or $prop($, 'cdx:nix:nar_hash') = null
71
+ )
72
+ ]
73
+ location: |
74
+ { "bomRef": $."bom-ref", "purl": purl }
75
+ message: "Nix package '{{ name }}' missing reproducibility metadata (revision or nar_hash)"
76
+ mitigation: "Ensure flake.lock includes both revision and nar_hash for content-addressed reproducibility"
77
+ evidence: |
78
+ {
79
+ "inputUrl": $prop($, 'cdx:nix:input_url'),
80
+ "ref": $prop($, 'cdx:nix:ref'),
81
+ "hasRevision": $hasProp($, 'cdx:nix:revision'),
82
+ "hasNarHash": $hasProp($, 'cdx:nix:nar_hash')
83
+ }
84
+ - id: PKG-005
85
+ name: "Ruby gem tracks mutable branch"
86
+ description: "Ruby gems sourced from git branches (without revision pin) can change unexpectedly"
87
+ severity: medium
88
+ category: dependency-source
89
+ condition: |
90
+ components[
91
+ $hasProp($, 'cdx:gem:remoteBranch')
92
+ and $hasProp($, 'cdx:gem:remoteRevision')
93
+ ]
94
+ location: |
95
+ { "bomRef": $."bom-ref", "purl": purl }
96
+ message: "Ruby gem '{{ name }}' tracks mutable branch '{{ $prop($, 'cdx:gem:remoteBranch') }}' without commit pin"
97
+ mitigation: "Pin to specific revision: gem 'foo', git: '...', ref: '<commit-sha>'"
98
+ evidence: |
99
+ {
100
+ "remote": $prop($, 'cdx:gem:remote'),
101
+ "branch": $prop($, 'cdx:gem:remoteBranch'),
102
+ "tag": $prop($, 'cdx:gem:remoteTag')
103
+ }
104
+ - id: PKG-006
105
+ name: "Python dependency from non-approved registry"
106
+ description: "PyPI packages from unapproved registries may introduce unvetted code"
107
+ severity: low
108
+ category: dependency-source
109
+ condition: |
110
+ components[
111
+ $hasProp($, 'cdx:pypi:registry')
112
+ and $prop($, 'cdx:pypi:registry') != 'https://pypi.org/simple'
113
+ and $prop($, 'cdx:pypi:registry') != 'https://pypi.org'
114
+ ]
115
+ location: |
116
+ { "bomRef": $."bom-ref", "purl": purl }
117
+ message: "Python package '{{ name }}' sourced from non-default registry: {{ $prop($, 'cdx:pypi:registry') }}"
118
+ mitigation: "Verify registry trustworthiness"
119
+ evidence: |
120
+ {
121
+ "registry": $prop($, 'cdx:pypi:registry'),
122
+ "resolvedFrom": $prop($, 'cdx:pypi:resolved_from')
123
+ }
@@ -0,0 +1,135 @@
1
+ # Package Integrity and Lifecycle Rules
2
+ # Category: package-integrity
3
+ # Detects deprecated, yanked, or tampered packages and suspicious metadata
4
+
5
+ - id: INT-001
6
+ name: "npm package with install script"
7
+ description: "npm packages with lifecycle hooks (preinstall, postinstall, etc.) execute arbitrary code during installation"
8
+ severity: medium
9
+ category: package-integrity
10
+ condition: |
11
+ components[
12
+ $prop($, 'cdx:npm:hasInstallScript') = 'true'
13
+ ]
14
+ location: |
15
+ { "bomRef": $."bom-ref", "purl": purl }
16
+ message: "npm package '{{ name }}@{{ version }}' has install-time execution hooks"
17
+ mitigation: "Review install scripts before use. Consider using --ignore-scripts or an allowlist-based approach"
18
+ evidence: |
19
+ {
20
+ "riskyScripts": $prop($, 'cdx:npm:risky_scripts'),
21
+ "isRegistryDependency": $prop($, 'cdx:npm:isRegistryDependency')
22
+ }
23
+
24
+ - id: INT-002
25
+ name: "npm package name or version mismatch"
26
+ description: "Detected mismatch between expected and resolved package name or version, which may indicate dependency confusion or tampering"
27
+ severity: high
28
+ category: package-integrity
29
+ condition: |
30
+ components[
31
+ $hasProp($, 'cdx:npm:nameMismatchError')
32
+ or $hasProp($, 'cdx:npm:versionMismatchError')
33
+ ]
34
+ location: |
35
+ { "bomRef": $."bom-ref", "purl": purl }
36
+ message: "npm package '{{ name }}@{{ version }}' has a name or version mismatch"
37
+ mitigation: "Investigate the mismatch immediately. This may indicate dependency confusion, registry tampering, or a corrupted lockfile"
38
+ evidence: |
39
+ {
40
+ "nameMismatch": $prop($, 'cdx:npm:nameMismatchError'),
41
+ "versionMismatch": $prop($, 'cdx:npm:versionMismatchError')
42
+ }
43
+
44
+ - id: INT-003
45
+ name: "Deprecated Go module"
46
+ description: "Go modules marked as deprecated may contain known issues or be abandoned"
47
+ severity: medium
48
+ category: package-integrity
49
+ condition: |
50
+ components[
51
+ $hasProp($, 'cdx:go:deprecated')
52
+ ]
53
+ location: |
54
+ { "bomRef": $."bom-ref", "purl": purl }
55
+ message: "Go module '{{ name }}' is deprecated: {{ $prop($, 'cdx:go:deprecated') }}"
56
+ mitigation: "Migrate to the recommended replacement module or assess continued usage risk"
57
+ evidence: |
58
+ {
59
+ "deprecationNotice": $prop($, 'cdx:go:deprecated'),
60
+ "isIndirect": $prop($, 'cdx:go:indirect')
61
+ }
62
+
63
+ - id: INT-004
64
+ name: "Yanked Ruby gem in dependency tree"
65
+ description: "Yanked gems have been removed from RubyGems, typically due to security issues or critical bugs"
66
+ severity: high
67
+ category: package-integrity
68
+ condition: |
69
+ components[
70
+ $prop($, 'cdx:gem:yanked') = 'true'
71
+ ]
72
+ location: |
73
+ { "bomRef": $."bom-ref", "purl": purl }
74
+ message: "Ruby gem '{{ name }}@{{ version }}' has been yanked from RubyGems"
75
+ mitigation: "Update to a non-yanked version immediately. Yanked gems are typically removed due to security or correctness issues"
76
+ evidence: |
77
+ {
78
+ "platform": $prop($, 'cdx:gem:platform'),
79
+ "isPrerelease": $prop($, 'cdx:gem:prerelease')
80
+ }
81
+
82
+ - id: INT-005
83
+ name: "npm deprecated package"
84
+ description: "npm packages marked as deprecated may have known vulnerabilities or unmaintained code"
85
+ severity: low
86
+ category: package-integrity
87
+ condition: |
88
+ components[
89
+ $prop($, 'cdx:npm:deprecated') = 'true'
90
+ ]
91
+ location: |
92
+ { "bomRef": $."bom-ref", "purl": purl }
93
+ message: "npm package '{{ name }}@{{ version }}' is deprecated: {{ $prop($, 'cdx:npm:deprecation_notice') }}"
94
+ mitigation: "Migrate to a maintained alternative package"
95
+ evidence: |
96
+ {
97
+ "deprecationNotice": $prop($, 'cdx:npm:deprecation_notice')
98
+ }
99
+
100
+ - id: INT-006
101
+ name: "Dart pub uses non-default registry"
102
+ description: "Dart packages from non-default registries may introduce unvetted code"
103
+ severity: low
104
+ category: package-integrity
105
+ condition: |
106
+ components[
107
+ $hasProp($, 'cdx:pub:registry')
108
+ ]
109
+ location: |
110
+ { "bomRef": $."bom-ref", "purl": purl }
111
+ message: "Dart package '{{ name }}' sourced from non-default registry: {{ $prop($, 'cdx:pub:registry') }}"
112
+ mitigation: "Verify registry trustworthiness"
113
+ evidence: |
114
+ {
115
+ "registry": $prop($, 'cdx:pub:registry')
116
+ }
117
+
118
+ - id: INT-007
119
+ name: "Maven shaded/relocated package"
120
+ description: "Maven packages with shaded or relocated classes may obscure the true dependency graph and introduce hidden vulnerabilities"
121
+ severity: low
122
+ category: package-integrity
123
+ condition: |
124
+ components[
125
+ $prop($, 'cdx:maven:shaded') = 'true'
126
+ ]
127
+ location: |
128
+ { "bomRef": $."bom-ref", "purl": purl }
129
+ message: "Maven package '{{ name }}@{{ version }}' contains shaded/relocated classes"
130
+ mitigation: "Prefer non-shaded dependency variants where available to maintain transparent dependency resolution"
131
+ evidence: |
132
+ {
133
+ "unshadedNamespaces": $prop($, 'cdx:maven:unshadedNamespaces'),
134
+ "scope": $prop($, 'cdx:maven:component_scope')
135
+ }
@@ -0,0 +1,228 @@
1
+ # VS Code Extension Security Rules
2
+ # Category: vscode-extension
3
+ # Evaluates VS Code extensions for install-time execution, host access, and workspace trust risks
4
+
5
+ - id: VSC-001
6
+ name: "Extension with install-time lifecycle scripts"
7
+ description: "VS Code extensions with postinstall/preinstall scripts execute arbitrary code during installation"
8
+ severity: critical
9
+ category: vscode-extension
10
+ condition: |
11
+ components[
12
+ $startsWith(purl, 'pkg:vscode-extension/')
13
+ and $hasProp($, 'cdx:vscode-extension:lifecycleScripts')
14
+ ]
15
+ location: |
16
+ {
17
+ "bomRef": $. "bom-ref",
18
+ "purl": purl,
19
+ "srcFile": $prop($, 'SrcFile')
20
+ }
21
+ message: "VS Code extension '{{ publisher }}.{{ name }}@{{ version }}' executes lifecycle scripts: {{ $prop($, 'cdx:vscode-extension:lifecycleScripts') }}"
22
+ mitigation: "Review extension source code before installation; prefer extensions without install-time scripts; use workspace trust boundaries"
23
+ evidence: |
24
+ {
25
+ "lifecycleScripts": $prop($, 'cdx:vscode-extension:lifecycleScripts'),
26
+ "mainEntryPoint": $prop($, 'cdx:vscode-extension:main'),
27
+ "browserEntryPoint": $prop($, 'cdx:vscode-extension:browser')
28
+ }
29
+
30
+ - id: VSC-002
31
+ name: "Always-on extension with terminal access"
32
+ description: "Extensions activating on '*' with terminal-access contribution can execute commands in any workspace"
33
+ severity: high
34
+ category: vscode-extension
35
+ condition: |
36
+ components[
37
+ $startsWith(purl, 'pkg:vscode-extension/')
38
+ and $listContains($propList($, 'cdx:vscode-extension:activationEvents'), '*')
39
+ and $listContains($propList($, 'cdx:vscode-extension:contributes'), 'terminal-access')
40
+ ]
41
+ location: |
42
+ {
43
+ "bomRef": $. "bom-ref",
44
+ "purl": purl
45
+ }
46
+ message: "Always-on VS Code extension '{{ publisher }}.{{ name }}' has terminal access capability"
47
+ mitigation: "Disable extension in untrusted workspaces; review contributed commands for injection risks; restrict via workspace trust settings"
48
+ evidence: |
49
+ {
50
+ "activationEvents": $prop($, 'cdx:vscode-extension:activationEvents'),
51
+ "contributes": $prop($, 'cdx:vscode-extension:contributes'),
52
+ "extensionKind": $prop($, 'cdx:vscode-extension:extensionKind')
53
+ }
54
+
55
+ - id: VSC-003
56
+ name: "Extension runs in untrusted workspaces with filesystem access"
57
+ description: "Extensions supporting untrustedWorkspaces=true with filesystem-provider contributions may access sensitive files"
58
+ severity: high
59
+ category: vscode-extension
60
+ condition: |
61
+ components[
62
+ $startsWith(purl, 'pkg:vscode-extension/')
63
+ and $propBool($, 'cdx:vscode-extension:untrustedWorkspaces') = true
64
+ and $listContains($propList($, 'cdx:vscode-extension:contributes'), 'filesystem-provider')
65
+ ]
66
+ location: |
67
+ {
68
+ "bomRef": $. "bom-ref",
69
+ "purl": purl
70
+ }
71
+ message: "VS Code extension '{{ publisher }}.{{ name }}' operates in untrusted workspaces with filesystem access"
72
+ mitigation: "Set workspace trust to 'limited' for this extension; audit filesystem-provider implementations; avoid using in sensitive projects"
73
+ evidence: |
74
+ {
75
+ "untrustedWorkspaces": $prop($, 'cdx:vscode-extension:untrustedWorkspaces'),
76
+ "contributes": $prop($, 'cdx:vscode-extension:contributes'),
77
+ "virtualWorkspaces": $prop($, 'cdx:vscode-extension:virtualWorkspaces')
78
+ }
79
+
80
+ - id: VSC-004
81
+ name: "Extension pack with risky member extensions"
82
+ description: "Extension packs implicitly install bundled extensions; flag packs containing members with lifecycle scripts or privileged capabilities"
83
+ severity: medium
84
+ category: vscode-extension
85
+ condition: |
86
+ components[
87
+ $startsWith(purl, 'pkg:vscode-extension/')
88
+ and $hasProp($, 'cdx:vscode-extension:extensionPack')
89
+ ]
90
+ location: |
91
+ {
92
+ "bomRef": $. "bom-ref",
93
+ "purl": purl
94
+ }
95
+ message: "VS Code extension pack '{{ publisher }}.{{ name }}' bundles extensions: {{ $prop($, 'cdx:vscode-extension:extensionPack') }}"
96
+ mitigation: "Review each bundled extension individually; prefer installing extensions explicitly rather than via packs"
97
+ evidence: |
98
+ {
99
+ "extensionPack": $prop($, 'cdx:vscode-extension:extensionPack'),
100
+ "extensionDependencies": $prop($, 'cdx:vscode-extension:extensionDependencies')
101
+ }
102
+
103
+ - id: VSC-005
104
+ name: "Extension dependency chain with execution risk"
105
+ description: "Extensions depending on other extensions inherit their trust boundary; flag chains where dependencies have install scripts or privileged access"
106
+ severity: medium
107
+ category: vscode-extension
108
+ condition: |
109
+ components[
110
+ $startsWith(purl, 'pkg:vscode-extension/')
111
+ and $hasProp($, 'cdx:vscode-extension:extensionDependencies')
112
+ ]
113
+ location: |
114
+ {
115
+ "bomRef": $. "bom-ref",
116
+ "purl": purl
117
+ }
118
+ message: "VS Code extension '{{ publisher }}.{{ name }}' depends on extensions: {{ $prop($, 'cdx:vscode-extension:extensionDependencies') }}"
119
+ mitigation: "Audit all dependency extensions for lifecycle scripts and privileged contributions; prefer extensions with minimal dependency chains"
120
+ evidence: |
121
+ {
122
+ "extensionDependencies": $prop($, 'cdx:vscode-extension:extensionDependencies'),
123
+ "lifecycleScripts": $prop($, 'cdx:vscode-extension:lifecycleScripts')
124
+ }
125
+
126
+ - id: VSC-006
127
+ name: "Extension with debugger or authentication provider contributions"
128
+ description: "Extensions contributing debuggers or authentication providers have elevated host access and credential handling capabilities"
129
+ severity: high
130
+ category: vscode-extension
131
+ condition: |
132
+ components[
133
+ $startsWith(purl, 'pkg:vscode-extension/')
134
+ and (
135
+ $listContains($propList($, 'cdx:vscode-extension:contributes'), 'debuggers')
136
+ or $listContains($propList($, 'cdx:vscode-extension:contributes'), 'authentication-provider')
137
+ )
138
+ ]
139
+ location: |
140
+ {
141
+ "bomRef": $. "bom-ref",
142
+ "purl": purl
143
+ }
144
+ message: "VS Code extension '{{ publisher }}.{{ name }}' contributes privileged capabilities: {{ $prop($, 'cdx:vscode-extension:contributes') }}"
145
+ mitigation: "Review extension source for credential handling; restrict to trusted workspaces; audit debugger attach permissions"
146
+ evidence: |
147
+ {
148
+ "contributes": $prop($, 'cdx:vscode-extension:contributes'),
149
+ "executesCode": $prop($, 'cdx:vscode-extension:executesCode'),
150
+ "extensionKind": $prop($, 'cdx:vscode-extension:extensionKind')
151
+ }
152
+
153
+ - id: VSC-007
154
+ name: "Extension running in workspace context with code execution"
155
+ description: "Extensions with extensionKind=workspace and executesCode=true run arbitrary code on remote hosts or containers"
156
+ severity: high
157
+ category: vscode-extension
158
+ condition: |
159
+ components[
160
+ $startsWith(purl, 'pkg:vscode-extension/')
161
+ and $listContains($propList($, 'cdx:vscode-extension:extensionKind'), 'workspace')
162
+ and $propBool($, 'cdx:vscode-extension:executesCode') = true
163
+ ]
164
+ location: |
165
+ {
166
+ "bomRef": $. "bom-ref",
167
+ "purl": purl
168
+ }
169
+ message: "VS Code extension '{{ publisher }}.{{ name }}' executes code in workspace (remote) context"
170
+ mitigation: "Verify extension source before use in remote development; restrict workspace extensions to trusted publishers"
171
+ evidence: |
172
+ {
173
+ "extensionKind": $prop($, 'cdx:vscode-extension:extensionKind'),
174
+ "executesCode": $prop($, 'cdx:vscode-extension:executesCode'),
175
+ "main": $prop($, 'cdx:vscode-extension:main')
176
+ }
177
+
178
+ - id: VSC-008
179
+ name: "Extension with outdated VS Code engine requirement"
180
+ description: "Extensions requiring VS Code engine <1.80 may lack workspace trust and other modern security features"
181
+ severity: low
182
+ category: vscode-extension
183
+ condition: |
184
+ components[
185
+ $startsWith(purl, 'pkg:vscode-extension/')
186
+ and $hasProp($, 'cdx:vscode-extension:vscodeEngine')
187
+ and $count($match($prop($, 'cdx:vscode-extension:vscodeEngine'), /(\^|>=)?1\.(8[0-9]|9[0-9])\./)) = 0
188
+ ]
189
+ location: |
190
+ {
191
+ "bomRef": $. "bom-ref",
192
+ "purl": purl
193
+ }
194
+ message: "VS Code extension '{{ publisher }}.{{ name }}' requires outdated engine: {{ $prop($, 'cdx:vscode-extension:vscodeEngine') }}"
195
+ mitigation: "Update extension or VS Code to ensure modern security features are available; contact publisher for updates"
196
+ evidence: |
197
+ {
198
+ "vscodeEngine": $prop($, 'cdx:vscode-extension:vscodeEngine'),
199
+ "version": version
200
+ }
201
+
202
+ - id: VSC-009
203
+ name: "Extension with browser entry point but no sandbox declaration"
204
+ description: "Extensions declaring browser entry points should run in web sandbox; flag if also declares workspace execution or filesystem access"
205
+ severity: medium
206
+ category: vscode-extension
207
+ condition: |
208
+ components[
209
+ $startsWith(purl, 'pkg:vscode-extension/')
210
+ and $hasProp($, 'cdx:vscode-extension:browser')
211
+ and (
212
+ $listContains($propList($, 'cdx:vscode-extension:extensionKind'), 'workspace')
213
+ or $listContains($propList($, 'cdx:vscode-extension:contributes'), 'filesystem-provider')
214
+ )
215
+ ]
216
+ location: |
217
+ {
218
+ "bomRef": $. "bom-ref",
219
+ "purl": purl
220
+ }
221
+ message: "VS Code extension '{{ publisher }}.{{ name }}' has browser entry point but also declares workspace/filesystem capabilities"
222
+ mitigation: "Clarify extension execution context; prefer separate web/native extension variants; audit cross-context data flows"
223
+ evidence: |
224
+ {
225
+ "browser": $prop($, 'cdx:vscode-extension:browser'),
226
+ "main": $prop($, 'cdx:vscode-extension:main'),
227
+ "contributes": $prop($, 'cdx:vscode-extension:contributes')
228
+ }