Skip to content

Commit

Permalink
feat: add Package.resolved swift files support (#4932)
Browse files Browse the repository at this point in the history
* add Package.resolved files analyzer

* add Swift detector and integration test

* refactor after go-dep-parser changes

* bump go-dep-parser

* remove replaces

* use filePath for Required func

* add ID field
  • Loading branch information
DmitriyLewen authored Aug 23, 2023
1 parent ec5d8be commit ef70d20
Show file tree
Hide file tree
Showing 16 changed files with 330 additions and 6 deletions.
1 change: 1 addition & 0 deletions .github/workflows/semantic-pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ jobs:
c\+\+
elixir
dart
swift
os
lang
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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-20230816082938-c86bfd152132
github.com/aquasecurity/go-dep-parser v0.0.0-20230823094455-40c1f85cc942
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
Expand All @@ -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-20230817085355-15ce04b6527c
github.com/aquasecurity/trivy-db v0.0.0-20230823084507-315928e846ff
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
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -325,8 +325,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-20230816082938-c86bfd152132 h1:SiiJwsijT2zgXJLGAPc5xXYH6QAnZjfsegm6vi2h/qo=
github.com/aquasecurity/go-dep-parser v0.0.0-20230816082938-c86bfd152132/go.mod h1:0+GvQF0gL4YEAAUPpNeLeGpFDxMvvIHLMd7vk9bpwko=
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=
Expand All @@ -345,8 +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-20230817085355-15ce04b6527c h1:vsWd8uL6C1MoeYhEaJFQU+Rcx93Qv1eFe6N1BO2LjUs=
github.com/aquasecurity/trivy-db v0.0.0-20230817085355-15ce04b6527c/go.mod h1:iJSGMMclPEhkYeyiN9i+gzjV9jhEv+XfPzfVgFhfvTE=
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=
Expand Down
9 changes: 9 additions & 0 deletions integration/repo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,15 @@ func TestRepository(t *testing.T) {
},
golden: "testdata/dotnet.json.golden",
},
{
name: "swift",
args: args{
scanner: types.VulnerabilityScanner,
listAllPkgs: true,
input: "testdata/fixtures/repo/swift",
},
golden: "testdata/swift.json.golden",
},
{
name: "cocoapods",
args: args{
Expand Down
14 changes: 14 additions & 0 deletions integration/testdata/fixtures/db/swift.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
- bucket: "swift::GitHub Security Advisory Swift"
pairs:
- bucket: github.com/apple/swift-nio
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"
18 changes: 18 additions & 0 deletions integration/testdata/fixtures/db/vulnerability.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1290,6 +1290,24 @@
- https://github.com/advisories/GHSA-4rgh-jx4f-qfcq
PublishedDate: "2022-05-24T17:37:16Z"
LastModifiedDate: "2022-10-06T20:26:08Z"
- key: CVE-2022-3215
value:
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
VendorSeverity:
ghsa: 2
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
PublishedDate: "2023-06-07T16:01:53Z"
LastModifiedDate: "2023-06-19T16:45:07Z"
- key: CVE-2022-24775
value:
Title: "Improper Input Validation in guzzlehttp/psr7"
Expand Down
25 changes: 25 additions & 0 deletions integration/testdata/fixtures/repo/swift/Package.resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"object": {
"pins": [
{
"package": "swift-atomics",
"repositoryURL": "https://github.com/apple/swift-atomics.git",
"state": {
"branch": null,
"revision": "6c89474e62719ddcc1e9614989fff2f68208fe10",
"version": "1.1.0"
}
},
{
"package": "swift-nio",
"repositoryURL": "https://github.com/apple/swift-nio",
"state": {
"branch": null,
"revision": "ece5057615d1bee848341eceafdf04ca54d60177",
"version": "2.41.0"
}
}
]
},
"version": 1
}
79 changes: 79 additions & 0 deletions integration/testdata/swift.json.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
{
"SchemaVersion": 2,
"ArtifactName": "testdata/fixtures/repo/swift",
"ArtifactType": "repository",
"Metadata": {
"ImageConfig": {
"architecture": "",
"created": "0001-01-01T00:00:00Z",
"os": "",
"rootfs": {
"type": "",
"diff_ids": null
},
"config": {}
}
},
"Results": [
{
"Target": "Package.resolved",
"Class": "lang-pkgs",
"Type": "swift",
"Packages": [
{
"ID": "github.com/apple/[email protected]",
"Name": "github.com/apple/swift-atomics",
"Version": "1.1.0",
"Layer": {},
"Locations": [
{
"StartLine": 4,
"EndLine": 12
}
]
},
{
"ID": "github.com/apple/[email protected]",
"Name": "github.com/apple/swift-nio",
"Version": "2.41.0",
"Layer": {},
"Locations": [
{
"StartLine": 13,
"EndLine": 21
}
]
}
],
"Vulnerabilities": [
{
"VulnerabilityID": "CVE-2022-3215",
"PkgID": "github.com/apple/[email protected]",
"PkgName": "github.com/apple/swift-nio",
"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"
],
"PublishedDate": "2023-06-07T16:01:53Z",
"LastModifiedDate": "2023-06-19T16:45:07Z"
}
]
}
]
}
5 changes: 5 additions & 0 deletions pkg/detector/library/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ func NewDriver(libType string) (Driver, bool) {
// Only semver can be used for version ranges
// https://docs.conan.io/en/latest/versioning/version_ranges.html
comparer = compare.GenericComparer{}
case ftypes.Swift:
// Swift uses semver
// https://www.swift.org/package-manager/#importing-dependencies
ecosystem = vulnerability.Swift
comparer = compare.GenericComparer{}
case ftypes.Cocoapods:
log.Logger.Warn("CocoaPods is supported for SBOM, not for vulnerability scanning")
return Driver{}, false
Expand Down
1 change: 1 addition & 0 deletions pkg/fanal/analyzer/all/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/rust/binary"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/rust/cargo"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/swift/cocoapods"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/swift/swift"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/licensing"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/os/alpine"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/os/amazonlinux"
Expand Down
1 change: 1 addition & 0 deletions pkg/fanal/analyzer/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ const (
TypeMixLock Type = "mix-lock"

// Swift
TypeSwift Type = "swift"
TypeCocoaPods Type = "cocoapods"

// Dart
Expand Down
46 changes: 46 additions & 0 deletions pkg/fanal/analyzer/language/swift/swift/swift.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package swift

import (
"context"
"os"
"path"

"github.com/aquasecurity/go-dep-parser/pkg/swift/swift"
"github.com/aquasecurity/trivy/pkg/fanal/analyzer"
"github.com/aquasecurity/trivy/pkg/fanal/analyzer/language"
"github.com/aquasecurity/trivy/pkg/fanal/types"

"golang.org/x/xerrors"
)

func init() {
analyzer.RegisterAnalyzer(&swiftLockAnalyzer{})
}

const (
version = 1
)

// swiftLockAnalyzer analyzes Package.resolved files
type swiftLockAnalyzer struct{}

func (a swiftLockAnalyzer) Analyze(_ context.Context, input analyzer.AnalysisInput) (*analyzer.AnalysisResult, error) {
p := swift.NewParser()
res, err := language.Analyze(types.Swift, input.FilePath, input.Content, p)
if err != nil {
return nil, xerrors.Errorf("%s parse error: %w", input.FilePath, err)
}
return res, nil
}

func (a swiftLockAnalyzer) Required(filePath string, _ os.FileInfo) bool {
return path.Base(filePath) == types.SwiftResolved
}

func (a swiftLockAnalyzer) Type() analyzer.Type {
return analyzer.TypeSwift
}

func (a swiftLockAnalyzer) Version() int {
return version
}
88 changes: 88 additions & 0 deletions pkg/fanal/analyzer/language/swift/swift/swift_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package swift

import (
"github.com/aquasecurity/trivy/pkg/fanal/analyzer"
"github.com/aquasecurity/trivy/pkg/fanal/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"os"
"testing"
)

func Test_swiftLockAnalyzer_Analyze(t *testing.T) {
tests := []struct {
name string
inputFile string
want *analyzer.AnalysisResult
}{
{
name: "happy path",
inputFile: "testdata/happy/Package.resolved",
want: &analyzer.AnalysisResult{
Applications: []types.Application{
{
Type: types.Swift,
FilePath: "testdata/happy/Package.resolved",
Libraries: types.Packages{

{
ID: "github.com/Quick/[email protected]",
Name: "github.com/Quick/Nimble",
Version: "9.2.1",
Locations: []types.Location{
{
StartLine: 4,
EndLine: 12,
},
},
},
{
ID: "github.com/Quick/[email protected]",
Name: "github.com/Quick/Quick",
Version: "7.0.0",
Locations: []types.Location{
{
StartLine: 13,
EndLine: 21,
},
},
},
{
ID: "github.com/ReactiveCocoa/[email protected]",
Name: "github.com/ReactiveCocoa/ReactiveSwift",
Version: "7.1.1",
Locations: []types.Location{
{
StartLine: 22,
EndLine: 30,
},
},
},
},
},
},
},
},
{
name: "empty file",
inputFile: "testdata/empty/Package.resolved",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
f, err := os.Open(tt.inputFile)
require.NoError(t, err)
defer f.Close()

a := swiftLockAnalyzer{}
got, err := a.Analyze(nil, analyzer.AnalysisInput{
FilePath: tt.inputFile,
Content: f,
})

assert.NoError(t, err)
assert.Equal(t, tt.want, got)
})
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
Loading

0 comments on commit ef70d20

Please sign in to comment.