@cdxgen/cdxgen 13.4.0 → 13.5.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 +7 -7
- package/bin/cdxgen-secure.js +15 -0
- package/bin/cdxgen.js +25 -5
- package/bin/evinse.js +5 -0
- package/bin/hbom.js +15 -7
- package/bin/repl.js +29 -0
- package/data/cbomosdb-queries.json +13 -1
- package/data/component-tags.json +8 -0
- package/data/queries-darwin.json +25 -1
- package/data/queries-win.json +19 -1
- package/data/queries.json +41 -0
- package/data/remediations.json +283 -1
- package/data/rules/cbom-security.yaml +235 -4
- package/data/rules/go-binaries.yaml +46 -0
- package/data/rules/golem-go.yaml +80 -0
- package/data/rules/hbom-compliance.yaml +40 -22
- package/data/rules/hbom-performance.yaml +7 -1
- package/data/rules/host-topology.yaml +1 -1
- package/data/rules/obom-runtime.yaml +31 -2
- package/data/rules/php-runtime.yaml +143 -0
- package/lib/audit/index.js +14 -0
- package/lib/cli/bomAssembly.js +28 -3
- package/lib/cli/cliOptions.js +110 -3
- package/lib/cli/index.js +73 -4
- package/lib/cli/jvmBom.js +126 -20
- package/lib/cli/managedBom.js +711 -71
- package/lib/cli/nativeBom.js +225 -28
- package/lib/core/env.js +30 -8
- package/lib/core/fs.js +28 -19
- package/lib/core/httpClient.js +74 -45
- package/lib/core/projectConfig.js +1 -0
- package/lib/core/projectTooling.js +97 -0
- package/lib/core/propertySanitizer.js +72 -0
- package/lib/ecosystems/golem.js +550 -6
- package/lib/ecosystems/gradleutils.js +30 -20
- package/lib/ecosystems/parsers-dotnet.js +117 -18
- package/lib/ecosystems/parsers-go.js +1090 -367
- package/lib/ecosystems/parsers-jvm.js +259 -17
- package/lib/ecosystems/parsers-misc.js +229 -44
- package/lib/ecosystems/parsers-python.js +11 -10
- package/lib/ecosystems/rubyutils.js +6 -3
- package/lib/ecosystems/rusi.js +10 -0
- package/lib/ecosystems/scalacliutils.js +2 -1
- package/lib/ecosystems/scalasem.js +3 -1
- package/lib/evinser/evinser.js +126 -18
- package/lib/evinser/swiftsem.js +68 -5
- package/lib/inventory/agentSkillSpec.js +17 -0
- package/lib/inventory/apkInstalledDb.js +243 -0
- package/lib/inventory/atomUtils.js +33 -0
- package/lib/inventory/auditCategories.js +3 -3
- package/lib/inventory/cacheDir.js +52 -9
- package/lib/inventory/certificates.js +2371 -0
- package/lib/inventory/communityAiConfigParser.js +4 -9
- package/lib/inventory/deps.js +6 -4
- package/lib/inventory/display.js +200 -3
- package/lib/inventory/dosai.js +500 -58
- package/lib/inventory/dynamic.js +45 -3
- package/lib/inventory/envcontext.js +168 -5
- package/lib/inventory/evidenceUtils.js +436 -23
- package/lib/inventory/formulationParsers.js +3 -2
- package/lib/inventory/goBuildInfo.js +140 -0
- package/lib/inventory/hbom.js +67 -7
- package/lib/inventory/hbomAnalysis.js +16 -0
- package/lib/inventory/hostTopology.js +21 -0
- package/lib/inventory/osPackagePurl.js +244 -0
- package/lib/inventory/osPackageResolver.js +89 -87
- package/lib/inventory/osinfo.js +79 -31
- package/lib/inventory/osqueryTransform.js +114 -5
- package/lib/inventory/phpBuildInfo.js +487 -0
- package/lib/inventory/phpHostProbe.js +641 -0
- package/lib/inventory/rootfsCerts.js +426 -0
- package/lib/inventory/source.js +207 -3
- package/lib/inventory/spdx.js +144 -0
- package/lib/inventory/traceRunner.js +5 -1
- package/lib/inventory/tracedCrypto.js +129 -0
- package/lib/managers/binary.js +529 -183
- package/lib/managers/docker.js +166 -12
- package/lib/parsers/email.js +277 -0
- package/lib/parsers/largeJson.js +34 -2
- package/lib/server/server.js +186 -1
- package/lib/stages/postgen/annotator.js +17 -1
- package/lib/stages/postgen/introspection/reflect.js +4 -1
- package/lib/stages/postgen/postgen.js +5 -5
- package/lib/stages/postgen/ruleEngine.js +58 -1
- package/lib/stages/postgen/specVersionCompat.js +30 -0
- package/lib/stages/pregen/pregen.js +117 -5
- package/lib/validator/bomValidator.js +26 -5
- package/lib/validator/generated/runtime.mjs +13 -0
- package/lib/validator/generated/validate-1.6.mjs +26 -7
- package/lib/validator/generated/validate-1.7.mjs +31 -12
- package/lib/validator/generated/validate-2.0.mjs +30 -11
- package/package.json +17 -17
- package/types/bin/cdxgen-secure.d.ts +3 -0
- package/types/bin/cdxgen-secure.d.ts.map +1 -0
- package/types/bin/repl.d.ts.map +1 -1
- package/types/lib/audit/index.d.ts.map +1 -1
- package/types/lib/cli/bomAssembly.d.ts +9 -2
- package/types/lib/cli/bomAssembly.d.ts.map +1 -1
- package/types/lib/cli/cliOptions.d.ts +43 -0
- package/types/lib/cli/cliOptions.d.ts.map +1 -1
- package/types/lib/cli/index.d.ts.map +1 -1
- package/types/lib/cli/jvmBom.d.ts +20 -0
- package/types/lib/cli/jvmBom.d.ts.map +1 -1
- package/types/lib/cli/managedBom.d.ts.map +1 -1
- package/types/lib/cli/nativeBom.d.ts.map +1 -1
- package/types/lib/core/env.d.ts +18 -2
- package/types/lib/core/env.d.ts.map +1 -1
- package/types/lib/core/fs.d.ts.map +1 -1
- package/types/lib/core/httpClient.d.ts.map +1 -1
- package/types/lib/core/projectConfig.d.ts.map +1 -1
- package/types/lib/core/projectTooling.d.ts +41 -0
- package/types/lib/core/projectTooling.d.ts.map +1 -0
- package/types/lib/core/propertySanitizer.d.ts +26 -0
- package/types/lib/core/propertySanitizer.d.ts.map +1 -1
- package/types/lib/ecosystems/cppEvidence.d.ts +1 -1
- package/types/lib/ecosystems/golem.d.ts +81 -1
- package/types/lib/ecosystems/golem.d.ts.map +1 -1
- package/types/lib/ecosystems/gradleutils.d.ts +10 -8
- package/types/lib/ecosystems/gradleutils.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-dotnet.d.ts +40 -4
- package/types/lib/ecosystems/parsers-dotnet.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-go.d.ts +85 -13
- package/types/lib/ecosystems/parsers-go.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-jvm.d.ts +28 -2
- package/types/lib/ecosystems/parsers-jvm.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-misc.d.ts +18 -58
- package/types/lib/ecosystems/parsers-misc.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-python.d.ts +4 -3
- package/types/lib/ecosystems/parsers-python.d.ts.map +1 -1
- package/types/lib/ecosystems/pythonutils.d.ts +1 -1
- package/types/lib/ecosystems/rubyutils.d.ts.map +1 -1
- package/types/lib/ecosystems/rusi.d.ts.map +1 -1
- package/types/lib/ecosystems/scalacliutils.d.ts.map +1 -1
- package/types/lib/ecosystems/scalasem.d.ts.map +1 -1
- package/types/lib/evinser/evinser.d.ts +25 -0
- package/types/lib/evinser/evinser.d.ts.map +1 -1
- package/types/lib/evinser/swiftsem.d.ts +10 -0
- package/types/lib/evinser/swiftsem.d.ts.map +1 -1
- package/types/lib/inventory/agentSkillSpec.d.ts +13 -0
- package/types/lib/inventory/agentSkillSpec.d.ts.map +1 -0
- package/types/lib/inventory/apkInstalledDb.d.ts +42 -0
- package/types/lib/inventory/apkInstalledDb.d.ts.map +1 -0
- package/types/lib/inventory/atomUtils.d.ts +14 -0
- package/types/lib/inventory/atomUtils.d.ts.map +1 -1
- package/types/lib/inventory/cacheDir.d.ts +12 -4
- package/types/lib/inventory/cacheDir.d.ts.map +1 -1
- package/types/lib/inventory/certificates.d.ts +205 -0
- package/types/lib/inventory/certificates.d.ts.map +1 -0
- package/types/lib/inventory/communityAiConfigParser.d.ts.map +1 -1
- package/types/lib/inventory/deps.d.ts +2 -1
- package/types/lib/inventory/deps.d.ts.map +1 -1
- package/types/lib/inventory/display.d.ts +18 -0
- package/types/lib/inventory/display.d.ts.map +1 -1
- package/types/lib/inventory/dosai.d.ts +145 -6
- package/types/lib/inventory/dosai.d.ts.map +1 -1
- package/types/lib/inventory/dynamic.d.ts +6 -1
- package/types/lib/inventory/dynamic.d.ts.map +1 -1
- package/types/lib/inventory/envcontext.d.ts +40 -2
- package/types/lib/inventory/envcontext.d.ts.map +1 -1
- package/types/lib/inventory/evidenceUtils.d.ts +29 -10
- package/types/lib/inventory/evidenceUtils.d.ts.map +1 -1
- package/types/lib/inventory/formulationParsers.d.ts.map +1 -1
- package/types/lib/inventory/goBuildInfo.d.ts +10 -0
- package/types/lib/inventory/goBuildInfo.d.ts.map +1 -0
- package/types/lib/inventory/hbom.d.ts.map +1 -1
- package/types/lib/inventory/hbomAnalysis.d.ts +10 -0
- package/types/lib/inventory/hbomAnalysis.d.ts.map +1 -1
- package/types/lib/inventory/hostTopology.d.ts.map +1 -1
- package/types/lib/inventory/osPackagePurl.d.ts +99 -0
- package/types/lib/inventory/osPackagePurl.d.ts.map +1 -0
- package/types/lib/inventory/osPackageResolver.d.ts +6 -2
- package/types/lib/inventory/osPackageResolver.d.ts.map +1 -1
- package/types/lib/inventory/osinfo.d.ts +31 -6
- package/types/lib/inventory/osinfo.d.ts.map +1 -1
- package/types/lib/inventory/osqueryTransform.d.ts +51 -0
- package/types/lib/inventory/osqueryTransform.d.ts.map +1 -1
- package/types/lib/inventory/phpBuildInfo.d.ts +142 -0
- package/types/lib/inventory/phpBuildInfo.d.ts.map +1 -0
- package/types/lib/inventory/phpHostProbe.d.ts +35 -0
- package/types/lib/inventory/phpHostProbe.d.ts.map +1 -0
- package/types/lib/inventory/rootfsCerts.d.ts +27 -0
- package/types/lib/inventory/rootfsCerts.d.ts.map +1 -0
- package/types/lib/inventory/source.d.ts +28 -0
- package/types/lib/inventory/source.d.ts.map +1 -1
- package/types/lib/inventory/spdx.d.ts +15 -0
- package/types/lib/inventory/spdx.d.ts.map +1 -1
- package/types/lib/inventory/traceRunner.d.ts +4 -1
- package/types/lib/inventory/traceRunner.d.ts.map +1 -1
- package/types/lib/inventory/tracedCrypto.d.ts +22 -0
- package/types/lib/inventory/tracedCrypto.d.ts.map +1 -1
- package/types/lib/managers/binary.d.ts +10 -0
- package/types/lib/managers/binary.d.ts.map +1 -1
- package/types/lib/managers/docker.d.ts +12 -0
- package/types/lib/managers/docker.d.ts.map +1 -1
- package/types/lib/parsers/email.d.ts +19 -0
- package/types/lib/parsers/email.d.ts.map +1 -0
- package/types/lib/parsers/largeJson.d.ts +13 -0
- package/types/lib/parsers/largeJson.d.ts.map +1 -1
- package/types/lib/server/server.d.ts +8 -0
- 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/introspection/reflect.d.ts.map +1 -1
- package/types/lib/stages/postgen/ruleEngine.d.ts +7 -4
- package/types/lib/stages/postgen/ruleEngine.d.ts.map +1 -1
- package/types/lib/stages/postgen/specVersionCompat.d.ts.map +1 -1
- package/types/lib/stages/pregen/pregen.d.ts +14 -1
- package/types/lib/stages/pregen/pregen.d.ts.map +1 -1
- package/types/lib/validator/bomValidator.d.ts.map +1 -1
package/data/rules/golem-go.yaml
CHANGED
|
@@ -227,3 +227,83 @@
|
|
|
227
227
|
"goModExcludeCount": $prop($, 'cdx:golem:goModExcludeCount'),
|
|
228
228
|
"excludeModule": $prop($, 'cdx:golem:excludeModule')
|
|
229
229
|
}
|
|
230
|
+
|
|
231
|
+
- id: GOLEM-SEC-008
|
|
232
|
+
name: "Go component configures a custom TLS root pool"
|
|
233
|
+
description: "Golem reported a tls.Config RootCAs or x509.VerifyOptions Roots override, so the module validates certificates against a pool it supplies instead of the system roots"
|
|
234
|
+
severity: low
|
|
235
|
+
category: golem-security
|
|
236
|
+
dry-run-support: full
|
|
237
|
+
condition: |
|
|
238
|
+
components[
|
|
239
|
+
'GOLEM-CRYPTO-TLS-CUSTOM-ROOTS' in properties[name = 'cdx:golem:cryptoFinding'].value
|
|
240
|
+
]
|
|
241
|
+
location: |
|
|
242
|
+
{ "bomRef": $."bom-ref", "purl": purl }
|
|
243
|
+
message: "Go component '{{ name }}' sets a custom TLS root CA pool"
|
|
244
|
+
mitigation: "Review where the custom pool comes from and refresh it from a trusted source; a stale pool keeps trusting revoked or distrusted intermediates"
|
|
245
|
+
evidence: |
|
|
246
|
+
{
|
|
247
|
+
"finding": $prop($, 'cdx:golem:cryptoFinding'),
|
|
248
|
+
"severity": $prop($, 'cdx:golem:cryptoFindingSeverity')
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
- id: GOLEM-SEC-009
|
|
252
|
+
name: "Go component replaces certificate verification"
|
|
253
|
+
description: "Golem reported a VerifyPeerCertificate or VerifyConnection callback, so the module performs its own certificate validation instead of (part of) the standard chain verification"
|
|
254
|
+
severity: medium
|
|
255
|
+
category: golem-security
|
|
256
|
+
dry-run-support: full
|
|
257
|
+
condition: |
|
|
258
|
+
components[
|
|
259
|
+
'GOLEM-CRYPTO-TLS-CUSTOM-VERIFY' in properties[name = 'cdx:golem:cryptoFinding'].value
|
|
260
|
+
]
|
|
261
|
+
location: |
|
|
262
|
+
{ "bomRef": $."bom-ref", "purl": purl }
|
|
263
|
+
message: "Go component '{{ name }}' installs a custom certificate verification callback"
|
|
264
|
+
mitigation: "Check that the callback still calls Certificate.Verify, or that its custom checks are at least as strict; hand-rolled verification can miss revoked or distrusted intermediates"
|
|
265
|
+
evidence: |
|
|
266
|
+
{
|
|
267
|
+
"finding": $prop($, 'cdx:golem:cryptoFinding'),
|
|
268
|
+
"severity": $prop($, 'cdx:golem:cryptoFindingSeverity')
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
- id: GOLEM-SEC-010
|
|
272
|
+
name: "Go component disables TLS verification while customising it"
|
|
273
|
+
description: "Golem reported an InsecureSkipVerify setting on a tls.Config that also customises verification, the pattern where Go's own distrust list no longer applies"
|
|
274
|
+
severity: high
|
|
275
|
+
category: golem-security
|
|
276
|
+
dry-run-support: full
|
|
277
|
+
condition: |
|
|
278
|
+
components[
|
|
279
|
+
'GOLEM-CRYPTO-TLS-VERIFY-REPLACED' in properties[name = 'cdx:golem:cryptoFinding'].value
|
|
280
|
+
]
|
|
281
|
+
location: |
|
|
282
|
+
{ "bomRef": $."bom-ref", "purl": purl }
|
|
283
|
+
message: "Go component '{{ name }}' sets InsecureSkipVerify together with custom verification"
|
|
284
|
+
mitigation: "Remove InsecureSkipVerify and implement the required checks inside VerifyPeerCertificate on top of the standard chain verification"
|
|
285
|
+
evidence: |
|
|
286
|
+
{
|
|
287
|
+
"finding": $prop($, 'cdx:golem:cryptoFinding'),
|
|
288
|
+
"severity": $prop($, 'cdx:golem:cryptoFindingSeverity')
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
- id: GOLEM-SEC-011
|
|
292
|
+
name: "Go component embeds a certificate pool"
|
|
293
|
+
description: "Golem reported a package-level //go:embed variable fed to x509.CertPool.AppendCertsFromPEM, so a private trust anchor travels inside the binary"
|
|
294
|
+
severity: low
|
|
295
|
+
category: golem-security
|
|
296
|
+
dry-run-support: full
|
|
297
|
+
condition: |
|
|
298
|
+
components[
|
|
299
|
+
'GOLEM-CRYPTO-X509-EMBEDDED-POOL' in properties[name = 'cdx:golem:cryptoFinding'].value
|
|
300
|
+
]
|
|
301
|
+
location: |
|
|
302
|
+
{ "bomRef": $."bom-ref", "purl": purl }
|
|
303
|
+
message: "Go component '{{ name }}' appends an embedded PEM bundle to an x509 pool"
|
|
304
|
+
mitigation: "Track the embedded bundle like any other trust store: refresh it when CAs change and confirm it contains none of the distrusted keys"
|
|
305
|
+
evidence: |
|
|
306
|
+
{
|
|
307
|
+
"finding": $prop($, 'cdx:golem:cryptoFinding'),
|
|
308
|
+
"severity": $prop($, 'cdx:golem:cryptoFindingSeverity')
|
|
309
|
+
}
|
|
@@ -16,26 +16,38 @@
|
|
|
16
16
|
- "1.1 Establish and Maintain Detailed Enterprise Asset Inventory"
|
|
17
17
|
condition: |
|
|
18
18
|
metadata.component[
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
19
|
+
(
|
|
20
|
+
$safeStr($prop($, 'cdx:hbom:platform')) = 'linux'
|
|
21
|
+
and $count(
|
|
22
|
+
$$.components[
|
|
23
|
+
$prop($, 'cdx:hbom:hardwareClass') = 'board'
|
|
24
|
+
and (
|
|
25
|
+
$hasProp($, 'cdx:hbom:boardVendor')
|
|
26
|
+
or $hasProp($, 'cdx:hbom:boardName')
|
|
27
|
+
or $hasProp($, 'cdx:hbom:biosVendor')
|
|
28
|
+
or $hasProp($, 'cdx:hbom:biosVersion')
|
|
29
|
+
or $hasProp($, 'cdx:hbom:firmwareDate')
|
|
30
|
+
)
|
|
31
|
+
]
|
|
32
|
+
) = 0
|
|
33
|
+
)
|
|
34
|
+
or (
|
|
35
|
+
$safeStr($prop($, 'cdx:hbom:platform')) = 'windows'
|
|
36
|
+
and $not(
|
|
37
|
+
$hasProp($, 'cdx:hbom:boardVendor')
|
|
38
|
+
or $hasProp($, 'cdx:hbom:boardName')
|
|
39
|
+
or $hasProp($, 'cdx:hbom:biosVendor')
|
|
40
|
+
or $hasProp($, 'cdx:hbom:biosVersion')
|
|
41
|
+
or $hasProp($, 'cdx:hbom:firmwareDate')
|
|
42
|
+
)
|
|
43
|
+
)
|
|
32
44
|
]
|
|
33
45
|
location: |
|
|
34
46
|
{
|
|
35
47
|
"bomRef": $firstNonEmpty($."bom-ref", bom.serialNumber)
|
|
36
48
|
}
|
|
37
49
|
message: "HBOM for '{{ name }}' lacks board or firmware provenance fields needed for governance review"
|
|
38
|
-
mitigation: "Enable richer firmware/board collection on supported Linux hosts, validate SMBIOS access, and ensure the inventory captures board vendor, board name, BIOS vendor, BIOS version, and firmware date where available."
|
|
50
|
+
mitigation: "Enable richer firmware/board collection on supported Linux hosts, validate SMBIOS access, and ensure the inventory captures board vendor, board name, BIOS vendor, BIOS version, and firmware date where available. On Windows these come from the windows-cim-platform batch, which a network logon (SSH, WinRM) as a non-administrator cannot run: collect from a local session or an elevated one."
|
|
39
51
|
evidence: |
|
|
40
52
|
{
|
|
41
53
|
"platform": $prop($, 'cdx:hbom:platform'),
|
|
@@ -142,7 +154,7 @@
|
|
|
142
154
|
"bomRef": $firstNonEmpty($."bom-ref", bom.serialNumber)
|
|
143
155
|
}
|
|
144
156
|
message: "HBOM for '{{ name }}' includes storage volumes but no explicit encryption posture evidence"
|
|
145
|
-
mitigation: "Enable volume-level enrichment on supported platforms or pair the HBOM with equivalent host controls evidence so encryption compliance can be verified."
|
|
157
|
+
mitigation: "Enable volume-level enrichment on supported platforms or pair the HBOM with equivalent host controls evidence so encryption compliance can be verified. On Windows, BitLocker status comes from the --privileged batch, so rerun from an elevated (Run as administrator) prompt with --privileged."
|
|
146
158
|
evidence: |
|
|
147
159
|
{
|
|
148
160
|
"storageVolumeCount": $count($$.components[$prop($, 'cdx:hbom:hardwareClass') = 'storage-volume']),
|
|
@@ -219,8 +231,8 @@
|
|
|
219
231
|
{
|
|
220
232
|
"bomRef": $firstNonEmpty($."bom-ref", bom.serialNumber)
|
|
221
233
|
}
|
|
222
|
-
message: "HBOM for '{{ name }}' hit permission-denied enrichments that likely require a rerun with --privileged"
|
|
223
|
-
mitigation: "Where policy allows, rerun HBOM collection with --privileged
|
|
234
|
+
message: "HBOM for '{{ name }}' hit permission-denied enrichments that likely require {{ $safeStr($prop($, 'cdx:hbom:platform')) = 'windows' ? 'a rerun from a local or elevated session' : 'a rerun with --privileged' }}"
|
|
235
|
+
mitigation: "Where policy allows, rerun HBOM collection with --privileged. On Linux, cdx-hbom then uses the documented non-interactive sudo path for permission-sensitive enrichments. On Windows it never elevates or prompts: run it from a local session (a non-administrator over SSH or WinRM is denied every WMI query) and, for the TPM, BitLocker and storage-reliability batch, from an elevated (Run as administrator) prompt."
|
|
224
236
|
evidence: |
|
|
225
237
|
{
|
|
226
238
|
"collectorProfile": $prop(bom, 'cdx:hbom:collectorProfile'),
|
|
@@ -260,7 +272,7 @@
|
|
|
260
272
|
|
|
261
273
|
- id: HBC-009
|
|
262
274
|
name: "HBOM board and BIOS provenance was blocked by permissions"
|
|
263
|
-
description: "When dmidecode-backed firmware and board enrichment is blocked, the HBOM may miss board-vendor, board-name, BIOS-version, and related governance evidence."
|
|
275
|
+
description: "When dmidecode-backed firmware and board enrichment is blocked on Linux, or Windows denies WMI to the whole session (a network logon), the HBOM may miss board-vendor, board-name, BIOS-version, and related governance evidence."
|
|
264
276
|
severity: medium
|
|
265
277
|
category: hbom-compliance
|
|
266
278
|
dry-run-support: full
|
|
@@ -270,15 +282,21 @@
|
|
|
270
282
|
- "SI-7 Software, Firmware, and Information Integrity"
|
|
271
283
|
condition: |
|
|
272
284
|
metadata.component[
|
|
273
|
-
|
|
274
|
-
|
|
285
|
+
(
|
|
286
|
+
$safeStr($prop($, 'cdx:hbom:platform')) = 'linux'
|
|
287
|
+
and $listContains($propList($$, 'cdx:hbom:analysis:permissionDeniedIds'), 'dmidecode-firmware-board')
|
|
288
|
+
)
|
|
289
|
+
or (
|
|
290
|
+
$safeStr($prop($, 'cdx:hbom:platform')) = 'windows'
|
|
291
|
+
and $listContains($propList($$, 'cdx:hbom:analysis:permissionDeniedIds'), 'windows-cim-platform:network-logon')
|
|
292
|
+
)
|
|
275
293
|
]
|
|
276
294
|
location: |
|
|
277
295
|
{
|
|
278
296
|
"bomRef": $firstNonEmpty($."bom-ref", bom.serialNumber)
|
|
279
297
|
}
|
|
280
|
-
message: "HBOM for '{{ name }}' could not capture full board and BIOS provenance because dmidecode enrichment was blocked"
|
|
281
|
-
mitigation: "Where policy allows, rerun with --privileged or equivalent access so the collector can gather firmware vendor, BIOS version, board vendor, and board name data."
|
|
298
|
+
message: "HBOM for '{{ name }}' could not capture full board and BIOS provenance because {{ $safeStr($prop($, 'cdx:hbom:platform')) = 'windows' ? 'WMI was denied to this network logon' : 'dmidecode enrichment was blocked' }}"
|
|
299
|
+
mitigation: "Where policy allows, rerun with --privileged or equivalent access so the collector can gather firmware vendor, BIOS version, board vendor, and board name data. On Windows, run HBOM from a local session or an elevated one instead of over SSH or WinRM as a non-administrator."
|
|
282
300
|
evidence: |
|
|
283
301
|
{
|
|
284
302
|
"collectorProfile": $prop(bom, 'cdx:hbom:collectorProfile'),
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
|
|
33
33
|
- id: HBP-002
|
|
34
34
|
name: "Storage health is degraded or wear is near exhaustion"
|
|
35
|
-
description: "Degraded SMART state or high wear percentage is a strong leading indicator of latency, failure, or replacement pressure."
|
|
35
|
+
description: "Degraded SMART state, a Warning or Unhealthy Windows storage health status, or high wear percentage is a strong leading indicator of latency, failure, or replacement pressure."
|
|
36
36
|
severity: high
|
|
37
37
|
category: hbom-performance
|
|
38
38
|
dry-run-support: full
|
|
@@ -50,6 +50,10 @@
|
|
|
50
50
|
and $lowercase($safeStr($prop($, 'cdx:hbom:smartStatus'))) != 'ok'
|
|
51
51
|
and $lowercase($safeStr($prop($, 'cdx:hbom:smartStatus'))) != 'passed'
|
|
52
52
|
)
|
|
53
|
+
or (
|
|
54
|
+
$lowercase($safeStr($prop($, 'cdx:hbom:healthStatus'))) = 'warning'
|
|
55
|
+
or $lowercase($safeStr($prop($, 'cdx:hbom:healthStatus'))) = 'unhealthy'
|
|
56
|
+
)
|
|
53
57
|
or (
|
|
54
58
|
$hasProp($, 'cdx:hbom:wearPercentageUsed')
|
|
55
59
|
and $number($prop($, 'cdx:hbom:wearPercentageUsed')) >= 80
|
|
@@ -65,6 +69,8 @@
|
|
|
65
69
|
evidence: |
|
|
66
70
|
{
|
|
67
71
|
"smartStatus": $prop($, 'cdx:hbom:smartStatus'),
|
|
72
|
+
"healthStatus": $prop($, 'cdx:hbom:healthStatus'),
|
|
73
|
+
"operationalStatus": $prop($, 'cdx:hbom:operationalStatus'),
|
|
68
74
|
"wearPercentageUsed": $prop($, 'cdx:hbom:wearPercentageUsed'),
|
|
69
75
|
"revision": $prop($, 'cdx:hbom:revision'),
|
|
70
76
|
"deviceSerial": $prop($, 'cdx:hbom:deviceSerial')
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
"bomRef": $firstNonEmpty($."bom-ref", bom.serialNumber)
|
|
91
91
|
}
|
|
92
92
|
message: "Merged host inventory for '{{ name }}' contains no strict HBOM-to-OBOM topology links"
|
|
93
|
-
mitigation: "Review collector coverage, ensure runtime categories such as interface_addresses or kernel_modules are available, and prefer exact identifier-bearing probes over heuristic joins."
|
|
93
|
+
mitigation: "Review collector coverage, ensure runtime categories such as interface_addresses or kernel_modules (logical_drives on Windows) are available, and prefer exact identifier-bearing probes over heuristic joins."
|
|
94
94
|
evidence: |
|
|
95
95
|
{
|
|
96
96
|
"hostViewMode": $prop($, 'cdx:hostview:mode'),
|
|
@@ -111,8 +111,9 @@
|
|
|
111
111
|
"deviceId": name,
|
|
112
112
|
"driveLetter": version,
|
|
113
113
|
"protectionStatus": $prop($, 'protection_status'),
|
|
114
|
-
"encryptionMethod":
|
|
115
|
-
"percentageEncrypted": $prop($, 'percentage_encrypted')
|
|
114
|
+
"encryptionMethod": description,
|
|
115
|
+
"percentageEncrypted": $prop($, 'percentage_encrypted'),
|
|
116
|
+
"protectorTypes": $prop($, 'protector_types')
|
|
116
117
|
}
|
|
117
118
|
|
|
118
119
|
- id: OBOM-WIN-002
|
|
@@ -1774,3 +1775,31 @@
|
|
|
1774
1775
|
"comment": description,
|
|
1775
1776
|
"uid": $prop($, 'uid')
|
|
1776
1777
|
}
|
|
1778
|
+
|
|
1779
|
+
- id: OBOM-LNX-023
|
|
1780
|
+
name: "Linux snap installed in devmode confinement"
|
|
1781
|
+
description: "A snap installed with --devmode runs without its sandbox being enforced: policy violations are only logged. Devmode is meant for snap development, not for software a host relies on."
|
|
1782
|
+
severity: medium
|
|
1783
|
+
category: obom-runtime
|
|
1784
|
+
dry-run-support: full
|
|
1785
|
+
condition: |
|
|
1786
|
+
components[
|
|
1787
|
+
$prop($, 'cdx:osquery:category') = 'snap_packages'
|
|
1788
|
+
and $lowercase($safeStr($prop($, 'cdx:snap:confinement'))) = 'devmode'
|
|
1789
|
+
]
|
|
1790
|
+
location: |
|
|
1791
|
+
{
|
|
1792
|
+
"bomRef": $."bom-ref",
|
|
1793
|
+
"purl": purl
|
|
1794
|
+
}
|
|
1795
|
+
message: "Snap '{{ name }}' {{ version }} (revision {{ $prop($, 'cdx:snap:revision') }}) is installed in devmode confinement, so its sandbox is not enforced"
|
|
1796
|
+
mitigation: "Reinstall the snap from a stable channel with strict confinement, or remove it. If devmode is required for development, keep it off production and shared hosts."
|
|
1797
|
+
evidence: |
|
|
1798
|
+
{
|
|
1799
|
+
"snap": name,
|
|
1800
|
+
"version": version,
|
|
1801
|
+
"revision": $prop($, 'cdx:snap:revision'),
|
|
1802
|
+
"channel": $prop($, 'cdx:snap:channel'),
|
|
1803
|
+
"confinement": $prop($, 'cdx:snap:confinement'),
|
|
1804
|
+
"grade": $prop($, 'grade')
|
|
1805
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# PHP source-build runtime rules
|
|
2
|
+
# Category: php-security
|
|
3
|
+
# Evaluates the cdx:php:* properties recorded for unpackaged PHP binaries and
|
|
4
|
+
# shared libraries during container, rootfs and OS (obom) scans. CVE-2026-109618 and
|
|
5
|
+
# CVE-2026-109619 are unauthenticated remote code execution bugs in request
|
|
6
|
+
# handling; fixed in 8.2.35, 8.3.36, 8.4.27 and 8.5.12.
|
|
7
|
+
# https://www.php.net/archive/2026.php#2026-10-21-5
|
|
8
|
+
#
|
|
9
|
+
# Builds from the php-src PHP-<M.m>-CVE-2026-109618-109619 backport branches
|
|
10
|
+
# keep their old version number, so a version check cannot tell them from a
|
|
11
|
+
# vulnerable build. That caveat is in the finding text.
|
|
12
|
+
|
|
13
|
+
- id: PHP-RCE-001
|
|
14
|
+
name: "Network-reachable PHP build affected by CVE-2026-109618 and CVE-2026-109619"
|
|
15
|
+
description: "A source-built PHP web SAPI older than its fixed release is vulnerable to two unauthenticated RCE bugs in request handling. PHP-FPM, php-cgi, libphp (Apache or embed) and FrankenPHP serve requests, so the worker is reachable from the network. The rule never reads PHP configuration: a mitigation never suppresses a finding."
|
|
16
|
+
severity: critical
|
|
17
|
+
category: php-security
|
|
18
|
+
dry-run-support: full
|
|
19
|
+
condition: |
|
|
20
|
+
components[
|
|
21
|
+
type = 'file'
|
|
22
|
+
and $hasProp($, 'cdx:php:buildVersion')
|
|
23
|
+
and $hasProp($, 'cdx:php:sapi')
|
|
24
|
+
and (
|
|
25
|
+
$m := $match($prop($, 'cdx:php:buildVersion'), /^(\d+)\.(\d+)\.(\d+)(?:-(dev)|(alpha|beta|RC)(\d+))?$/);
|
|
26
|
+
$m != null
|
|
27
|
+
and (
|
|
28
|
+
$number($m.groups[0]) < 8
|
|
29
|
+
or ($number($m.groups[0]) = 8 and $number($m.groups[1]) < 2)
|
|
30
|
+
or (
|
|
31
|
+
$number($m.groups[0]) = 8
|
|
32
|
+
and $number($m.groups[1]) = 2
|
|
33
|
+
and $number($m.groups[2]) < 35
|
|
34
|
+
)
|
|
35
|
+
or (
|
|
36
|
+
$number($m.groups[0]) = 8
|
|
37
|
+
and $number($m.groups[1]) = 3
|
|
38
|
+
and $number($m.groups[2]) < 36
|
|
39
|
+
)
|
|
40
|
+
or (
|
|
41
|
+
$number($m.groups[0]) = 8
|
|
42
|
+
and $number($m.groups[1]) = 4
|
|
43
|
+
and $number($m.groups[2]) < 27
|
|
44
|
+
)
|
|
45
|
+
or (
|
|
46
|
+
$number($m.groups[0]) = 8
|
|
47
|
+
and $number($m.groups[1]) = 5
|
|
48
|
+
and $number($m.groups[2]) < 12
|
|
49
|
+
)
|
|
50
|
+
or (
|
|
51
|
+
$number($m.groups[0]) = 8
|
|
52
|
+
and $number($m.groups[1]) = 6
|
|
53
|
+
and $number($m.groups[2]) = 0
|
|
54
|
+
and $m.groups[4] != null
|
|
55
|
+
and (
|
|
56
|
+
$m.groups[4] = 'alpha'
|
|
57
|
+
or $m.groups[4] = 'beta'
|
|
58
|
+
or ($m.groups[4] = 'RC' and $number($m.groups[5]) <= 3)
|
|
59
|
+
)
|
|
60
|
+
)
|
|
61
|
+
)
|
|
62
|
+
)
|
|
63
|
+
and $prop($, 'cdx:php:sapi') in ['fpm', 'cgi', 'libphp', 'frankenphp']
|
|
64
|
+
]
|
|
65
|
+
location: |
|
|
66
|
+
{
|
|
67
|
+
"bomRef": $firstNonEmpty($."bom-ref", bom.serialNumber)
|
|
68
|
+
}
|
|
69
|
+
message: "PHP {{ $prop($, 'cdx:php:sapi') }} '{{ name }}' is {{ $prop($, 'cdx:php:buildVersion') }}, which is affected by CVE-2026-109618 and CVE-2026-109619 (unauthenticated RCE); fixed in {{ $startsWith($prop($, 'cdx:php:buildVersion'), '8.2.') ? '8.2.35' : $startsWith($prop($, 'cdx:php:buildVersion'), '8.3.') ? '8.3.36' : $startsWith($prop($, 'cdx:php:buildVersion'), '8.4.') ? '8.4.27' : $startsWith($prop($, 'cdx:php:buildVersion'), '8.5.') ? '8.5.12' : $startsWith($prop($, 'cdx:php:buildVersion'), '8.6.') ? '8.6.0RC4 or later' : 'a supported PHP branch or a vendor backport (builds from the php-src CVE backport branches keep their version number and are false positives)' }}"
|
|
70
|
+
mitigation: "Upgrade to PHP 8.5.12, 8.4.27, 8.3.36 or 8.2.35. For 8.1 and older, move to a supported branch or a vendor backport. https://www.php.net/archive/2026.php#2026-10-21-5 Interim measures named by the advisory (an admin-level memory_limit=-1, a low post_max_size, session.upload_progress.enabled=0, and fatal_error_backtraces=0 on 8.5) reduce but do not remove the risk. Builds from the php-src PHP-<M.m>-CVE-2026-109618-109619 backport branches keep their old version number and are false positives."
|
|
71
|
+
evidence: |
|
|
72
|
+
{
|
|
73
|
+
"buildVersion": $prop($, 'cdx:php:buildVersion'),
|
|
74
|
+
"sapi": $prop($, 'cdx:php:sapi'),
|
|
75
|
+
"source": $prop($, 'cdx:php:buildVersionSource'),
|
|
76
|
+
"srcFile": $prop($, 'internal:SrcFile')
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
- id: PHP-RCE-002
|
|
80
|
+
name: "PHP CLI build affected by CVE-2026-109618 and CVE-2026-109619"
|
|
81
|
+
description: "A source-built PHP CLI or phpdbg older than its fixed release contains the same vulnerable request-handling code. The CLI is not network-reachable, but any web SAPI built from the same tree is, so the build should be upgraded."
|
|
82
|
+
severity: medium
|
|
83
|
+
category: php-security
|
|
84
|
+
dry-run-support: full
|
|
85
|
+
condition: |
|
|
86
|
+
components[
|
|
87
|
+
type = 'file'
|
|
88
|
+
and $hasProp($, 'cdx:php:buildVersion')
|
|
89
|
+
and $hasProp($, 'cdx:php:sapi')
|
|
90
|
+
and (
|
|
91
|
+
$m := $match($prop($, 'cdx:php:buildVersion'), /^(\d+)\.(\d+)\.(\d+)(?:-(dev)|(alpha|beta|RC)(\d+))?$/);
|
|
92
|
+
$m != null
|
|
93
|
+
and (
|
|
94
|
+
$number($m.groups[0]) < 8
|
|
95
|
+
or ($number($m.groups[0]) = 8 and $number($m.groups[1]) < 2)
|
|
96
|
+
or (
|
|
97
|
+
$number($m.groups[0]) = 8
|
|
98
|
+
and $number($m.groups[1]) = 2
|
|
99
|
+
and $number($m.groups[2]) < 35
|
|
100
|
+
)
|
|
101
|
+
or (
|
|
102
|
+
$number($m.groups[0]) = 8
|
|
103
|
+
and $number($m.groups[1]) = 3
|
|
104
|
+
and $number($m.groups[2]) < 36
|
|
105
|
+
)
|
|
106
|
+
or (
|
|
107
|
+
$number($m.groups[0]) = 8
|
|
108
|
+
and $number($m.groups[1]) = 4
|
|
109
|
+
and $number($m.groups[2]) < 27
|
|
110
|
+
)
|
|
111
|
+
or (
|
|
112
|
+
$number($m.groups[0]) = 8
|
|
113
|
+
and $number($m.groups[1]) = 5
|
|
114
|
+
and $number($m.groups[2]) < 12
|
|
115
|
+
)
|
|
116
|
+
or (
|
|
117
|
+
$number($m.groups[0]) = 8
|
|
118
|
+
and $number($m.groups[1]) = 6
|
|
119
|
+
and $number($m.groups[2]) = 0
|
|
120
|
+
and $m.groups[4] != null
|
|
121
|
+
and (
|
|
122
|
+
$m.groups[4] = 'alpha'
|
|
123
|
+
or $m.groups[4] = 'beta'
|
|
124
|
+
or ($m.groups[4] = 'RC' and $number($m.groups[5]) <= 3)
|
|
125
|
+
)
|
|
126
|
+
)
|
|
127
|
+
)
|
|
128
|
+
)
|
|
129
|
+
and $prop($, 'cdx:php:sapi') in ['cli', 'phpdbg']
|
|
130
|
+
]
|
|
131
|
+
location: |
|
|
132
|
+
{
|
|
133
|
+
"bomRef": $firstNonEmpty($."bom-ref", bom.serialNumber)
|
|
134
|
+
}
|
|
135
|
+
message: "PHP {{ $prop($, 'cdx:php:sapi') }} '{{ name }}' is {{ $prop($, 'cdx:php:buildVersion') }}, which is affected by CVE-2026-109618 and CVE-2026-109619 (unauthenticated RCE); fixed in {{ $startsWith($prop($, 'cdx:php:buildVersion'), '8.2.') ? '8.2.35' : $startsWith($prop($, 'cdx:php:buildVersion'), '8.3.') ? '8.3.36' : $startsWith($prop($, 'cdx:php:buildVersion'), '8.4.') ? '8.4.27' : $startsWith($prop($, 'cdx:php:buildVersion'), '8.5.') ? '8.5.12' : $startsWith($prop($, 'cdx:php:buildVersion'), '8.6.') ? '8.6.0RC4 or later' : 'a supported PHP branch or a vendor backport (builds from the php-src CVE backport branches keep their version number and are false positives)' }}. The CLI is not network-reachable, but the same build's web SAPIs are."
|
|
136
|
+
mitigation: "Upgrade to PHP 8.5.12, 8.4.27, 8.3.36 or 8.2.35. For 8.1 and older, move to a supported branch or a vendor backport. https://www.php.net/archive/2026.php#2026-10-21-5 Builds from the php-src PHP-<M.m>-CVE-2026-109618-109619 backport branches keep their old version number and are false positives."
|
|
137
|
+
evidence: |
|
|
138
|
+
{
|
|
139
|
+
"buildVersion": $prop($, 'cdx:php:buildVersion'),
|
|
140
|
+
"sapi": $prop($, 'cdx:php:sapi'),
|
|
141
|
+
"source": $prop($, 'cdx:php:buildVersionSource'),
|
|
142
|
+
"srcFile": $prop($, 'internal:SrcFile')
|
|
143
|
+
}
|
package/lib/audit/index.js
CHANGED
|
@@ -47,6 +47,7 @@ import {
|
|
|
47
47
|
resolveGitUrlFromPurl,
|
|
48
48
|
resolvePurlSourceDirectory,
|
|
49
49
|
sanitizeRemoteUrlForLogs,
|
|
50
|
+
validateAndRejectGitSource,
|
|
50
51
|
} from "../inventory/source.js";
|
|
51
52
|
import { executeOsQuery } from "../managers/binary.js";
|
|
52
53
|
import { getBomWithOras } from "../managers/oci.js";
|
|
@@ -1307,6 +1308,17 @@ export function buildTargetContextFindings(target) {
|
|
|
1307
1308
|
* @returns {void}
|
|
1308
1309
|
*/
|
|
1309
1310
|
function cloneRepositoryToDir(repoUrl, cloneDir, gitRef) {
|
|
1311
|
+
// The repository URL comes from registry metadata, so it gets the same
|
|
1312
|
+
// protocol and host checks as a URL sent to the server.
|
|
1313
|
+
const validationError = validateAndRejectGitSource(repoUrl);
|
|
1314
|
+
if (validationError) {
|
|
1315
|
+
const error = new Error(
|
|
1316
|
+
`${validationError.error}: ${validationError.details}`,
|
|
1317
|
+
);
|
|
1318
|
+
error.errorType = "clone";
|
|
1319
|
+
error.retryable = false;
|
|
1320
|
+
throw error;
|
|
1321
|
+
}
|
|
1310
1322
|
const gitArgs = [
|
|
1311
1323
|
"-c",
|
|
1312
1324
|
"alias.clone=",
|
|
@@ -1316,6 +1328,8 @@ function cloneRepositoryToDir(repoUrl, cloneDir, gitRef) {
|
|
|
1316
1328
|
"safe.bareRepository=explicit",
|
|
1317
1329
|
"-c",
|
|
1318
1330
|
"core.hooksPath=/dev/null",
|
|
1331
|
+
"-c",
|
|
1332
|
+
"core.symlinks=false",
|
|
1319
1333
|
"clone",
|
|
1320
1334
|
"--template=",
|
|
1321
1335
|
"--depth",
|
package/lib/cli/bomAssembly.js
CHANGED
|
@@ -45,6 +45,7 @@ import {
|
|
|
45
45
|
setCycloneDxFormat,
|
|
46
46
|
toCycloneDxSpecVersionString,
|
|
47
47
|
} from "../inventory/bomUtils.js";
|
|
48
|
+
import { mergeDuplicateCryptoComponents } from "../inventory/certificates.js";
|
|
48
49
|
import { mergeServices, trimComponents } from "../inventory/depsUtils.js";
|
|
49
50
|
import {
|
|
50
51
|
attachIdentityTools,
|
|
@@ -457,6 +458,11 @@ export const addLifecyclesSection = (options) => {
|
|
|
457
458
|
/**
|
|
458
459
|
* Function to create metadata block
|
|
459
460
|
*
|
|
461
|
+
* @param {Object} [parentComponent] Component the BOM describes
|
|
462
|
+
* @param {Object} [options] CLI options
|
|
463
|
+
* @param {Object} [context] Generator context. `context.metadataProperties`
|
|
464
|
+
* holds facts of a manifest that has no component to carry them, such as the
|
|
465
|
+
* platform data of a composer.lock whose composer.json names no project.
|
|
460
466
|
*/
|
|
461
467
|
export function addMetadata(parentComponent = {}, options = {}, context = {}) {
|
|
462
468
|
// DO NOT fork this project to just change the vendor or author's name
|
|
@@ -752,7 +758,7 @@ export function addMetadata(parentComponent = {}, options = {}, context = {}) {
|
|
|
752
758
|
});
|
|
753
759
|
let appLanguage;
|
|
754
760
|
// TODO: Move these lists to a config file.
|
|
755
|
-
for (const lang
|
|
761
|
+
for (const lang of [
|
|
756
762
|
"java",
|
|
757
763
|
"node",
|
|
758
764
|
"dotnet",
|
|
@@ -828,6 +834,9 @@ export function addMetadata(parentComponent = {}, options = {}, context = {}) {
|
|
|
828
834
|
// AI provenance/oversight detection (`-t ai-provenance`) is injected into the
|
|
829
835
|
// BOM document root (bomJson.properties) after post-processing, not into
|
|
830
836
|
// metadata.properties. See ensureAiProvenanceProperties/ensureAiOversightProperties.
|
|
837
|
+
if (context?.metadataProperties?.length) {
|
|
838
|
+
mproperties.push(...context.metadataProperties);
|
|
839
|
+
}
|
|
831
840
|
if (mproperties.length) {
|
|
832
841
|
metadata.properties = mproperties;
|
|
833
842
|
}
|
|
@@ -1602,6 +1611,10 @@ export const buildBomNSData = (options, pkgInfo, ptype, context) => {
|
|
|
1602
1611
|
if (context?.formulationList?.length) {
|
|
1603
1612
|
bomNSData.formulationList = context.formulationList;
|
|
1604
1613
|
}
|
|
1614
|
+
// createMultiXBom rebuilds the metadata block, so these are handed on.
|
|
1615
|
+
if (context?.metadataProperties?.length) {
|
|
1616
|
+
bomNSData.metadataProperties = context.metadataProperties;
|
|
1617
|
+
}
|
|
1605
1618
|
// Carry language-specific provenance citations (e.g. PEP 770 embedded
|
|
1606
1619
|
// SBOMs) so postProcess can attach them in the single root-level citations
|
|
1607
1620
|
// section it builds.
|
|
@@ -1933,16 +1946,28 @@ export function emitAiInventorySummary(aiInventory, discoveryPath) {
|
|
|
1933
1946
|
* @param {Array} components Components
|
|
1934
1947
|
* @param {Object} parentComponent Parent component
|
|
1935
1948
|
* @param {Array} dependencies Dependencies
|
|
1949
|
+
* @param {Array} [metadataProperties] Properties for the metadata block, from
|
|
1950
|
+
* generators whose manifest has no component to carry them
|
|
1936
1951
|
*
|
|
1937
1952
|
* @returns {Object} Object including BOM Json
|
|
1938
1953
|
*/
|
|
1939
|
-
export function dedupeBom(
|
|
1954
|
+
export function dedupeBom(
|
|
1955
|
+
options,
|
|
1956
|
+
components,
|
|
1957
|
+
parentComponent,
|
|
1958
|
+
dependencies,
|
|
1959
|
+
metadataProperties = [],
|
|
1960
|
+
) {
|
|
1940
1961
|
if (!components) {
|
|
1941
1962
|
return {};
|
|
1942
1963
|
}
|
|
1943
1964
|
if (!dependencies) {
|
|
1944
1965
|
dependencies = [];
|
|
1945
1966
|
}
|
|
1967
|
+
// Certificate components from different producers (trustinspector rootfs,
|
|
1968
|
+
// the source-directory scan, observed chains) share a bom-ref; merge their
|
|
1969
|
+
// occurrences and properties before the generic trim.
|
|
1970
|
+
components = mergeDuplicateCryptoComponents(components);
|
|
1946
1971
|
components = trimComponents(components);
|
|
1947
1972
|
// Let's apply some common tweaks
|
|
1948
1973
|
// Convert evidence.identity section to an object for 1.5
|
|
@@ -1971,7 +1996,7 @@ export function dedupeBom(options, components, parentComponent, dependencies) {
|
|
|
1971
1996
|
),
|
|
1972
1997
|
serialNumber: serialNum,
|
|
1973
1998
|
version: 1,
|
|
1974
|
-
metadata: addMetadata(parentComponent, options, {}),
|
|
1999
|
+
metadata: addMetadata(parentComponent, options, { metadataProperties }),
|
|
1975
2000
|
components,
|
|
1976
2001
|
services: options.services || [],
|
|
1977
2002
|
dependencies,
|