Swift: CVEs missed by Grype when using Syft-generated SBOMs β missing group field breaks PURL matching
Hi team,
I wanted to report a concrete issue I encountered when generating SBOMs for a Swift project that contains a known vulnerable dependency.
π§ͺ Reproduction Scenario
I have a Swift project that includes [email protected], which I know has a known CVE. I used syft to generate SBOMs in various formats:
- syft-json
- cyclonedx-json
- spdx-json
syft scan dir:. --output [email protected]=syft-cdx.json
syft scan dir:. --output [email protected]=syft-spdx.json
syft scan dir:. --output syft-json=syft-syft.json
Then I passed each of them into grype:
$ grype sbom:syft-cdx.json
β Scanned for vulnerabilities [0 vulnerability matches]
βββ by severity: 0 critical, 0 high, 0 medium, 0 low, 0 negligible
βββ by status: 0 fixed, 0 not-fixed, 0 ignored
No vulnerabilities found
$ grype sbom:syft-spdx.json
β Scanned for vulnerabilities [0 vulnerability matches]
βββ by severity: 0 critical, 0 high, 0 medium, 0 low, 0 negligible
βββ by status: 0 fixed, 0 not-fixed, 0 ignored
No vulnerabilities found
$ grype sbom:syft-syft.json
β Scanned for vulnerabilities [0 vulnerability matches]
βββ by severity: 0 critical, 0 high, 0 medium, 0 low, 0 negligible
βββ by status: 0 fixed, 0 not-fixed, 0 ignored
No vulnerabilities found
Result: Grype found nothing β no CVE reported for the vulnerable dependency.
π Cross-check with cdxgen
To double-check, I generated a CycloneDX SBOM using cdxgen :
$ cdxgen -t ios -o cdxgen.json -p
β Grype immediately detected the CVE in [email protected].
$ grype sbom:cdxgen.json
β Scanned for vulnerabilities [1 vulnerability matches]
βββ by severity: 1 critical, 0 high, 0 medium, 0 low, 0 negligible
βββ by status: 1 fixed, 0 not-fixed, 0 ignored
NAME INSTALLED FIXED-IN TYPE VULNERABILITY SEVERITY EPSS% RISK
github.com/apple/swift-nio-ssl 2.0.0 2.4.1 swift GHSA-frg3-gpcx-968f Critical 68.18 0.6
π Manual Debug β Key Finding
After comparing the cdxgen and syft SBOMs (CycloneDX), I found a key difference:
The cdxgen version includes :
"group": "github.com/apple",
"name": "swift-nio-ssl",
"version": "2.0.0",
"purl": "pkg:swift/github.com/apple/[email protected]",
"type": "library",
"bom-ref": "pkg:swift/github.com/apple/[email protected]",
The syft version lacks the group, producing:
"bom-ref": "pkg:swift/github.com/apple/swift-nio-ssl.git/[email protected]?package-id=3309939d9c7f2f56",
"type": "library",
"name": "swift-nio-ssl",
"version": "2.0.0",
"cpe": "cpe:2.3:a:swift-nio-ssl:swift-nio-ssl:2.0.0:*:*:*:*:*:*:*",
"purl": "pkg:swift/github.com/apple/swift-nio-ssl.git/[email protected]",
To confirm this was the root cause, I manually edited the Syft-generated CycloneDX SBOM, adding:
"group": "github.com/apple"
to the swift-nio-ssl component.
β‘οΈ Re-running grype on the modified SBOM correctly triggered the CVE detection.
$ grype sbom:syft-cdx.json
β Scanned for vulnerabilities [1 vulnerability matches]
βββ by severity: 1 critical, 0 high, 0 medium, 0 low, 0 negligible
βββ by status: 1 fixed, 0 not-fixed, 0 ignored
NAME INSTALLED FIXED-IN TYPE VULNERABILITY SEVERITY EPSS% RISK
github.com/apple/swift-nio-ssl 2.0.0 2.4.1 swift GHSA-frg3-gpcx-968f Critical 68.18 0.6
NB: I also tested removing the group field from the SBOM generated by cdxgen, and in that case, Grype no longer detected the CVE, confirming that the issue is solely caused by the missing group in the Swift component.
π‘ Conclusion
Grype relies heavily on the PURL being correct. Missing group info leads to invalid PURLs and breaks the link with known CVEs. This isnβt just a CycloneDX issue β the same behavior happens with the native syft-json format.
β What I'd Expect
Swift packages (especially when coming from Package.resolved) should include the correct namespace/group (github.com/apple) in the SBOM.
Syft should ideally support proper Swift dependency parsing.
π οΈ Environment
syft v1.26.1 grype v0.92.2 Swift project managed by SPM OS macOS 15.5
I let you all testing files to reproduce this behavior.
cdxgen.json syft-cdx.json syft-spdx.json syft-syft.json SPM.zip
Hey @jesuisben, I'm trying to understand the right thing to do here.
It looks like we are generating proper PURLs for these packages, which include the github.com/apple namespace portion. This is due to: https://github.com/anchore/syft/blob/main/syft/pkg/cataloger/swift/package.go#L65 however, we are not considering this to be part of the package name when we scan the Swift package.
We have a couple of paths forward, but the easiest seems to me to be to update the package name to include this information, which would make import from CycloneDX with the group consistent, however it would also mean that when we generate CycloneDX we are outputting the full name and no group. An alternate fix would be to introduce a top-level group in the Syft to hold this information (or introduce a group in the swift metadata, which we then need to be aware of everywhere, and I would prefer to avoid).
It seems to me enough ecosystems have a group / namespace in this manner we should probably introduce this into the Syft data model but we may not want to do this as part of Syft 1.0. I've marked this issue as needs-discussion to get the team's input. Thanks for the report π
After a team discussion, I think there isn't a need to add group, and there is instead a bug with naming where we should include the group/namespace portion of these packages in the name. Additionally, there is a bug parsing the URLs that should be fixed (e.g. it is including .git or other parts of the URL incorrectly).
Hello @kzantow, any news regarding this issue?