From e5347e3c9ec52a11a6aafebaaa8bdd1b0e0a670f Mon Sep 17 00:00:00 2001 From: DmitriyLewen Date: Thu, 24 Aug 2023 17:45:00 +0600 Subject: [PATCH 01/12] add vulns for cocoapods, fix purl --- go.mod | 4 ++ go.sum | 8 +-- integration/testdata/cocoapods.json.golden | 65 +++++++++---------- .../testdata/fixtures/db/cocoapods.yaml | 14 ++++ .../fixtures/repo/cocoapods/Podfile.lock | 26 ++++---- pkg/detector/library/driver.go | 6 +- .../swift/cocoapods/cocoapods_test.go | 18 ++--- pkg/purl/purl.go | 11 ++++ pkg/purl/purl_test.go | 32 +++++++++ 9 files changed, 123 insertions(+), 61 deletions(-) create mode 100644 integration/testdata/fixtures/db/cocoapods.yaml diff --git a/go.mod b/go.mod index d9d8f493ae0f..9724de0c5f04 100644 --- a/go.mod +++ b/go.mod @@ -403,3 +403,7 @@ require ( // oras 1.2.2 is incompatible with github.com/docker/docker v24.0.2 // cf. https://github.com/oras-project/oras-go/pull/527 replace oras.land/oras-go => oras.land/oras-go v1.2.4-0.20230801060855-932dd06d38af + +replace github.com/aquasecurity/trivy-db => github.com/DmitriyLewen/trivy-db v0.0.0-20230824102611-4e398f81cb3b + +replace github.com/aquasecurity/go-dep-parser => github.com/DmitriyLewen/go-dep-parser v0.0.0-20230824105602-3f7622fbbc25 diff --git a/go.sum b/go.sum index eb4829bc3fd5..6eb7c25f26e8 100644 --- a/go.sum +++ b/go.sum @@ -240,6 +240,10 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym github.com/CycloneDX/cyclonedx-go v0.7.2-0.20230625092137-07e2f29defc3 h1:NqeV+ZMqpcosu0Xg2VW14Ru9ayBs/toe2oihS7sN6Xo= github.com/CycloneDX/cyclonedx-go v0.7.2-0.20230625092137-07e2f29defc3/go.mod h1:fGXSp1lCDfMQ8KR1EjxT4ewc5HHhGczRF2pWhLSWohs= github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= +github.com/DmitriyLewen/go-dep-parser v0.0.0-20230824105602-3f7622fbbc25 h1:6sLAQT10WhpBb+JYpKXnHhYtBh5rM1U3ulhRfS57Lk0= +github.com/DmitriyLewen/go-dep-parser v0.0.0-20230824105602-3f7622fbbc25/go.mod h1:0+GvQF0gL4YEAAUPpNeLeGpFDxMvvIHLMd7vk9bpwko= +github.com/DmitriyLewen/trivy-db v0.0.0-20230824102611-4e398f81cb3b h1:n44r0G1H353jpO+i5kFTxmWHl2ZsDtETwRSI4Bt62VQ= +github.com/DmitriyLewen/trivy-db v0.0.0-20230824102611-4e398f81cb3b/go.mod h1:iJSGMMclPEhkYeyiN9i+gzjV9jhEv+XfPzfVgFhfvTE= github.com/GoogleCloudPlatform/docker-credential-gcr v2.0.5+incompatible h1:juIaKLLVhqzP55d8x4cSVgwyQv76Z55/fRv/UBr2KkQ= github.com/GoogleCloudPlatform/docker-credential-gcr v2.0.5+incompatible/go.mod h1:BB1eHdMLYEFuFdBlRMb0N7YGVdM5s6Pt0njxgvfbGGs= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= @@ -325,8 +329,6 @@ github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986 h1:2a30 github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986/go.mod h1:NT+jyeCzXk6vXR5MTkdn4z64TgGfE5HMLC8qfj5unl8= github.com/aquasecurity/defsec v0.91.1 h1:dBIPm6Tva9I+ZTQv+6t9wob3ZlMSu8NFqMJr4mgJC5A= github.com/aquasecurity/defsec v0.91.1/go.mod h1:l/srzxtuuyb6c6FlqUvMp3xw2ZbvuZ0l9972MNJM7V8= -github.com/aquasecurity/go-dep-parser v0.0.0-20230823094455-40c1f85cc942 h1:VGfeUtZyya9Vsl8enDurZ7pb/NDp2aJlL2rx2g4pR6A= -github.com/aquasecurity/go-dep-parser v0.0.0-20230823094455-40c1f85cc942/go.mod h1:0+GvQF0gL4YEAAUPpNeLeGpFDxMvvIHLMd7vk9bpwko= github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce h1:QgBRgJvtEOBtUXilDb1MLi1p1MWoyFDXAu5DEUl5nwM= github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce/go.mod h1:HXgVzOPvXhVGLJs4ZKO817idqr/xhwsTcj17CLYY74s= github.com/aquasecurity/go-mock-aws v0.0.0-20230328195059-5bf52338aec3 h1:Vt9y1gZS5JGY3tsL9zc++Cg4ofX51CG7PaMyC5SXWPg= @@ -345,8 +347,6 @@ github.com/aquasecurity/testdocker v0.0.0-20230111101738-e741bda259da h1:pj/adfN github.com/aquasecurity/testdocker v0.0.0-20230111101738-e741bda259da/go.mod h1:852lbQLpK2nCwlR4ZLYIccxYCfoQao6q9Nl6tjz54v8= github.com/aquasecurity/tml v0.6.1 h1:y2ZlGSfrhnn7t4ZJ/0rotuH+v5Jgv6BDDO5jB6A9gwo= github.com/aquasecurity/tml v0.6.1/go.mod h1:OnYMWY5lvI9ejU7yH9LCberWaaTBW7hBFsITiIMY2yY= -github.com/aquasecurity/trivy-db v0.0.0-20230823084507-315928e846ff h1:+MLnPm81Msu921N/lBrKd/NwwBrrzRoTgyMq0pIUhbs= -github.com/aquasecurity/trivy-db v0.0.0-20230823084507-315928e846ff/go.mod h1:iJSGMMclPEhkYeyiN9i+gzjV9jhEv+XfPzfVgFhfvTE= github.com/aquasecurity/trivy-java-db v0.0.0-20230209231723-7cddb1406728 h1:0eS+V7SXHgqoT99tV1mtMW6HL4HdoB9qGLMCb1fZp8A= github.com/aquasecurity/trivy-java-db v0.0.0-20230209231723-7cddb1406728/go.mod h1:Ldya37FLi0e/5Cjq2T5Bty7cFkzUDwTcPeQua+2M8i8= github.com/aquasecurity/trivy-kubernetes v0.5.7-0.20230814115812-7afa52705226 h1:fL4BpAfnLFruHqkomRDAB7Lv8yv3zuKdg71mZk9y61c= diff --git a/integration/testdata/cocoapods.json.golden b/integration/testdata/cocoapods.json.golden index 5d66b7a6786a..14685eac577a 100644 --- a/integration/testdata/cocoapods.json.golden +++ b/integration/testdata/cocoapods.json.golden @@ -21,44 +21,39 @@ "Type": "cocoapods", "Packages": [ { - "ID": "AppCenter/4.2.0", - "Name": "AppCenter", - "Version": "4.2.0", - "DependsOn": [ - "AppCenter/Analytics/4.2.0", - "AppCenter/Crashes/4.2.0" - ], - "Layer": {} - }, - { - "ID": "AppCenter/Analytics/4.2.0", - "Name": "AppCenter/Analytics", - "Version": "4.2.0", - "DependsOn": [ - "AppCenter/Core/4.2.0" - ], - "Layer": {} - }, - { - "ID": "AppCenter/Core/4.2.0", - "Name": "AppCenter/Core", - "Version": "4.2.0", + "ID": "_NIODataStructures@2.41.0", + "Name": "_NIODataStructures", + "Version": "2.41.0", "Layer": {} - }, + } + ], + "Vulnerabilities": [ { - "ID": "AppCenter/Crashes/4.2.0", - "Name": "AppCenter/Crashes", - "Version": "4.2.0", - "DependsOn": [ - "AppCenter/Core/4.2.0" + "VulnerabilityID": "CVE-2022-3215", + "PkgID": "_NIODataStructures@2.41.0", + "PkgName": "_NIODataStructures", + "InstalledVersion": "2.41.0", + "FixedVersion": "2.29.1, 2.39.1, 2.42.0", + "Status": "fixed", + "Layer": {}, + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2022-3215", + "Title": "SwiftNIO vulnerable to Improper Neutralization of CRLF Sequences in HTTP Headers ('HTTP Response Splitting')", + "Description": "`NIOHTTP1` and projects using it for generating HTTP responses, including SwiftNIO, can be subject to a HTTP Response Injection attack...", + "Severity": "MEDIUM", + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N", + "V3Score": 5.3 + } + }, + "References": [ + "https://github.com/apple/swift-nio/security/advisories/GHSA-7fj7-39wj-c64f", + "https://nvd.nist.gov/vuln/detail/CVE-2022-3215", + "https://github.com/apple/swift-nio/commit/a16e2f54a25b2af217044e5168997009a505930f", + "https://github.com/advisories/GHSA-7fj7-39wj-c64f" ], - "Layer": {} - }, - { - "ID": "KeychainAccess/4.2.1", - "Name": "KeychainAccess", - "Version": "4.2.1", - "Layer": {} + "PublishedDate": "2023-06-07T16:01:53Z", + "LastModifiedDate": "2023-06-19T16:45:07Z" } ] } diff --git a/integration/testdata/fixtures/db/cocoapods.yaml b/integration/testdata/fixtures/db/cocoapods.yaml new file mode 100644 index 000000000000..3b218912e36a --- /dev/null +++ b/integration/testdata/fixtures/db/cocoapods.yaml @@ -0,0 +1,14 @@ +- bucket: "cocoapods::GitHub Security Advisory Cocoapods" + pairs: + - bucket: _NIODataStructures + pairs: + - key: CVE-2022-3215 + value: + PatchedVersions: + - "2.29.1" + - "2.39.1" + - "2.42.0" + VulnerableVersions: + - "< 2.29.1" + - ">= 2.39.0, < 2.39.1" + - ">= 2.41.0, < 2.42.0" \ No newline at end of file diff --git a/integration/testdata/fixtures/repo/cocoapods/Podfile.lock b/integration/testdata/fixtures/repo/cocoapods/Podfile.lock index 65600c35476c..905fe5fc5119 100644 --- a/integration/testdata/fixtures/repo/cocoapods/Podfile.lock +++ b/integration/testdata/fixtures/repo/cocoapods/Podfile.lock @@ -1,12 +1,16 @@ PODS: - - AppCenter (4.2.0): - - AppCenter/Analytics (= 4.2.0) - - AppCenter/Crashes (= 4.2.0) - - AppCenter/Analytics (4.2.0): - - AppCenter/Core - - AppCenter/Core (4.2.0) - - AppCenter/Crashes (4.2.0): - - AppCenter/Core - - KeychainAccess (4.2.1) - -COCOAPODS: 1.11.2 \ No newline at end of file + - _NIODataStructures (2.41.0) + +DEPENDENCIES: + - _NIODataStructures (= 2.41.0) + +SPEC REPOS: + trunk: + - _NIODataStructures + +SPEC CHECKSUMS: + _NIODataStructures: 3d45d8e70a1d17a15b1dc59d102c63dbc0525ffd + +PODFILE CHECKSUM: 2acff18c7f9246879b6a1a2d04e5decbc9410ef4 + +COCOAPODS: 1.12.1 \ No newline at end of file diff --git a/pkg/detector/library/driver.go b/pkg/detector/library/driver.go index 395738d76e14..7350641fb0c8 100644 --- a/pkg/detector/library/driver.go +++ b/pkg/detector/library/driver.go @@ -66,8 +66,10 @@ func NewDriver(libType string) (Driver, bool) { ecosystem = vulnerability.Swift comparer = compare.GenericComparer{} case ftypes.Cocoapods: - log.Logger.Warn("CocoaPods is supported for SBOM, not for vulnerability scanning") - return Driver{}, false + // Cocoapods uses RubyGems version specifiers + // https://guides.cocoapods.org/making/making-a-cocoapod.html#cocoapods-versioning-specifics + ecosystem = vulnerability.Cocoapods + comparer = rubygems.Comparer{} case ftypes.CondaPkg: log.Logger.Warn("Conda package is supported for SBOM, not for vulnerability scanning") return Driver{}, false diff --git a/pkg/fanal/analyzer/language/swift/cocoapods/cocoapods_test.go b/pkg/fanal/analyzer/language/swift/cocoapods/cocoapods_test.go index 0a12f0230eb3..8d8ea5620a6e 100644 --- a/pkg/fanal/analyzer/language/swift/cocoapods/cocoapods_test.go +++ b/pkg/fanal/analyzer/language/swift/cocoapods/cocoapods_test.go @@ -27,37 +27,37 @@ func Test_cocoaPodsLockAnalyzer_Analyze(t *testing.T) { FilePath: "testdata/happy.lock", Libraries: types.Packages{ { - ID: "AppCenter/4.2.0", + ID: "AppCenter@4.2.0", Name: "AppCenter", Version: "4.2.0", DependsOn: []string{ - "AppCenter/Analytics/4.2.0", - "AppCenter/Crashes/4.2.0", + "AppCenter/Analytics@4.2.0", + "AppCenter/Crashes@4.2.0", }, }, { - ID: "AppCenter/Analytics/4.2.0", + ID: "AppCenter/Analytics@4.2.0", Name: "AppCenter/Analytics", Version: "4.2.0", DependsOn: []string{ - "AppCenter/Core/4.2.0", + "AppCenter/Core@4.2.0", }, }, { - ID: "AppCenter/Core/4.2.0", + ID: "AppCenter/Core@4.2.0", Name: "AppCenter/Core", Version: "4.2.0", }, { - ID: "AppCenter/Crashes/4.2.0", + ID: "AppCenter/Crashes@4.2.0", Name: "AppCenter/Crashes", Version: "4.2.0", DependsOn: []string{ - "AppCenter/Core/4.2.0", + "AppCenter/Core@4.2.0", }, }, { - ID: "KeychainAccess/4.2.1", + ID: "KeychainAccess@4.2.1", Name: "KeychainAccess", Version: "4.2.1", }, diff --git a/pkg/purl/purl.go b/pkg/purl/purl.go index 6278943a870a..e00a983c4bcb 100644 --- a/pkg/purl/purl.go +++ b/pkg/purl/purl.go @@ -109,6 +109,8 @@ func (p *PackageURL) PackageType() string { case packageurl.TypeNuget: return ftypes.NuGet case packageurl.TypeSwift: + return ftypes.Swift + case packageurl.TypeCocoapods: return ftypes.Cocoapods case packageurl.TypeHex: return ftypes.Hex @@ -180,6 +182,8 @@ func NewPackageURL(t string, metadata types.Metadata, pkg ftypes.Package) (Packa namespace, name = parseGolang(name) case packageurl.TypeNPM: namespace, name = parseNpm(name) + case packageurl.TypeSwift: + namespace, name = parseSwift(name) case packageurl.TypeOCI: purl, err := parseOCI(metadata) if err != nil { @@ -306,6 +310,11 @@ func parseComposer(pkgName string) (string, string) { return parsePkgName(pkgName) } +// ref. https://github.com/package-url/purl-spec/blob/a748c36ad415c8aeffe2b8a4a5d8a50d16d6d85f/PURL-TYPES.rst#swift +func parseSwift(pkgName string) (string, string) { + return parsePkgName(pkgName) +} + // ref. https://github.com/package-url/purl-spec/blob/a748c36ad415c8aeffe2b8a4a5d8a50d16d6d85f/PURL-TYPES.rst#npm func parseNpm(pkgName string) (string, string) { // the name must be lowercased @@ -330,6 +339,8 @@ func purlType(t string) string { case ftypes.Npm, ftypes.NodePkg, ftypes.Yarn, ftypes.Pnpm: return packageurl.TypeNPM case ftypes.Cocoapods: + return packageurl.TypeCocoapods + case ftypes.Swift: return packageurl.TypeSwift case ftypes.Hex: return packageurl.TypeHex diff --git a/pkg/purl/purl_test.go b/pkg/purl/purl_test.go index 0de388ce2b29..2faa189eec82 100644 --- a/pkg/purl/purl_test.go +++ b/pkg/purl/purl_test.go @@ -213,6 +213,38 @@ func TestNewPackageURL(t *testing.T) { }, }, }, + { + name: "swift package", + typ: ftypes.Swift, + pkg: ftypes.Package{ + ID: "github.com/apple/swift-atomics@1.1.0", + Name: "github.com/apple/swift-atomics", + Version: "1.1.0", + }, + want: purl.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeSwift, + Name: "github.com/apple/swift-atomics", + Version: "1.1.0", + }, + }, + }, + { + name: "cocoapods package", + typ: ftypes.Cocoapods, + pkg: ftypes.Package{ + ID: "_NIODataStructures@2.41.0", + Name: "_NIODataStructures", + Version: "2.41.0", + }, + want: purl.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeCocoapods, + Name: "_NIODataStructures", + Version: "2.41.0", + }, + }, + }, { name: "os package", typ: os.RedHat, From 13945730b17557e8d6cdd0507a226fb4effb91b1 Mon Sep 17 00:00:00 2001 From: DmitriyLewen Date: Fri, 25 Aug 2023 10:16:45 +0600 Subject: [PATCH 02/12] update docs --- docs/docs/coverage/language/index.md | 3 ++- docs/docs/coverage/language/swift.md | 34 ++++++++++++++++++++++++---- docs/docs/scanner/vulnerability.md | 6 +++-- pkg/fanal/analyzer/const.go | 2 ++ 4 files changed, 37 insertions(+), 8 deletions(-) diff --git a/docs/docs/coverage/language/index.md b/docs/docs/coverage/language/index.md index ef45c8d25b1e..18c3aa1f3909 100644 --- a/docs/docs/coverage/language/index.md +++ b/docs/docs/coverage/language/index.md @@ -17,7 +17,7 @@ If the target is a pre-build project, like a code repository, Trivy will analyze On the other hand, when the target is a post-build artifact, like a container image, Trivy will analyze installed package metadata like `.gemspec`, binary files, and so on. | Language | File | Image[^5] | Rootfs[^6] | Filesystem[^7] | Repository[^8] | -| -------------------- | ------------------------------------------------------------------------------------------ | :-------: | :--------: | :------------: | :------------: | +|----------------------|--------------------------------------------------------------------------------------------|:---------:|:----------:|:--------------:|:--------------:| | [Ruby](ruby.md) | Gemfile.lock | - | - | ✅ | ✅ | | | gemspec | ✅ | ✅ | - | - | | [Python](python.md) | Pipfile.lock | - | - | ✅ | ✅ | @@ -45,6 +45,7 @@ On the other hand, when the target is a post-build artifact, like a container im | [Elixir](elixir.md) | mix.lock[^10] | - | - | ✅ | ✅ | | [Dart](dart.md) | pubspec.lock | - | - | ✅ | ✅ | | [Swift](swift.md) | Podfile.lock | - | - | ✅ | ✅ | +| | Package.resolved | - | - | ✅ | ✅ | The path of these files does not matter. diff --git a/docs/docs/coverage/language/swift.md b/docs/docs/coverage/language/swift.md index 226dee08054c..a2079b2e8bfd 100644 --- a/docs/docs/coverage/language/swift.md +++ b/docs/docs/coverage/language/swift.md @@ -1,10 +1,34 @@ # Swift -Trivy supports [CocoaPods][cocoapods] for Swift packages. +Trivy supports [CocoaPods][cocoapods] and [Swift][swift] package managers. + The following scanners are supported. -| Package manager | SBOM | Vulnerability | License | -| --------------- | :---: | :-----------: | :-----: | -| CocoaPods | ✓ | - | - | +| Package manager | SBOM | Vulnerability | License | +|-----------------|:----:|:-------------:|:-------:| +| Swift | ✓ | ✓ | - | +| CocoaPods | ✓ | ✓ | - | + +The following table provides an outline of the features Trivy offers. + +| Package manager | File | Transitive dependencies | Dev dependencies | [Dependency graph][dependency-graph] | Position | +|:---------------:|------------------|:-----------------------:|:----------------:|:------------------------------------:|:--------:| +| Swift | Package.resolved | ✓ | Included | - | ✓ | +| Cocoapods | Podfile.lock | ✓ | Included | ✓ | - | + +These may be enabled or disabled depending on the target. +See [here](./index.md) for the detail. + +## swift +Trivy parses [Package.resolved][package-resolved] file to find dependencies. Don't forger to update (`swift package update` command) this file before scanning. + +## cocoapods +Cocoapods uses package names in `PodFile.lock`, but [GitHub advisory database][ghsa] uses git links. +We parse [Cocoapods Specs][cocoapods-specs] to match package names and links. -[cocoapods]: https://cocoapods.org/ \ No newline at end of file +[cocoapods]: https://cocoapods.org/ +[cocoapods-specs]: https://github.com/CocoaPods/Specs +[ghsa]: https://github.com/advisories?query=type%3Areviewed+ecosystem%3Aswift +[swift]: https://www.swift.org/package-manager/ +[package-resolved]: https://github.com/apple/swift-package-manager/blob/main/Documentation/Usage.md#resolving-versions-packageresolved-file +[dependency-graph]: ../../configuration/reporting.md#show-origins-of-vulnerable-dependencies \ No newline at end of file diff --git a/docs/docs/scanner/vulnerability.md b/docs/docs/scanner/vulnerability.md index 820be63d4759..b1d9681197e7 100644 --- a/docs/docs/scanner/vulnerability.md +++ b/docs/docs/scanner/vulnerability.md @@ -77,7 +77,7 @@ See [here](../coverage/language/index.md#supported-languages) for the supported ### Data Sources | Language | Source | Commercial Use | Delay[^1] | -| -------- | --------------------------------------------------- | :------------: | :-------: | +|----------|-----------------------------------------------------|:--------------:|:---------:| | PHP | [PHP Security Advisories Database][php] | ✅ | - | | | [GitHub Advisory Database (Composer)][php-ghsa] | ✅ | - | | Python | [GitHub Advisory Database (pip)][python-ghsa] | ✅ | - | @@ -93,7 +93,8 @@ See [here](../coverage/language/index.md#supported-languages) for the supported | .NET | [GitHub Advisory Database (NuGet)][dotnet-ghsa] | ✅ | - | | C/C++ | [GitLab Advisories Community][gitlab] | ✅ | 1 month | | Dart | [GitHub Advisory Database (Pub)][pub-ghsa] | ✅ | - | -| Elixir | [GitHub Advisory Database (Erlang)][erlang-ghsa] | ✅ | | +| Elixir | [GitHub Advisory Database (Erlang)][erlang-ghsa] | ✅ | - | +| Swift | [GitHub Advisory Database (Swift)][swift-ghsa] | ✅ | - | [^1]: Intentional delay between vulnerability disclosure and registration in the DB @@ -168,6 +169,7 @@ Currently, specifying a username and password is not supported. [pub-ghsa]: https://github.com/advisories?query=ecosystem%3Apub [erlang-ghsa]: https://github.com/advisories?query=ecosystem%3Aerlang [go-ghsa]: https://github.com/advisories?query=ecosystem%3Ago +[swift-ghsa]: https://github.com/advisories?query=ecosystem%3Aswift [php]: https://github.com/FriendsOfPHP/security-advisories [ruby]: https://github.com/rubysec/ruby-advisory-db diff --git a/pkg/fanal/analyzer/const.go b/pkg/fanal/analyzer/const.go index 5f2be4551df9..896b76202c01 100644 --- a/pkg/fanal/analyzer/const.go +++ b/pkg/fanal/analyzer/const.go @@ -181,6 +181,7 @@ var ( TypeRustBinary, TypeConanLock, TypeCocoaPods, + TypeSwift, TypePubSpecLock, TypeMixLock, } @@ -199,6 +200,7 @@ var ( TypeConanLock, TypeGradleLock, TypeCocoaPods, + TypeSwift, TypePubSpecLock, TypeMixLock, } From 94125c49fa00511c9963295c3b382627a2ec8a5f Mon Sep 17 00:00:00 2001 From: DmitriyLewen Date: Fri, 25 Aug 2023 11:32:30 +0600 Subject: [PATCH 03/12] remove go-dep-parser replace --- go.mod | 4 +--- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 9724de0c5f04..cf2ad3190d5d 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/alicebob/miniredis/v2 v2.30.4 github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986 github.com/aquasecurity/defsec v0.91.1 - github.com/aquasecurity/go-dep-parser v0.0.0-20230823094455-40c1f85cc942 + github.com/aquasecurity/go-dep-parser v0.0.0-20230825043456-df72a286b673 github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce github.com/aquasecurity/go-npm-version v0.0.0-20201110091526-0b796d180798 github.com/aquasecurity/go-pep440-version v0.0.0-20210121094942-22b2f8951d46 @@ -405,5 +405,3 @@ require ( replace oras.land/oras-go => oras.land/oras-go v1.2.4-0.20230801060855-932dd06d38af replace github.com/aquasecurity/trivy-db => github.com/DmitriyLewen/trivy-db v0.0.0-20230824102611-4e398f81cb3b - -replace github.com/aquasecurity/go-dep-parser => github.com/DmitriyLewen/go-dep-parser v0.0.0-20230824105602-3f7622fbbc25 diff --git a/go.sum b/go.sum index 6eb7c25f26e8..3efec0503738 100644 --- a/go.sum +++ b/go.sum @@ -240,8 +240,6 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym github.com/CycloneDX/cyclonedx-go v0.7.2-0.20230625092137-07e2f29defc3 h1:NqeV+ZMqpcosu0Xg2VW14Ru9ayBs/toe2oihS7sN6Xo= github.com/CycloneDX/cyclonedx-go v0.7.2-0.20230625092137-07e2f29defc3/go.mod h1:fGXSp1lCDfMQ8KR1EjxT4ewc5HHhGczRF2pWhLSWohs= github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= -github.com/DmitriyLewen/go-dep-parser v0.0.0-20230824105602-3f7622fbbc25 h1:6sLAQT10WhpBb+JYpKXnHhYtBh5rM1U3ulhRfS57Lk0= -github.com/DmitriyLewen/go-dep-parser v0.0.0-20230824105602-3f7622fbbc25/go.mod h1:0+GvQF0gL4YEAAUPpNeLeGpFDxMvvIHLMd7vk9bpwko= github.com/DmitriyLewen/trivy-db v0.0.0-20230824102611-4e398f81cb3b h1:n44r0G1H353jpO+i5kFTxmWHl2ZsDtETwRSI4Bt62VQ= github.com/DmitriyLewen/trivy-db v0.0.0-20230824102611-4e398f81cb3b/go.mod h1:iJSGMMclPEhkYeyiN9i+gzjV9jhEv+XfPzfVgFhfvTE= github.com/GoogleCloudPlatform/docker-credential-gcr v2.0.5+incompatible h1:juIaKLLVhqzP55d8x4cSVgwyQv76Z55/fRv/UBr2KkQ= @@ -329,6 +327,8 @@ github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986 h1:2a30 github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986/go.mod h1:NT+jyeCzXk6vXR5MTkdn4z64TgGfE5HMLC8qfj5unl8= github.com/aquasecurity/defsec v0.91.1 h1:dBIPm6Tva9I+ZTQv+6t9wob3ZlMSu8NFqMJr4mgJC5A= github.com/aquasecurity/defsec v0.91.1/go.mod h1:l/srzxtuuyb6c6FlqUvMp3xw2ZbvuZ0l9972MNJM7V8= +github.com/aquasecurity/go-dep-parser v0.0.0-20230825043456-df72a286b673 h1:RMhUzr2ZfQ8OAO26aUkqbwfxK7d3ieFtPqUhiwTxOe0= +github.com/aquasecurity/go-dep-parser v0.0.0-20230825043456-df72a286b673/go.mod h1:0+GvQF0gL4YEAAUPpNeLeGpFDxMvvIHLMd7vk9bpwko= github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce h1:QgBRgJvtEOBtUXilDb1MLi1p1MWoyFDXAu5DEUl5nwM= github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce/go.mod h1:HXgVzOPvXhVGLJs4ZKO817idqr/xhwsTcj17CLYY74s= github.com/aquasecurity/go-mock-aws v0.0.0-20230328195059-5bf52338aec3 h1:Vt9y1gZS5JGY3tsL9zc++Cg4ofX51CG7PaMyC5SXWPg= From 047bd3726395010b209c95d9e1c307bb8efbe26f Mon Sep 17 00:00:00 2001 From: DmitriyLewen Date: Fri, 25 Aug 2023 12:12:45 +0600 Subject: [PATCH 04/12] update purl and test --- pkg/purl/purl.go | 25 ++- pkg/purl/purl_test.go | 31 ++- .../happy/cocoapods-with-submodule-bom.json | 176 +++++++++++++++++ pkg/sbom/cyclonedx/unmarshal_test.go | 44 +++++ .../happy/cocoapods-with-submodule-bom.json | 177 ++++++++++++++++++ pkg/sbom/spdx/unmarshal_test.go | 44 +++++ 6 files changed, 488 insertions(+), 9 deletions(-) create mode 100644 pkg/sbom/cyclonedx/testdata/happy/cocoapods-with-submodule-bom.json create mode 100644 pkg/sbom/spdx/testdata/happy/cocoapods-with-submodule-bom.json diff --git a/pkg/purl/purl.go b/pkg/purl/purl.go index e00a983c4bcb..92df2eb619d7 100644 --- a/pkg/purl/purl.go +++ b/pkg/purl/purl.go @@ -57,6 +57,15 @@ func (p *PackageURL) Package() *ftypes.Package { } } + // Cocoapods purl has no namespace, but has subpath + // https://github.com/package-url/purl-spec/blob/a748c36ad415c8aeffe2b8a4a5d8a50d16d6d85f/PURL-TYPES.rst#cocoapods + if p.Type == packageurl.TypeCocoapods && p.Subpath != "" { + pkg.Name = strings.Join([]string{ + p.Name, + p.Subpath, + }, "/") + } + if p.Type == packageurl.TypeRPM { rpmVer := version.NewVersion(p.Version) pkg.Release = rpmVer.Release() @@ -156,6 +165,7 @@ func NewPackageURL(t string, metadata types.Metadata, pkg ftypes.Package) (Packa name := pkg.Name ver := utils.FormatVersion(pkg) namespace := "" + subpath := "" switch ptype { case packageurl.TypeRPM: @@ -184,6 +194,8 @@ func NewPackageURL(t string, metadata types.Metadata, pkg ftypes.Package) (Packa namespace, name = parseNpm(name) case packageurl.TypeSwift: namespace, name = parseSwift(name) + case packageurl.TypeCocoapods: + name, subpath = parseCocoapods(name) case packageurl.TypeOCI: purl, err := parseOCI(metadata) if err != nil { @@ -193,7 +205,7 @@ func NewPackageURL(t string, metadata types.Metadata, pkg ftypes.Package) (Packa } return PackageURL{ - PackageURL: *packageurl.NewPackageURL(ptype, namespace, name, ver, qualifiers, ""), + PackageURL: *packageurl.NewPackageURL(ptype, namespace, name, ver, qualifiers, subpath), FilePath: pkg.FilePath, }, nil } @@ -315,6 +327,17 @@ func parseSwift(pkgName string) (string, string) { return parsePkgName(pkgName) } +// ref. https://github.com/package-url/purl-spec/blob/a748c36ad415c8aeffe2b8a4a5d8a50d16d6d85f/PURL-TYPES.rst#cocoapods +func parseCocoapods(pkgName string) (string, string) { + var subpath string + index := strings.Index(pkgName, "/") + if index != -1 { + subpath = pkgName[index+1:] + pkgName = pkgName[:index] + } + return pkgName, subpath +} + // ref. https://github.com/package-url/purl-spec/blob/a748c36ad415c8aeffe2b8a4a5d8a50d16d6d85f/PURL-TYPES.rst#npm func parseNpm(pkgName string) (string, string) { // the name must be lowercased diff --git a/pkg/purl/purl_test.go b/pkg/purl/purl_test.go index 2faa189eec82..c6308e7ed591 100644 --- a/pkg/purl/purl_test.go +++ b/pkg/purl/purl_test.go @@ -223,9 +223,10 @@ func TestNewPackageURL(t *testing.T) { }, want: purl.PackageURL{ PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeSwift, - Name: "github.com/apple/swift-atomics", - Version: "1.1.0", + Type: packageurl.TypeSwift, + Namespace: "github.com/apple", + Name: "swift-atomics", + Version: "1.1.0", }, }, }, @@ -233,15 +234,16 @@ func TestNewPackageURL(t *testing.T) { name: "cocoapods package", typ: ftypes.Cocoapods, pkg: ftypes.Package{ - ID: "_NIODataStructures@2.41.0", - Name: "_NIODataStructures", - Version: "2.41.0", + ID: "GoogleUtilities/NSData+zlib@7.5.2", + Name: "GoogleUtilities/NSData+zlib", + Version: "7.5.2", }, want: purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeCocoapods, - Name: "_NIODataStructures", - Version: "2.41.0", + Name: "GoogleUtilities", + Version: "7.5.2", + Subpath: "NSData+zlib", }, }, }, @@ -447,6 +449,19 @@ func TestFromString(t *testing.T) { }, }, }, + { + name: "happy path for coocapods", + purl: "pkg:cocoapods/GoogleUtilities@7.5.2#NSData+zlib", + want: purl.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeCocoapods, + Name: "GoogleUtilities", + Version: "7.5.2", + Subpath: "NSData+zlib", + Qualifiers: packageurl.Qualifiers{}, + }, + }, + }, { name: "happy path for hex", purl: "pkg:hex/plug@1.14.0", diff --git a/pkg/sbom/cyclonedx/testdata/happy/cocoapods-with-submodule-bom.json b/pkg/sbom/cyclonedx/testdata/happy/cocoapods-with-submodule-bom.json new file mode 100644 index 000000000000..3152524836e6 --- /dev/null +++ b/pkg/sbom/cyclonedx/testdata/happy/cocoapods-with-submodule-bom.json @@ -0,0 +1,176 @@ +{ + "$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.5", + "serialNumber": "urn:uuid:94e2b1f4-cbaf-43bc-a6d4-88a10a03c23b", + "version": 1, + "metadata": { + "timestamp": "2023-08-25T05:50:30+00:00", + "tools": [ + { + "vendor": "aquasecurity", + "name": "trivy", + "version": "0.36.6-32-g94125c49f" + } + ], + "component": { + "bom-ref": "02d273d1-fb20-4e8b-8a4b-40147b74f873", + "type": "application", + "name": "Podfile.lock", + "properties": [ + { + "name": "aquasecurity:trivy:SchemaVersion", + "value": "2" + } + ] + } + }, + "components": [ + { + "bom-ref": "7bd638fb-e214-49cb-9207-4303a4460cd8", + "type": "application", + "name": "Podfile.lock", + "properties": [ + { + "name": "aquasecurity:trivy:Class", + "value": "lang-pkgs" + }, + { + "name": "aquasecurity:trivy:Type", + "value": "cocoapods" + } + ] + }, + { + "bom-ref": "pkg:cocoapods/AppCenter@4.2.0", + "type": "library", + "name": "AppCenter", + "version": "4.2.0", + "purl": "pkg:cocoapods/AppCenter@4.2.0", + "properties": [ + { + "name": "aquasecurity:trivy:PkgID", + "value": "AppCenter@4.2.0" + }, + { + "name": "aquasecurity:trivy:PkgType", + "value": "cocoapods" + } + ] + }, + { + "bom-ref": "pkg:cocoapods/AppCenter@4.2.0#Analytics", + "type": "library", + "name": "AppCenter/Analytics", + "version": "4.2.0", + "purl": "pkg:cocoapods/AppCenter@4.2.0#Analytics", + "properties": [ + { + "name": "aquasecurity:trivy:PkgID", + "value": "AppCenter/Analytics@4.2.0" + }, + { + "name": "aquasecurity:trivy:PkgType", + "value": "cocoapods" + } + ] + }, + { + "bom-ref": "pkg:cocoapods/AppCenter@4.2.0#Core", + "type": "library", + "name": "AppCenter/Core", + "version": "4.2.0", + "purl": "pkg:cocoapods/AppCenter@4.2.0#Core", + "properties": [ + { + "name": "aquasecurity:trivy:PkgID", + "value": "AppCenter/Core@4.2.0" + }, + { + "name": "aquasecurity:trivy:PkgType", + "value": "cocoapods" + } + ] + }, + { + "bom-ref": "pkg:cocoapods/AppCenter@4.2.0#Crashes", + "type": "library", + "name": "AppCenter/Crashes", + "version": "4.2.0", + "purl": "pkg:cocoapods/AppCenter@4.2.0#Crashes", + "properties": [ + { + "name": "aquasecurity:trivy:PkgID", + "value": "AppCenter/Crashes@4.2.0" + }, + { + "name": "aquasecurity:trivy:PkgType", + "value": "cocoapods" + } + ] + }, + { + "bom-ref": "pkg:cocoapods/KeychainAccess@4.2.1", + "type": "library", + "name": "KeychainAccess", + "version": "4.2.1", + "purl": "pkg:cocoapods/KeychainAccess@4.2.1", + "properties": [ + { + "name": "aquasecurity:trivy:PkgID", + "value": "KeychainAccess@4.2.1" + }, + { + "name": "aquasecurity:trivy:PkgType", + "value": "cocoapods" + } + ] + } + ], + "dependencies": [ + { + "ref": "02d273d1-fb20-4e8b-8a4b-40147b74f873", + "dependsOn": [ + "7bd638fb-e214-49cb-9207-4303a4460cd8" + ] + }, + { + "ref": "7bd638fb-e214-49cb-9207-4303a4460cd8", + "dependsOn": [ + "pkg:cocoapods/AppCenter@4.2.0", + "pkg:cocoapods/AppCenter@4.2.0#Analytics", + "pkg:cocoapods/AppCenter@4.2.0#Core", + "pkg:cocoapods/AppCenter@4.2.0#Crashes", + "pkg:cocoapods/KeychainAccess@4.2.1" + ] + }, + { + "ref": "pkg:cocoapods/AppCenter@4.2.0", + "dependsOn": [ + "pkg:cocoapods/AppCenter@4.2.0#Analytics", + "pkg:cocoapods/AppCenter@4.2.0#Crashes" + ] + }, + { + "ref": "pkg:cocoapods/AppCenter@4.2.0#Analytics", + "dependsOn": [ + "pkg:cocoapods/AppCenter@4.2.0#Core" + ] + }, + { + "ref": "pkg:cocoapods/AppCenter@4.2.0#Core", + "dependsOn": [] + }, + { + "ref": "pkg:cocoapods/AppCenter@4.2.0#Crashes", + "dependsOn": [ + "pkg:cocoapods/AppCenter@4.2.0#Core" + ] + }, + { + "ref": "pkg:cocoapods/KeychainAccess@4.2.1", + "dependsOn": [] + } + ], + "vulnerabilities": [] +} diff --git a/pkg/sbom/cyclonedx/unmarshal_test.go b/pkg/sbom/cyclonedx/unmarshal_test.go index 8314d95da814..cea885c39807 100644 --- a/pkg/sbom/cyclonedx/unmarshal_test.go +++ b/pkg/sbom/cyclonedx/unmarshal_test.go @@ -313,6 +313,50 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { }, }, }, + { + name: "happy path for cocoapods with purl subpath", + inputFile: "testdata/happy/cocoapods-with-submodule-bom.json", + want: types.SBOM{ + Applications: []ftypes.Application{ + { + Type: "cocoapods", + FilePath: "Podfile.lock", + Libraries: ftypes.Packages{ + { + ID: "AppCenter@4.2.0", + Name: "AppCenter", + Version: "4.2.0", + Ref: "pkg:cocoapods/AppCenter@4.2.0", + }, + { + ID: "AppCenter/Analytics@4.2.0", + Name: "AppCenter/Analytics", + Version: "4.2.0", + Ref: "pkg:cocoapods/AppCenter@4.2.0#Analytics", + }, + { + ID: "AppCenter/Core@4.2.0", + Name: "AppCenter/Core", + Version: "4.2.0", + Ref: "pkg:cocoapods/AppCenter@4.2.0#Core", + }, + { + ID: "AppCenter/Crashes@4.2.0", + Name: "AppCenter/Crashes", + Version: "4.2.0", + Ref: "pkg:cocoapods/AppCenter@4.2.0#Crashes", + }, + { + ID: "KeychainAccess@4.2.1", + Name: "KeychainAccess", + Version: "4.2.1", + Ref: "pkg:cocoapods/KeychainAccess@4.2.1", + }, + }, + }, + }, + }, + }, { name: "happy path only os component", inputFile: "testdata/happy/os-only-bom.json", diff --git a/pkg/sbom/spdx/testdata/happy/cocoapods-with-submodule-bom.json b/pkg/sbom/spdx/testdata/happy/cocoapods-with-submodule-bom.json new file mode 100644 index 000000000000..d069d8f6f2ce --- /dev/null +++ b/pkg/sbom/spdx/testdata/happy/cocoapods-with-submodule-bom.json @@ -0,0 +1,177 @@ +{ + "spdxVersion": "SPDX-2.3", + "dataLicense": "CC0-1.0", + "SPDXID": "SPDXRef-DOCUMENT", + "name": "Podfile.lock", + "documentNamespace": "http://aquasecurity.github.io/trivy/filesystem/Podfile.lock-1752bcf4-69dd-46d8-997b-748607ec3e0b", + "creationInfo": { + "licenseListVersion": "", + "creators": [ + "Organization: aquasecurity", + "Tool: trivy-0.36.6-32-g94125c49f" + ], + "created": "2023-08-25T05:56:30Z" + }, + "packages": [ + { + "name": "AppCenter", + "SPDXID": "SPDXRef-Package-144a57434e07e8c0", + "versionInfo": "4.2.0", + "supplier": "NOASSERTION", + "downloadLocation": "NONE", + "licenseConcluded": "NONE", + "licenseDeclared": "NONE", + "copyrightText": "", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:cocoapods/AppCenter@4.2.0" + } + ], + "attributionTexts": [ + "PkgID: AppCenter@4.2.0" + ], + "primaryPackagePurpose": "LIBRARY" + }, + { + "name": "AppCenter/Analytics", + "SPDXID": "SPDXRef-Package-6a9881161aee5290", + "versionInfo": "4.2.0", + "supplier": "NOASSERTION", + "downloadLocation": "NONE", + "licenseConcluded": "NONE", + "licenseDeclared": "NONE", + "copyrightText": "", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:cocoapods/AppCenter@4.2.0#Analytics" + } + ], + "attributionTexts": [ + "PkgID: AppCenter/Analytics@4.2.0" + ], + "primaryPackagePurpose": "LIBRARY" + }, + { + "name": "AppCenter/Core", + "SPDXID": "SPDXRef-Package-c4f1c9236d016489", + "versionInfo": "4.2.0", + "supplier": "NOASSERTION", + "downloadLocation": "NONE", + "licenseConcluded": "NONE", + "licenseDeclared": "NONE", + "copyrightText": "", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:cocoapods/AppCenter@4.2.0#Core" + } + ], + "attributionTexts": [ + "PkgID: AppCenter/Core@4.2.0" + ], + "primaryPackagePurpose": "LIBRARY" + }, + { + "name": "AppCenter/Crashes", + "SPDXID": "SPDXRef-Package-b3f8783ccf090c78", + "versionInfo": "4.2.0", + "supplier": "NOASSERTION", + "downloadLocation": "NONE", + "licenseConcluded": "NONE", + "licenseDeclared": "NONE", + "copyrightText": "", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:cocoapods/AppCenter@4.2.0#Crashes" + } + ], + "attributionTexts": [ + "PkgID: AppCenter/Crashes@4.2.0" + ], + "primaryPackagePurpose": "LIBRARY" + }, + { + "name": "KeychainAccess", + "SPDXID": "SPDXRef-Package-60be11aa76f38c9b", + "versionInfo": "4.2.1", + "supplier": "NOASSERTION", + "downloadLocation": "NONE", + "licenseConcluded": "NONE", + "licenseDeclared": "NONE", + "copyrightText": "", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:cocoapods/KeychainAccess@4.2.1" + } + ], + "attributionTexts": [ + "PkgID: KeychainAccess@4.2.1" + ], + "primaryPackagePurpose": "LIBRARY" + }, + { + "name": "Podfile.lock", + "SPDXID": "SPDXRef-Filesystem-adc2a67e18a4cde5", + "downloadLocation": "NONE", + "copyrightText": "", + "attributionTexts": [ + "SchemaVersion: 2" + ], + "primaryPackagePurpose": "SOURCE" + }, + { + "name": "cocoapods", + "SPDXID": "SPDXRef-Application-4bddee9eba9c9e8d", + "downloadLocation": "NONE", + "sourceInfo": "Podfile.lock", + "copyrightText": "", + "primaryPackagePurpose": "APPLICATION" + } + ], + "relationships": [ + { + "spdxElementId": "SPDXRef-DOCUMENT", + "relatedSpdxElement": "SPDXRef-Filesystem-adc2a67e18a4cde5", + "relationshipType": "DESCRIBES" + }, + { + "spdxElementId": "SPDXRef-Filesystem-adc2a67e18a4cde5", + "relatedSpdxElement": "SPDXRef-Application-4bddee9eba9c9e8d", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-Application-4bddee9eba9c9e8d", + "relatedSpdxElement": "SPDXRef-Package-144a57434e07e8c0", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-Application-4bddee9eba9c9e8d", + "relatedSpdxElement": "SPDXRef-Package-6a9881161aee5290", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-Application-4bddee9eba9c9e8d", + "relatedSpdxElement": "SPDXRef-Package-c4f1c9236d016489", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-Application-4bddee9eba9c9e8d", + "relatedSpdxElement": "SPDXRef-Package-b3f8783ccf090c78", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-Application-4bddee9eba9c9e8d", + "relatedSpdxElement": "SPDXRef-Package-60be11aa76f38c9b", + "relationshipType": "CONTAINS" + } + ] +} \ No newline at end of file diff --git a/pkg/sbom/spdx/unmarshal_test.go b/pkg/sbom/spdx/unmarshal_test.go index 5b72fb9e0d05..39e18abd3146 100644 --- a/pkg/sbom/spdx/unmarshal_test.go +++ b/pkg/sbom/spdx/unmarshal_test.go @@ -114,6 +114,50 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { }, }, }, + { + name: "happy path for cocoapods with submodules bom (purl uses subpath)", + inputFile: "testdata/happy/cocoapods-with-submodule-bom.json", + want: types.SBOM{ + Applications: []ftypes.Application{ + { + Type: "cocoapods", + FilePath: "Podfile.lock", + Libraries: ftypes.Packages{ + { + ID: "AppCenter@4.2.0", + Name: "AppCenter", + Version: "4.2.0", + Ref: "pkg:cocoapods/AppCenter@4.2.0", + }, + { + ID: "AppCenter/Analytics@4.2.0", + Name: "AppCenter/Analytics", + Version: "4.2.0", + Ref: "pkg:cocoapods/AppCenter@4.2.0#Analytics", + }, + { + ID: "AppCenter/Core@4.2.0", + Name: "AppCenter/Core", + Version: "4.2.0", + Ref: "pkg:cocoapods/AppCenter@4.2.0#Core", + }, + { + ID: "AppCenter/Crashes@4.2.0", + Name: "AppCenter/Crashes", + Version: "4.2.0", + Ref: "pkg:cocoapods/AppCenter@4.2.0#Crashes", + }, + { + ID: "KeychainAccess@4.2.1", + Name: "KeychainAccess", + Version: "4.2.1", + Ref: "pkg:cocoapods/KeychainAccess@4.2.1", + }, + }, + }, + }, + }, + }, { name: "happy path for bom with hasFiles field", inputFile: "testdata/happy/with-hasfiles-bom.json", From 233eed1d2df46b3ed9eefad901de83e680abacd9 Mon Sep 17 00:00:00 2001 From: DmitriyLewen Date: Mon, 28 Aug 2023 15:14:33 +0600 Subject: [PATCH 05/12] bump github.com/DmitriyLewen/trivy-db --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index cf2ad3190d5d..d58bcfb7b5f5 100644 --- a/go.mod +++ b/go.mod @@ -404,4 +404,4 @@ require ( // cf. https://github.com/oras-project/oras-go/pull/527 replace oras.land/oras-go => oras.land/oras-go v1.2.4-0.20230801060855-932dd06d38af -replace github.com/aquasecurity/trivy-db => github.com/DmitriyLewen/trivy-db v0.0.0-20230824102611-4e398f81cb3b +replace github.com/aquasecurity/trivy-db => github.com/DmitriyLewen/trivy-db v0.0.0-20230828082501-16f358ccad70 diff --git a/go.sum b/go.sum index 3efec0503738..606569d778f9 100644 --- a/go.sum +++ b/go.sum @@ -240,8 +240,8 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym github.com/CycloneDX/cyclonedx-go v0.7.2-0.20230625092137-07e2f29defc3 h1:NqeV+ZMqpcosu0Xg2VW14Ru9ayBs/toe2oihS7sN6Xo= github.com/CycloneDX/cyclonedx-go v0.7.2-0.20230625092137-07e2f29defc3/go.mod h1:fGXSp1lCDfMQ8KR1EjxT4ewc5HHhGczRF2pWhLSWohs= github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= -github.com/DmitriyLewen/trivy-db v0.0.0-20230824102611-4e398f81cb3b h1:n44r0G1H353jpO+i5kFTxmWHl2ZsDtETwRSI4Bt62VQ= -github.com/DmitriyLewen/trivy-db v0.0.0-20230824102611-4e398f81cb3b/go.mod h1:iJSGMMclPEhkYeyiN9i+gzjV9jhEv+XfPzfVgFhfvTE= +github.com/DmitriyLewen/trivy-db v0.0.0-20230828082501-16f358ccad70 h1:WhG+d+gZg/cr5AD6jJzD6ekyVFQdeBzHvs7XK91xnm8= +github.com/DmitriyLewen/trivy-db v0.0.0-20230828082501-16f358ccad70/go.mod h1:WJ5Qnk5ZNGWvks07GOZe2IOsuXrPfSC5c8hYGOGfrsU= github.com/GoogleCloudPlatform/docker-credential-gcr v2.0.5+incompatible h1:juIaKLLVhqzP55d8x4cSVgwyQv76Z55/fRv/UBr2KkQ= github.com/GoogleCloudPlatform/docker-credential-gcr v2.0.5+incompatible/go.mod h1:BB1eHdMLYEFuFdBlRMb0N7YGVdM5s6Pt0njxgvfbGGs= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= From 6662d0b8733e4cd8a985193dfde189e406827822 Mon Sep 17 00:00:00 2001 From: DmitriyLewen Date: Mon, 28 Aug 2023 17:08:59 +0600 Subject: [PATCH 06/12] remove replace for trivy-db --- go.mod | 4 +--- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index d58bcfb7b5f5..dd3ddac53376 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,7 @@ require ( github.com/aquasecurity/table v1.8.0 github.com/aquasecurity/testdocker v0.0.0-20230111101738-e741bda259da github.com/aquasecurity/tml v0.6.1 - github.com/aquasecurity/trivy-db v0.0.0-20230823084507-315928e846ff + github.com/aquasecurity/trivy-db v0.0.0-20230828105148-2c9c4da5a321 github.com/aquasecurity/trivy-java-db v0.0.0-20230209231723-7cddb1406728 github.com/aquasecurity/trivy-kubernetes v0.5.7-0.20230814115812-7afa52705226 github.com/aws/aws-sdk-go v1.44.273 @@ -403,5 +403,3 @@ require ( // oras 1.2.2 is incompatible with github.com/docker/docker v24.0.2 // cf. https://github.com/oras-project/oras-go/pull/527 replace oras.land/oras-go => oras.land/oras-go v1.2.4-0.20230801060855-932dd06d38af - -replace github.com/aquasecurity/trivy-db => github.com/DmitriyLewen/trivy-db v0.0.0-20230828082501-16f358ccad70 diff --git a/go.sum b/go.sum index 606569d778f9..ec2e0e341896 100644 --- a/go.sum +++ b/go.sum @@ -240,8 +240,6 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym github.com/CycloneDX/cyclonedx-go v0.7.2-0.20230625092137-07e2f29defc3 h1:NqeV+ZMqpcosu0Xg2VW14Ru9ayBs/toe2oihS7sN6Xo= github.com/CycloneDX/cyclonedx-go v0.7.2-0.20230625092137-07e2f29defc3/go.mod h1:fGXSp1lCDfMQ8KR1EjxT4ewc5HHhGczRF2pWhLSWohs= github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= -github.com/DmitriyLewen/trivy-db v0.0.0-20230828082501-16f358ccad70 h1:WhG+d+gZg/cr5AD6jJzD6ekyVFQdeBzHvs7XK91xnm8= -github.com/DmitriyLewen/trivy-db v0.0.0-20230828082501-16f358ccad70/go.mod h1:WJ5Qnk5ZNGWvks07GOZe2IOsuXrPfSC5c8hYGOGfrsU= github.com/GoogleCloudPlatform/docker-credential-gcr v2.0.5+incompatible h1:juIaKLLVhqzP55d8x4cSVgwyQv76Z55/fRv/UBr2KkQ= github.com/GoogleCloudPlatform/docker-credential-gcr v2.0.5+incompatible/go.mod h1:BB1eHdMLYEFuFdBlRMb0N7YGVdM5s6Pt0njxgvfbGGs= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= @@ -347,6 +345,8 @@ github.com/aquasecurity/testdocker v0.0.0-20230111101738-e741bda259da h1:pj/adfN github.com/aquasecurity/testdocker v0.0.0-20230111101738-e741bda259da/go.mod h1:852lbQLpK2nCwlR4ZLYIccxYCfoQao6q9Nl6tjz54v8= github.com/aquasecurity/tml v0.6.1 h1:y2ZlGSfrhnn7t4ZJ/0rotuH+v5Jgv6BDDO5jB6A9gwo= github.com/aquasecurity/tml v0.6.1/go.mod h1:OnYMWY5lvI9ejU7yH9LCberWaaTBW7hBFsITiIMY2yY= +github.com/aquasecurity/trivy-db v0.0.0-20230828105148-2c9c4da5a321 h1:oAXkM8x6jMal+6p2XB78+ntPs5LGjxZhtWHdOy4crlg= +github.com/aquasecurity/trivy-db v0.0.0-20230828105148-2c9c4da5a321/go.mod h1:WJ5Qnk5ZNGWvks07GOZe2IOsuXrPfSC5c8hYGOGfrsU= github.com/aquasecurity/trivy-java-db v0.0.0-20230209231723-7cddb1406728 h1:0eS+V7SXHgqoT99tV1mtMW6HL4HdoB9qGLMCb1fZp8A= github.com/aquasecurity/trivy-java-db v0.0.0-20230209231723-7cddb1406728/go.mod h1:Ldya37FLi0e/5Cjq2T5Bty7cFkzUDwTcPeQua+2M8i8= github.com/aquasecurity/trivy-kubernetes v0.5.7-0.20230814115812-7afa52705226 h1:fL4BpAfnLFruHqkomRDAB7Lv8yv3zuKdg71mZk9y61c= From 346162362151f1e08c8e88ee936774365bc6015f Mon Sep 17 00:00:00 2001 From: DmitriyLewen Date: Tue, 29 Aug 2023 09:21:05 +0600 Subject: [PATCH 07/12] remove added sbom tests --- .../happy/cocoapods-with-submodule-bom.json | 176 ----------------- pkg/sbom/cyclonedx/unmarshal_test.go | 44 ----- .../happy/cocoapods-with-submodule-bom.json | 177 ------------------ pkg/sbom/spdx/unmarshal_test.go | 44 ----- 4 files changed, 441 deletions(-) delete mode 100644 pkg/sbom/cyclonedx/testdata/happy/cocoapods-with-submodule-bom.json delete mode 100644 pkg/sbom/spdx/testdata/happy/cocoapods-with-submodule-bom.json diff --git a/pkg/sbom/cyclonedx/testdata/happy/cocoapods-with-submodule-bom.json b/pkg/sbom/cyclonedx/testdata/happy/cocoapods-with-submodule-bom.json deleted file mode 100644 index 3152524836e6..000000000000 --- a/pkg/sbom/cyclonedx/testdata/happy/cocoapods-with-submodule-bom.json +++ /dev/null @@ -1,176 +0,0 @@ -{ - "$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.5", - "serialNumber": "urn:uuid:94e2b1f4-cbaf-43bc-a6d4-88a10a03c23b", - "version": 1, - "metadata": { - "timestamp": "2023-08-25T05:50:30+00:00", - "tools": [ - { - "vendor": "aquasecurity", - "name": "trivy", - "version": "0.36.6-32-g94125c49f" - } - ], - "component": { - "bom-ref": "02d273d1-fb20-4e8b-8a4b-40147b74f873", - "type": "application", - "name": "Podfile.lock", - "properties": [ - { - "name": "aquasecurity:trivy:SchemaVersion", - "value": "2" - } - ] - } - }, - "components": [ - { - "bom-ref": "7bd638fb-e214-49cb-9207-4303a4460cd8", - "type": "application", - "name": "Podfile.lock", - "properties": [ - { - "name": "aquasecurity:trivy:Class", - "value": "lang-pkgs" - }, - { - "name": "aquasecurity:trivy:Type", - "value": "cocoapods" - } - ] - }, - { - "bom-ref": "pkg:cocoapods/AppCenter@4.2.0", - "type": "library", - "name": "AppCenter", - "version": "4.2.0", - "purl": "pkg:cocoapods/AppCenter@4.2.0", - "properties": [ - { - "name": "aquasecurity:trivy:PkgID", - "value": "AppCenter@4.2.0" - }, - { - "name": "aquasecurity:trivy:PkgType", - "value": "cocoapods" - } - ] - }, - { - "bom-ref": "pkg:cocoapods/AppCenter@4.2.0#Analytics", - "type": "library", - "name": "AppCenter/Analytics", - "version": "4.2.0", - "purl": "pkg:cocoapods/AppCenter@4.2.0#Analytics", - "properties": [ - { - "name": "aquasecurity:trivy:PkgID", - "value": "AppCenter/Analytics@4.2.0" - }, - { - "name": "aquasecurity:trivy:PkgType", - "value": "cocoapods" - } - ] - }, - { - "bom-ref": "pkg:cocoapods/AppCenter@4.2.0#Core", - "type": "library", - "name": "AppCenter/Core", - "version": "4.2.0", - "purl": "pkg:cocoapods/AppCenter@4.2.0#Core", - "properties": [ - { - "name": "aquasecurity:trivy:PkgID", - "value": "AppCenter/Core@4.2.0" - }, - { - "name": "aquasecurity:trivy:PkgType", - "value": "cocoapods" - } - ] - }, - { - "bom-ref": "pkg:cocoapods/AppCenter@4.2.0#Crashes", - "type": "library", - "name": "AppCenter/Crashes", - "version": "4.2.0", - "purl": "pkg:cocoapods/AppCenter@4.2.0#Crashes", - "properties": [ - { - "name": "aquasecurity:trivy:PkgID", - "value": "AppCenter/Crashes@4.2.0" - }, - { - "name": "aquasecurity:trivy:PkgType", - "value": "cocoapods" - } - ] - }, - { - "bom-ref": "pkg:cocoapods/KeychainAccess@4.2.1", - "type": "library", - "name": "KeychainAccess", - "version": "4.2.1", - "purl": "pkg:cocoapods/KeychainAccess@4.2.1", - "properties": [ - { - "name": "aquasecurity:trivy:PkgID", - "value": "KeychainAccess@4.2.1" - }, - { - "name": "aquasecurity:trivy:PkgType", - "value": "cocoapods" - } - ] - } - ], - "dependencies": [ - { - "ref": "02d273d1-fb20-4e8b-8a4b-40147b74f873", - "dependsOn": [ - "7bd638fb-e214-49cb-9207-4303a4460cd8" - ] - }, - { - "ref": "7bd638fb-e214-49cb-9207-4303a4460cd8", - "dependsOn": [ - "pkg:cocoapods/AppCenter@4.2.0", - "pkg:cocoapods/AppCenter@4.2.0#Analytics", - "pkg:cocoapods/AppCenter@4.2.0#Core", - "pkg:cocoapods/AppCenter@4.2.0#Crashes", - "pkg:cocoapods/KeychainAccess@4.2.1" - ] - }, - { - "ref": "pkg:cocoapods/AppCenter@4.2.0", - "dependsOn": [ - "pkg:cocoapods/AppCenter@4.2.0#Analytics", - "pkg:cocoapods/AppCenter@4.2.0#Crashes" - ] - }, - { - "ref": "pkg:cocoapods/AppCenter@4.2.0#Analytics", - "dependsOn": [ - "pkg:cocoapods/AppCenter@4.2.0#Core" - ] - }, - { - "ref": "pkg:cocoapods/AppCenter@4.2.0#Core", - "dependsOn": [] - }, - { - "ref": "pkg:cocoapods/AppCenter@4.2.0#Crashes", - "dependsOn": [ - "pkg:cocoapods/AppCenter@4.2.0#Core" - ] - }, - { - "ref": "pkg:cocoapods/KeychainAccess@4.2.1", - "dependsOn": [] - } - ], - "vulnerabilities": [] -} diff --git a/pkg/sbom/cyclonedx/unmarshal_test.go b/pkg/sbom/cyclonedx/unmarshal_test.go index cea885c39807..8314d95da814 100644 --- a/pkg/sbom/cyclonedx/unmarshal_test.go +++ b/pkg/sbom/cyclonedx/unmarshal_test.go @@ -313,50 +313,6 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { }, }, }, - { - name: "happy path for cocoapods with purl subpath", - inputFile: "testdata/happy/cocoapods-with-submodule-bom.json", - want: types.SBOM{ - Applications: []ftypes.Application{ - { - Type: "cocoapods", - FilePath: "Podfile.lock", - Libraries: ftypes.Packages{ - { - ID: "AppCenter@4.2.0", - Name: "AppCenter", - Version: "4.2.0", - Ref: "pkg:cocoapods/AppCenter@4.2.0", - }, - { - ID: "AppCenter/Analytics@4.2.0", - Name: "AppCenter/Analytics", - Version: "4.2.0", - Ref: "pkg:cocoapods/AppCenter@4.2.0#Analytics", - }, - { - ID: "AppCenter/Core@4.2.0", - Name: "AppCenter/Core", - Version: "4.2.0", - Ref: "pkg:cocoapods/AppCenter@4.2.0#Core", - }, - { - ID: "AppCenter/Crashes@4.2.0", - Name: "AppCenter/Crashes", - Version: "4.2.0", - Ref: "pkg:cocoapods/AppCenter@4.2.0#Crashes", - }, - { - ID: "KeychainAccess@4.2.1", - Name: "KeychainAccess", - Version: "4.2.1", - Ref: "pkg:cocoapods/KeychainAccess@4.2.1", - }, - }, - }, - }, - }, - }, { name: "happy path only os component", inputFile: "testdata/happy/os-only-bom.json", diff --git a/pkg/sbom/spdx/testdata/happy/cocoapods-with-submodule-bom.json b/pkg/sbom/spdx/testdata/happy/cocoapods-with-submodule-bom.json deleted file mode 100644 index d069d8f6f2ce..000000000000 --- a/pkg/sbom/spdx/testdata/happy/cocoapods-with-submodule-bom.json +++ /dev/null @@ -1,177 +0,0 @@ -{ - "spdxVersion": "SPDX-2.3", - "dataLicense": "CC0-1.0", - "SPDXID": "SPDXRef-DOCUMENT", - "name": "Podfile.lock", - "documentNamespace": "http://aquasecurity.github.io/trivy/filesystem/Podfile.lock-1752bcf4-69dd-46d8-997b-748607ec3e0b", - "creationInfo": { - "licenseListVersion": "", - "creators": [ - "Organization: aquasecurity", - "Tool: trivy-0.36.6-32-g94125c49f" - ], - "created": "2023-08-25T05:56:30Z" - }, - "packages": [ - { - "name": "AppCenter", - "SPDXID": "SPDXRef-Package-144a57434e07e8c0", - "versionInfo": "4.2.0", - "supplier": "NOASSERTION", - "downloadLocation": "NONE", - "licenseConcluded": "NONE", - "licenseDeclared": "NONE", - "copyrightText": "", - "externalRefs": [ - { - "referenceCategory": "PACKAGE-MANAGER", - "referenceType": "purl", - "referenceLocator": "pkg:cocoapods/AppCenter@4.2.0" - } - ], - "attributionTexts": [ - "PkgID: AppCenter@4.2.0" - ], - "primaryPackagePurpose": "LIBRARY" - }, - { - "name": "AppCenter/Analytics", - "SPDXID": "SPDXRef-Package-6a9881161aee5290", - "versionInfo": "4.2.0", - "supplier": "NOASSERTION", - "downloadLocation": "NONE", - "licenseConcluded": "NONE", - "licenseDeclared": "NONE", - "copyrightText": "", - "externalRefs": [ - { - "referenceCategory": "PACKAGE-MANAGER", - "referenceType": "purl", - "referenceLocator": "pkg:cocoapods/AppCenter@4.2.0#Analytics" - } - ], - "attributionTexts": [ - "PkgID: AppCenter/Analytics@4.2.0" - ], - "primaryPackagePurpose": "LIBRARY" - }, - { - "name": "AppCenter/Core", - "SPDXID": "SPDXRef-Package-c4f1c9236d016489", - "versionInfo": "4.2.0", - "supplier": "NOASSERTION", - "downloadLocation": "NONE", - "licenseConcluded": "NONE", - "licenseDeclared": "NONE", - "copyrightText": "", - "externalRefs": [ - { - "referenceCategory": "PACKAGE-MANAGER", - "referenceType": "purl", - "referenceLocator": "pkg:cocoapods/AppCenter@4.2.0#Core" - } - ], - "attributionTexts": [ - "PkgID: AppCenter/Core@4.2.0" - ], - "primaryPackagePurpose": "LIBRARY" - }, - { - "name": "AppCenter/Crashes", - "SPDXID": "SPDXRef-Package-b3f8783ccf090c78", - "versionInfo": "4.2.0", - "supplier": "NOASSERTION", - "downloadLocation": "NONE", - "licenseConcluded": "NONE", - "licenseDeclared": "NONE", - "copyrightText": "", - "externalRefs": [ - { - "referenceCategory": "PACKAGE-MANAGER", - "referenceType": "purl", - "referenceLocator": "pkg:cocoapods/AppCenter@4.2.0#Crashes" - } - ], - "attributionTexts": [ - "PkgID: AppCenter/Crashes@4.2.0" - ], - "primaryPackagePurpose": "LIBRARY" - }, - { - "name": "KeychainAccess", - "SPDXID": "SPDXRef-Package-60be11aa76f38c9b", - "versionInfo": "4.2.1", - "supplier": "NOASSERTION", - "downloadLocation": "NONE", - "licenseConcluded": "NONE", - "licenseDeclared": "NONE", - "copyrightText": "", - "externalRefs": [ - { - "referenceCategory": "PACKAGE-MANAGER", - "referenceType": "purl", - "referenceLocator": "pkg:cocoapods/KeychainAccess@4.2.1" - } - ], - "attributionTexts": [ - "PkgID: KeychainAccess@4.2.1" - ], - "primaryPackagePurpose": "LIBRARY" - }, - { - "name": "Podfile.lock", - "SPDXID": "SPDXRef-Filesystem-adc2a67e18a4cde5", - "downloadLocation": "NONE", - "copyrightText": "", - "attributionTexts": [ - "SchemaVersion: 2" - ], - "primaryPackagePurpose": "SOURCE" - }, - { - "name": "cocoapods", - "SPDXID": "SPDXRef-Application-4bddee9eba9c9e8d", - "downloadLocation": "NONE", - "sourceInfo": "Podfile.lock", - "copyrightText": "", - "primaryPackagePurpose": "APPLICATION" - } - ], - "relationships": [ - { - "spdxElementId": "SPDXRef-DOCUMENT", - "relatedSpdxElement": "SPDXRef-Filesystem-adc2a67e18a4cde5", - "relationshipType": "DESCRIBES" - }, - { - "spdxElementId": "SPDXRef-Filesystem-adc2a67e18a4cde5", - "relatedSpdxElement": "SPDXRef-Application-4bddee9eba9c9e8d", - "relationshipType": "CONTAINS" - }, - { - "spdxElementId": "SPDXRef-Application-4bddee9eba9c9e8d", - "relatedSpdxElement": "SPDXRef-Package-144a57434e07e8c0", - "relationshipType": "CONTAINS" - }, - { - "spdxElementId": "SPDXRef-Application-4bddee9eba9c9e8d", - "relatedSpdxElement": "SPDXRef-Package-6a9881161aee5290", - "relationshipType": "CONTAINS" - }, - { - "spdxElementId": "SPDXRef-Application-4bddee9eba9c9e8d", - "relatedSpdxElement": "SPDXRef-Package-c4f1c9236d016489", - "relationshipType": "CONTAINS" - }, - { - "spdxElementId": "SPDXRef-Application-4bddee9eba9c9e8d", - "relatedSpdxElement": "SPDXRef-Package-b3f8783ccf090c78", - "relationshipType": "CONTAINS" - }, - { - "spdxElementId": "SPDXRef-Application-4bddee9eba9c9e8d", - "relatedSpdxElement": "SPDXRef-Package-60be11aa76f38c9b", - "relationshipType": "CONTAINS" - } - ] -} \ No newline at end of file diff --git a/pkg/sbom/spdx/unmarshal_test.go b/pkg/sbom/spdx/unmarshal_test.go index 39e18abd3146..5b72fb9e0d05 100644 --- a/pkg/sbom/spdx/unmarshal_test.go +++ b/pkg/sbom/spdx/unmarshal_test.go @@ -114,50 +114,6 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { }, }, }, - { - name: "happy path for cocoapods with submodules bom (purl uses subpath)", - inputFile: "testdata/happy/cocoapods-with-submodule-bom.json", - want: types.SBOM{ - Applications: []ftypes.Application{ - { - Type: "cocoapods", - FilePath: "Podfile.lock", - Libraries: ftypes.Packages{ - { - ID: "AppCenter@4.2.0", - Name: "AppCenter", - Version: "4.2.0", - Ref: "pkg:cocoapods/AppCenter@4.2.0", - }, - { - ID: "AppCenter/Analytics@4.2.0", - Name: "AppCenter/Analytics", - Version: "4.2.0", - Ref: "pkg:cocoapods/AppCenter@4.2.0#Analytics", - }, - { - ID: "AppCenter/Core@4.2.0", - Name: "AppCenter/Core", - Version: "4.2.0", - Ref: "pkg:cocoapods/AppCenter@4.2.0#Core", - }, - { - ID: "AppCenter/Crashes@4.2.0", - Name: "AppCenter/Crashes", - Version: "4.2.0", - Ref: "pkg:cocoapods/AppCenter@4.2.0#Crashes", - }, - { - ID: "KeychainAccess@4.2.1", - Name: "KeychainAccess", - Version: "4.2.1", - Ref: "pkg:cocoapods/KeychainAccess@4.2.1", - }, - }, - }, - }, - }, - }, { name: "happy path for bom with hasFiles field", inputFile: "testdata/happy/with-hasfiles-bom.json", From de0a63151224c63d699c86e3ca86c1fee94ba258 Mon Sep 17 00:00:00 2001 From: DmitriyLewen Date: Tue, 29 Aug 2023 09:21:26 +0600 Subject: [PATCH 08/12] add test for Package() func --- pkg/purl/purl_test.go | 101 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 100 insertions(+), 1 deletion(-) diff --git a/pkg/purl/purl_test.go b/pkg/purl/purl_test.go index c6308e7ed591..85e698b54dbf 100644 --- a/pkg/purl/purl_test.go +++ b/pkg/purl/purl_test.go @@ -411,7 +411,6 @@ func TestNewPackageURL(t *testing.T) { } func TestFromString(t *testing.T) { - testCases := []struct { name string purl string @@ -561,3 +560,103 @@ func TestFromString(t *testing.T) { }) } } + +func TestPackage(t *testing.T) { + tests := []struct { + name string + pkgURL *purl.PackageURL + wantPkg *ftypes.Package + }{ + { + name: "rpm + Qualifiers", + pkgURL: &purl.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeRPM, + Namespace: "redhat", + Name: "nodejs-full-i18n", + Version: "10.21.0-3.module_el8.2.0+391+8da3adc6", + Qualifiers: packageurl.Qualifiers{ + { + Key: "arch", + Value: "x86_64", + }, + { + Key: "epoch", + Value: "1", + }, + { + Key: "modularitylabel", + Value: "nodejs:10:8020020200707141642:6a468ee4", + }, + { + Key: "distro", + Value: "redhat-8", + }, + }, + }, + }, + wantPkg: &ftypes.Package{ + Name: "nodejs-full-i18n", + Version: "10.21.0", + Release: "3.module_el8.2.0+391+8da3adc6", + Arch: "x86_64", + Epoch: 1, + Modularitylabel: "nodejs:10:8020020200707141642:6a468ee4", + }, + }, + { + name: "composer with namespace", + pkgURL: &purl.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "symfony", + Name: "contracts", + Version: "v1.0.2", + }, + }, + wantPkg: &ftypes.Package{ + Name: "symfony/contracts", + Version: "v1.0.2", + }, + }, + { + name: "maven with namespace", + pkgURL: &purl.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "org.springframework", + Name: "spring-core", + Version: "5.0.4.RELEASE", + Qualifiers: packageurl.Qualifiers{}, + }, + }, + wantPkg: &ftypes.Package{ + Name: "org.springframework:spring-core", + Version: "5.0.4.RELEASE", + }, + }, + { + name: "cocoapods with subpath", + pkgURL: &purl.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeCocoapods, + Version: "4.2.0", + Name: "AppCenter", + Subpath: "Analytics", + Qualifiers: packageurl.Qualifiers{}, + }, + }, + wantPkg: &ftypes.Package{ + Name: "AppCenter/Analytics", + Version: "4.2.0", + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := tt.pkgURL.Package() + assert.Equal(t, tt.wantPkg, got) + }) + } +} From f36879fb6f75ed9e8dedddd79116e70c39e13177 Mon Sep 17 00:00:00 2001 From: DmitriyLewen Date: Tue, 29 Aug 2023 09:25:01 +0600 Subject: [PATCH 09/12] add wrong epoch test --- pkg/purl/purl_test.go | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/pkg/purl/purl_test.go b/pkg/purl/purl_test.go index 85e698b54dbf..defd24a309e8 100644 --- a/pkg/purl/purl_test.go +++ b/pkg/purl/purl_test.go @@ -651,6 +651,28 @@ func TestPackage(t *testing.T) { Version: "4.2.0", }, }, + { + name: "wrong epoch", + pkgURL: &purl.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeRPM, + Namespace: "redhat", + Name: "acl", + Version: "2.2.53-1.el8", + Qualifiers: packageurl.Qualifiers{ + { + Key: "epoch", + Value: "wrong", + }, + }, + }, + }, + wantPkg: &ftypes.Package{ + Name: "acl", + Version: "2.2.53", + Release: "1.el8", + }, + }, } for _, tt := range tests { From 3713c0397bf395740209de60ca84ad76eb7f0afd Mon Sep 17 00:00:00 2001 From: DmitriyLewen Date: Tue, 29 Aug 2023 12:18:45 +0600 Subject: [PATCH 10/12] refactor docs --- docs/docs/coverage/language/swift.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/docs/docs/coverage/language/swift.md b/docs/docs/coverage/language/swift.md index a2079b2e8bfd..f9867519339e 100644 --- a/docs/docs/coverage/language/swift.md +++ b/docs/docs/coverage/language/swift.md @@ -14,21 +14,25 @@ The following table provides an outline of the features Trivy offers. | Package manager | File | Transitive dependencies | Dev dependencies | [Dependency graph][dependency-graph] | Position | |:---------------:|------------------|:-----------------------:|:----------------:|:------------------------------------:|:--------:| | Swift | Package.resolved | ✓ | Included | - | ✓ | -| Cocoapods | Podfile.lock | ✓ | Included | ✓ | - | +| CocoaPods | Podfile.lock | ✓ | Included | ✓ | - | These may be enabled or disabled depending on the target. See [here](./index.md) for the detail. -## swift +## Swift Trivy parses [Package.resolved][package-resolved] file to find dependencies. Don't forger to update (`swift package update` command) this file before scanning. -## cocoapods -Cocoapods uses package names in `PodFile.lock`, but [GitHub advisory database][ghsa] uses git links. -We parse [Cocoapods Specs][cocoapods-specs] to match package names and links. +## CocoaPods +CocoaPods uses package names in `PodFile.lock`, but [GitHub Advisory Database][ghsa] uses git links. +We parse [CocoaPods Specs][cocoapods-specs] to match package names and links. + +`GitHub Advisory Database` currently uses advisories for root module. But modules and submodules of `CocoaPods` use same git link. +We can't select only vulnerable submodule. +That is why Trivy shows vulnerabilities for all modules with the same URL. [cocoapods]: https://cocoapods.org/ [cocoapods-specs]: https://github.com/CocoaPods/Specs [ghsa]: https://github.com/advisories?query=type%3Areviewed+ecosystem%3Aswift [swift]: https://www.swift.org/package-manager/ -[package-resolved]: https://github.com/apple/swift-package-manager/blob/main/Documentation/Usage.md#resolving-versions-packageresolved-file +[package-resolved]: https://github.com/apple/swift-package-manager/blob/4a42f2519e3f7b8a731c5ed89b47ed577df8f86c/Documentation/Usage.md#resolving-versions-packageresolved-file [dependency-graph]: ../../configuration/reporting.md#show-origins-of-vulnerable-dependencies \ No newline at end of file From 775a6c39af9f14214fdf1c08f322b50c12194760 Mon Sep 17 00:00:00 2001 From: DmitriyLewen Date: Tue, 29 Aug 2023 12:57:36 +0600 Subject: [PATCH 11/12] add comment to join the module and submodule in purl --- pkg/detector/library/driver.go | 2 +- pkg/purl/purl.go | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/pkg/detector/library/driver.go b/pkg/detector/library/driver.go index 7350641fb0c8..52d0196efbd2 100644 --- a/pkg/detector/library/driver.go +++ b/pkg/detector/library/driver.go @@ -66,7 +66,7 @@ func NewDriver(libType string) (Driver, bool) { ecosystem = vulnerability.Swift comparer = compare.GenericComparer{} case ftypes.Cocoapods: - // Cocoapods uses RubyGems version specifiers + // CocoaPods uses RubyGems version specifiers // https://guides.cocoapods.org/making/making-a-cocoapod.html#cocoapods-versioning-specifics ecosystem = vulnerability.Cocoapods comparer = rubygems.Comparer{} diff --git a/pkg/purl/purl.go b/pkg/purl/purl.go index 92df2eb619d7..fa7ea391129e 100644 --- a/pkg/purl/purl.go +++ b/pkg/purl/purl.go @@ -57,9 +57,11 @@ func (p *PackageURL) Package() *ftypes.Package { } } - // Cocoapods purl has no namespace, but has subpath + // CocoaPods purl has no namespace, but has subpath // https://github.com/package-url/purl-spec/blob/a748c36ad415c8aeffe2b8a4a5d8a50d16d6d85f/PURL-TYPES.rst#cocoapods if p.Type == packageurl.TypeCocoapods && p.Subpath != "" { + // CocoaPods uses / format for package name + // e.g. `pkg:cocoapods/GoogleUtilities@7.5.2#NSData+zlib` => `GoogleUtilities/NSData+zlib` pkg.Name = strings.Join([]string{ p.Name, p.Subpath, From 3fe8925653c85af7ade8c404b7c0c6834b793b95 Mon Sep 17 00:00:00 2001 From: knqyf263 Date: Tue, 29 Aug 2023 15:12:22 +0300 Subject: [PATCH 12/12] docs: add an example --- docs/docs/coverage/language/swift.md | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/docs/docs/coverage/language/swift.md b/docs/docs/coverage/language/swift.md index f9867519339e..0245a06b44a3 100644 --- a/docs/docs/coverage/language/swift.md +++ b/docs/docs/coverage/language/swift.md @@ -20,19 +20,25 @@ These may be enabled or disabled depending on the target. See [here](./index.md) for the detail. ## Swift -Trivy parses [Package.resolved][package-resolved] file to find dependencies. Don't forger to update (`swift package update` command) this file before scanning. +Trivy parses [Package.resolved][package-resolved] file to find dependencies. +Don't forget to update (`swift package update` command) this file before scanning. ## CocoaPods -CocoaPods uses package names in `PodFile.lock`, but [GitHub Advisory Database][ghsa] uses git links. -We parse [CocoaPods Specs][cocoapods-specs] to match package names and links. +CocoaPods uses package names in `PodFile.lock`, but [GitHub Advisory Database (GHSA)][ghsa] Trivy relies on uses Git URLs. +We parse [the CocoaPods Specs][cocoapods-specs] to match package names and links. -`GitHub Advisory Database` currently uses advisories for root module. But modules and submodules of `CocoaPods` use same git link. -We can't select only vulnerable submodule. -That is why Trivy shows vulnerabilities for all modules with the same URL. +!!! note "Limitation" + Since [GHSA][ghsa] holds only Git URLs, such as github.com/apple/swift-nio, + Trivy can't identify affected submodules, and detect all submodules maintained by the same URL. + For example, [SwiftNIOHTTP1][niohttp1] and [SwiftNIOWebSocket][niowebsocket] both are maintained under `github.com/apple/swift-nio`, + and Trivy detect CVE-2022-3215 for both of them, even though only [SwiftNIOHTTP1][niohttp1] is actually affected. [cocoapods]: https://cocoapods.org/ [cocoapods-specs]: https://github.com/CocoaPods/Specs [ghsa]: https://github.com/advisories?query=type%3Areviewed+ecosystem%3Aswift [swift]: https://www.swift.org/package-manager/ [package-resolved]: https://github.com/apple/swift-package-manager/blob/4a42f2519e3f7b8a731c5ed89b47ed577df8f86c/Documentation/Usage.md#resolving-versions-packageresolved-file -[dependency-graph]: ../../configuration/reporting.md#show-origins-of-vulnerable-dependencies \ No newline at end of file +[dependency-graph]: ../../configuration/reporting.md#show-origins-of-vulnerable-dependencies + +[niohttp1]: https://cocoapods.org/pods/SwiftNIOHTTP1 +[niowebsocket]: https://cocoapods.org/pods/SwiftNIOWebSocket \ No newline at end of file