mirror of
https://github.com/aquasecurity/trivy.git
synced 2025-12-12 15:50:15 -08:00
feat: add support pubspec.lock files for dart (#3344)
Co-authored-by: knqyf263 <knqyf263@gmail.com>
This commit is contained in:
1
.github/workflows/semantic-pr.yaml
vendored
1
.github/workflows/semantic-pr.yaml
vendored
@@ -71,6 +71,7 @@ jobs:
|
|||||||
c
|
c
|
||||||
c++
|
c++
|
||||||
elixir
|
elixir
|
||||||
|
dart
|
||||||
|
|
||||||
os
|
os
|
||||||
lang
|
lang
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ language:
|
|||||||
- java
|
- java
|
||||||
- go
|
- go
|
||||||
- elixir
|
- elixir
|
||||||
|
- dart
|
||||||
|
|
||||||
vuln:
|
vuln:
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
| Rust | [Open Source Vulnerabilities (crates.io)][rust-osv] | ✅ | - |
|
| Rust | [Open Source Vulnerabilities (crates.io)][rust-osv] | ✅ | - |
|
||||||
| .NET | [GitHub Advisory Database (NuGet)][dotnet-ghsa] | ✅ | - |
|
| .NET | [GitHub Advisory Database (NuGet)][dotnet-ghsa] | ✅ | - |
|
||||||
| C/C++ | [GitLab Advisories Community][gitlab] | ✅ | 1 month |
|
| 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] | ✅ | |
|
||||||
|
|
||||||
[^1]: Intentional delay between vulnerability disclosure and registration in the DB
|
[^1]: Intentional delay between vulnerability disclosure and registration in the DB
|
||||||
@@ -79,6 +80,7 @@ The severity is from the selected data source. If the data source does not provi
|
|||||||
[nodejs-ghsa]: https://github.com/advisories?query=ecosystem%3Anpm
|
[nodejs-ghsa]: https://github.com/advisories?query=ecosystem%3Anpm
|
||||||
[java-ghsa]: https://github.com/advisories?query=ecosystem%3Amaven
|
[java-ghsa]: https://github.com/advisories?query=ecosystem%3Amaven
|
||||||
[dotnet-ghsa]: https://github.com/advisories?query=ecosystem%3Anuget
|
[dotnet-ghsa]: https://github.com/advisories?query=ecosystem%3Anuget
|
||||||
|
[pub-ghsa]: https://github.com/advisories?query=ecosystem%3Apub
|
||||||
[erlang-ghsa]: https://github.com/advisories?query=ecosystem%3Aerlang
|
[erlang-ghsa]: https://github.com/advisories?query=ecosystem%3Aerlang
|
||||||
|
|
||||||
[php]: https://github.com/FriendsOfPHP/security-advisories
|
[php]: https://github.com/FriendsOfPHP/security-advisories
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
| | Binaries built with [cargo-auditable](https://github.com/rust-secure-code/cargo-auditable) | ✅ | ✅ | - | - | excluded | - |
|
| | Binaries built with [cargo-auditable](https://github.com/rust-secure-code/cargo-auditable) | ✅ | ✅ | - | - | excluded | - |
|
||||||
| C/C++ | conan.lock[^13] | - | - | ✅ | ✅ | excluded | - |
|
| C/C++ | conan.lock[^13] | - | - | ✅ | ✅ | excluded | - |
|
||||||
| Elixir | mix.lock[^13] | - | - | ✅ | ✅ | excluded | ✅ |
|
| Elixir | mix.lock[^13] | - | - | ✅ | ✅ | excluded | ✅ |
|
||||||
|
| Dart | pubspec.lock | ✅ | ✅ | - | - | included | - |
|
||||||
|
|
||||||
The path of these files does not matter.
|
The path of these files does not matter.
|
||||||
|
|
||||||
|
|||||||
2
go.mod
2
go.mod
@@ -19,7 +19,7 @@ require (
|
|||||||
github.com/aquasecurity/table v1.8.0
|
github.com/aquasecurity/table v1.8.0
|
||||||
github.com/aquasecurity/testdocker v0.0.0-20210911155206-e1e85f5a1516
|
github.com/aquasecurity/testdocker v0.0.0-20210911155206-e1e85f5a1516
|
||||||
github.com/aquasecurity/tml v0.6.1
|
github.com/aquasecurity/tml v0.6.1
|
||||||
github.com/aquasecurity/trivy-db v0.0.0-20221227141502-af78ecb7db4c
|
github.com/aquasecurity/trivy-db v0.0.0-20230105123735-5ce110fc82e1
|
||||||
github.com/aquasecurity/trivy-kubernetes v0.3.1-0.20221021174315-8d74450b4506
|
github.com/aquasecurity/trivy-kubernetes v0.3.1-0.20221021174315-8d74450b4506
|
||||||
github.com/aws/aws-sdk-go v1.44.171
|
github.com/aws/aws-sdk-go v1.44.171
|
||||||
github.com/aws/aws-sdk-go-v2 v1.17.1
|
github.com/aws/aws-sdk-go-v2 v1.17.1
|
||||||
|
|||||||
4
go.sum
4
go.sum
@@ -217,8 +217,8 @@ github.com/aquasecurity/testdocker v0.0.0-20210911155206-e1e85f5a1516 h1:moQmzbp
|
|||||||
github.com/aquasecurity/testdocker v0.0.0-20210911155206-e1e85f5a1516/go.mod h1:gTd97VdQ0rg8Mkiic3rPgNOQdprZ7feTAhiD5mGQjgM=
|
github.com/aquasecurity/testdocker v0.0.0-20210911155206-e1e85f5a1516/go.mod h1:gTd97VdQ0rg8Mkiic3rPgNOQdprZ7feTAhiD5mGQjgM=
|
||||||
github.com/aquasecurity/tml v0.6.1 h1:y2ZlGSfrhnn7t4ZJ/0rotuH+v5Jgv6BDDO5jB6A9gwo=
|
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/tml v0.6.1/go.mod h1:OnYMWY5lvI9ejU7yH9LCberWaaTBW7hBFsITiIMY2yY=
|
||||||
github.com/aquasecurity/trivy-db v0.0.0-20221227141502-af78ecb7db4c h1:CgJiXxVxgFOQ4btP97LEYqEHnx++FRpf2IJEXJV+xHs=
|
github.com/aquasecurity/trivy-db v0.0.0-20230105123735-5ce110fc82e1 h1:3ANUmuIZlMpSmhd6ah3FWQuZxZQFdpRzlrn0p90zzVc=
|
||||||
github.com/aquasecurity/trivy-db v0.0.0-20221227141502-af78ecb7db4c/go.mod h1:/nULgnDeq/JMPMVwE1dmf4kWlYn++7VrM3O2naj4BHA=
|
github.com/aquasecurity/trivy-db v0.0.0-20230105123735-5ce110fc82e1/go.mod h1:/nULgnDeq/JMPMVwE1dmf4kWlYn++7VrM3O2naj4BHA=
|
||||||
github.com/aquasecurity/trivy-kubernetes v0.3.1-0.20221021174315-8d74450b4506 h1:maijOWmI5Ec/R7V0wpXoqvQC7fTjQD+PbDktKIK1VXs=
|
github.com/aquasecurity/trivy-kubernetes v0.3.1-0.20221021174315-8d74450b4506 h1:maijOWmI5Ec/R7V0wpXoqvQC7fTjQD+PbDktKIK1VXs=
|
||||||
github.com/aquasecurity/trivy-kubernetes v0.3.1-0.20221021174315-8d74450b4506/go.mod h1:xXd1m0iRJrz3ISbOXVDaR4hCWoSrF4RbIfNTN4dTrjY=
|
github.com/aquasecurity/trivy-kubernetes v0.3.1-0.20221021174315-8d74450b4506/go.mod h1:xXd1m0iRJrz3ISbOXVDaR4hCWoSrF4RbIfNTN4dTrjY=
|
||||||
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q=
|
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q=
|
||||||
|
|||||||
@@ -147,6 +147,15 @@ func TestFilesystem(t *testing.T) {
|
|||||||
},
|
},
|
||||||
golden: "testdata/cocoapods.json.golden",
|
golden: "testdata/cocoapods.json.golden",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "pubspec.lock",
|
||||||
|
args: args{
|
||||||
|
securityChecks: "vuln",
|
||||||
|
listAllPkgs: true,
|
||||||
|
input: "testdata/fixtures/fs/pubspec",
|
||||||
|
},
|
||||||
|
golden: "testdata/pubspec.lock.json.golden",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "mix.lock",
|
name: "mix.lock",
|
||||||
args: args{
|
args: args{
|
||||||
|
|||||||
@@ -30,6 +30,11 @@
|
|||||||
ID: "ghsa"
|
ID: "ghsa"
|
||||||
Name: "GitHub Security Advisory RubyGems"
|
Name: "GitHub Security Advisory RubyGems"
|
||||||
URL: "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Arubygems"
|
URL: "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Arubygems"
|
||||||
|
- key: "pub::GitHub Security Advisory Pub"
|
||||||
|
value:
|
||||||
|
ID: "ghsa"
|
||||||
|
Name: "GitHub Security Advisory Pub"
|
||||||
|
URL: "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Apub"
|
||||||
- key: "erlang::GitHub Security Advisory Erlang"
|
- key: "erlang::GitHub Security Advisory Erlang"
|
||||||
value:
|
value:
|
||||||
ID: "ghsa"
|
ID: "ghsa"
|
||||||
|
|||||||
10
integration/testdata/fixtures/db/pub.yaml
vendored
Normal file
10
integration/testdata/fixtures/db/pub.yaml
vendored
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
- bucket: pub::GitHub Security Advisory Pub
|
||||||
|
pairs:
|
||||||
|
- bucket: http
|
||||||
|
pairs:
|
||||||
|
- key: CVE-2020-35669
|
||||||
|
value:
|
||||||
|
PatchedVersions:
|
||||||
|
- 0.13.3
|
||||||
|
VulnerableVersions:
|
||||||
|
- "<= 0.13.3"
|
||||||
@@ -1271,6 +1271,29 @@
|
|||||||
- https://github.com/advisories/GHSA-p8f7-22gq-m7j9
|
- https://github.com/advisories/GHSA-p8f7-22gq-m7j9
|
||||||
PublishedDate: "2022-10-17T12:00:27Z"
|
PublishedDate: "2022-10-17T12:00:27Z"
|
||||||
LastModifiedDate: "2022-10-18T18:01:44Z"
|
LastModifiedDate: "2022-10-18T18:01:44Z"
|
||||||
|
- key: CVE-2020-35669
|
||||||
|
value:
|
||||||
|
Title: "http before 0.13.3 vulnerable to header injection"
|
||||||
|
Description: "An issue was discovered in the http package before 0.13.3 for Dart. If the attacker controls the HTTP method and the app is using Request directly, it's possible to achieve CRLF injection in an HTTP request via HTTP header injection. This issue has been addressed in commit abb2bb182 by validating request methods."
|
||||||
|
Severity: MEDIUM
|
||||||
|
VendorSeverity:
|
||||||
|
ghsa: 2
|
||||||
|
CweIDs:
|
||||||
|
- CWE-74
|
||||||
|
CVSS:
|
||||||
|
ghsa:
|
||||||
|
V3Vector: "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N"
|
||||||
|
V3Score: 6.1
|
||||||
|
References:
|
||||||
|
- https://nvd.nist.gov/vuln/detail/CVE-2020-35669
|
||||||
|
- https://github.com/dart-lang/http/issues/511
|
||||||
|
- https://github.com/dart-lang/http/blob/master/CHANGELOG.md#0133
|
||||||
|
- https://github.com/dart-lang/http/pull/512
|
||||||
|
- https://github.com/dart-lang/http/commit/abb2bb182fbd7f03aafd1f889b902d7b3bdb8769
|
||||||
|
- https://pub.dev/packages/http/changelog#0133
|
||||||
|
- https://github.com/advisories/GHSA-4rgh-jx4f-qfcq
|
||||||
|
PublishedDate: "2022-05-24T17:37:16Z"
|
||||||
|
LastModifiedDate: "2022-10-06T20:26:08Z"
|
||||||
- key: CVE-2022-22965
|
- key: CVE-2022-22965
|
||||||
value:
|
value:
|
||||||
Title: "spring-framework: RCE via Data Binding on JDK 9+"
|
Title: "spring-framework: RCE via Data Binding on JDK 9+"
|
||||||
|
|||||||
20
integration/testdata/fixtures/fs/pubspec/pubspec.lock
vendored
Normal file
20
integration/testdata/fixtures/fs/pubspec/pubspec.lock
vendored
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# Generated by pub
|
||||||
|
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||||
|
packages:
|
||||||
|
http:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: http
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.13.2"
|
||||||
|
shelf:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: shelf
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.3.1"
|
||||||
|
sdks:
|
||||||
|
dart: ">=2.18.0 <3.0.0"
|
||||||
|
flutter: ">=3.3.0"
|
||||||
77
integration/testdata/pubspec.lock.json.golden
vendored
Normal file
77
integration/testdata/pubspec.lock.json.golden
vendored
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
{
|
||||||
|
"SchemaVersion": 2,
|
||||||
|
"ArtifactName": "testdata/fixtures/fs/pubspec",
|
||||||
|
"ArtifactType": "filesystem",
|
||||||
|
"Metadata": {
|
||||||
|
"ImageConfig": {
|
||||||
|
"architecture": "",
|
||||||
|
"created": "0001-01-01T00:00:00Z",
|
||||||
|
"os": "",
|
||||||
|
"rootfs": {
|
||||||
|
"type": "",
|
||||||
|
"diff_ids": null
|
||||||
|
},
|
||||||
|
"config": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Results": [
|
||||||
|
{
|
||||||
|
"Target": "pubspec.lock",
|
||||||
|
"Class": "lang-pkgs",
|
||||||
|
"Type": "pub",
|
||||||
|
"Packages": [
|
||||||
|
{
|
||||||
|
"ID": "http@0.13.2",
|
||||||
|
"Name": "http",
|
||||||
|
"Version": "0.13.2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ID": "shelf@1.3.1",
|
||||||
|
"Name": "shelf",
|
||||||
|
"Version": "1.3.1",
|
||||||
|
"Indirect": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Vulnerabilities": [
|
||||||
|
{
|
||||||
|
"VulnerabilityID": "CVE-2020-35669",
|
||||||
|
"PkgName": "http",
|
||||||
|
"PkgID": "http@0.13.2",
|
||||||
|
"InstalledVersion": "0.13.2",
|
||||||
|
"FixedVersion": "0.13.3",
|
||||||
|
"Layer": {},
|
||||||
|
"SeveritySource": "ghsa",
|
||||||
|
"PrimaryURL": "https://avd.aquasec.com/nvd/cve-2020-35669",
|
||||||
|
"DataSource": {
|
||||||
|
"ID": "ghsa",
|
||||||
|
"Name": "GitHub Security Advisory Pub",
|
||||||
|
"URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Apub"
|
||||||
|
},
|
||||||
|
"Title": "http before 0.13.3 vulnerable to header injection",
|
||||||
|
"Description": "An issue was discovered in the http package before 0.13.3 for Dart. If the attacker controls the HTTP method and the app is using Request directly, it's possible to achieve CRLF injection in an HTTP request via HTTP header injection. This issue has been addressed in commit abb2bb182 by validating request methods.",
|
||||||
|
"Severity": "MEDIUM",
|
||||||
|
"CweIDs": [
|
||||||
|
"CWE-74"
|
||||||
|
],
|
||||||
|
"CVSS": {
|
||||||
|
"ghsa": {
|
||||||
|
"V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N",
|
||||||
|
"V3Score": 6.1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"References": [
|
||||||
|
"https://nvd.nist.gov/vuln/detail/CVE-2020-35669",
|
||||||
|
"https://github.com/dart-lang/http/issues/511",
|
||||||
|
"https://github.com/dart-lang/http/blob/master/CHANGELOG.md#0133",
|
||||||
|
"https://github.com/dart-lang/http/pull/512",
|
||||||
|
"https://github.com/dart-lang/http/commit/abb2bb182fbd7f03aafd1f889b902d7b3bdb8769",
|
||||||
|
"https://pub.dev/packages/http/changelog#0133",
|
||||||
|
"https://github.com/advisories/GHSA-4rgh-jx4f-qfcq"
|
||||||
|
],
|
||||||
|
"PublishedDate": "2022-05-24T17:37:16Z",
|
||||||
|
"LastModifiedDate": "2022-10-06T20:26:08Z"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -51,6 +51,9 @@ func NewDriver(libType string) (Driver, error) {
|
|||||||
case ftypes.Pipenv, ftypes.Poetry, ftypes.Pip, ftypes.PythonPkg:
|
case ftypes.Pipenv, ftypes.Poetry, ftypes.Pip, ftypes.PythonPkg:
|
||||||
ecosystem = vulnerability.Pip
|
ecosystem = vulnerability.Pip
|
||||||
comparer = pep440.Comparer{}
|
comparer = pep440.Comparer{}
|
||||||
|
case ftypes.Pub:
|
||||||
|
ecosystem = vulnerability.Pub
|
||||||
|
comparer = compare.GenericComparer{}
|
||||||
case ftypes.Hex:
|
case ftypes.Hex:
|
||||||
ecosystem = vulnerability.Erlang
|
ecosystem = vulnerability.Erlang
|
||||||
comparer = compare.GenericComparer{}
|
comparer = compare.GenericComparer{}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/config/all"
|
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/config/all"
|
||||||
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/executable"
|
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/executable"
|
||||||
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/c/conan"
|
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/c/conan"
|
||||||
|
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/dart/pub"
|
||||||
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/dotnet/deps"
|
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/dotnet/deps"
|
||||||
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/dotnet/nuget"
|
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/dotnet/nuget"
|
||||||
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/elixir/mix"
|
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/elixir/mix"
|
||||||
|
|||||||
@@ -80,6 +80,9 @@ const (
|
|||||||
// Swift
|
// Swift
|
||||||
TypeCocoaPods Type = "cocoapods"
|
TypeCocoaPods Type = "cocoapods"
|
||||||
|
|
||||||
|
// Dart
|
||||||
|
TypePubSpecLock Type = "pubspec-lock"
|
||||||
|
|
||||||
// ============
|
// ============
|
||||||
// Non-packaged
|
// Non-packaged
|
||||||
// ============
|
// ============
|
||||||
@@ -131,14 +134,14 @@ var (
|
|||||||
TypeBundler, TypeGemSpec, TypeCargo, TypeComposer, TypeJar, TypePom, TypeGradleLock,
|
TypeBundler, TypeGemSpec, TypeCargo, TypeComposer, TypeJar, TypePom, TypeGradleLock,
|
||||||
TypeNpmPkgLock, TypeNodePkg, TypeYarn, TypePnpm, TypeNuget, TypeDotNetCore,
|
TypeNpmPkgLock, TypeNodePkg, TypeYarn, TypePnpm, TypeNuget, TypeDotNetCore,
|
||||||
TypePythonPkg, TypePip, TypePipenv, TypePoetry, TypeGoBinary, TypeGoMod, TypeRustBinary, TypeConanLock,
|
TypePythonPkg, TypePip, TypePipenv, TypePoetry, TypeGoBinary, TypeGoMod, TypeRustBinary, TypeConanLock,
|
||||||
TypeCocoaPods, TypeMixLock,
|
TypeCocoaPods, TypePubSpecLock, TypeMixLock,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TypeLockfiles has all lock file analyzers
|
// TypeLockfiles has all lock file analyzers
|
||||||
TypeLockfiles = []Type{
|
TypeLockfiles = []Type{
|
||||||
TypeBundler, TypeNpmPkgLock, TypeYarn,
|
TypeBundler, TypeNpmPkgLock, TypeYarn,
|
||||||
TypePnpm, TypePip, TypePipenv, TypePoetry, TypeGoMod, TypePom, TypeConanLock, TypeGradleLock,
|
TypePnpm, TypePip, TypePipenv, TypePoetry, TypeGoMod, TypePom, TypeConanLock, TypeGradleLock,
|
||||||
TypeCocoaPods, TypeMixLock,
|
TypeCocoaPods, TypePubSpecLock, TypeMixLock,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TypeIndividualPkgs has all analyzers for individual packages
|
// TypeIndividualPkgs has all analyzers for individual packages
|
||||||
|
|||||||
46
pkg/fanal/analyzer/language/dart/pub/pubspec.go
Normal file
46
pkg/fanal/analyzer/language/dart/pub/pubspec.go
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
package pub
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
|
"github.com/aquasecurity/go-dep-parser/pkg/dart/pub"
|
||||||
|
"github.com/aquasecurity/trivy/pkg/fanal/analyzer"
|
||||||
|
"github.com/aquasecurity/trivy/pkg/fanal/analyzer/language"
|
||||||
|
"github.com/aquasecurity/trivy/pkg/fanal/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
analyzer.RegisterAnalyzer(&pubSpecLockAnalyzer{})
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
version = 1
|
||||||
|
)
|
||||||
|
|
||||||
|
// pubSpecLockAnalyzer analyzes pubspec.lock
|
||||||
|
type pubSpecLockAnalyzer struct{}
|
||||||
|
|
||||||
|
func (a pubSpecLockAnalyzer) Analyze(_ context.Context, input analyzer.AnalysisInput) (*analyzer.AnalysisResult, error) {
|
||||||
|
p := pub.NewParser()
|
||||||
|
res, err := language.Analyze(types.Pub, input.FilePath, input.Content, p)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("%s parse error: %w", input.FilePath, err)
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a pubSpecLockAnalyzer) Required(filePath string, _ os.FileInfo) bool {
|
||||||
|
return filepath.Base(filePath) == types.PubSpecLock
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a pubSpecLockAnalyzer) Type() analyzer.Type {
|
||||||
|
return analyzer.TypePubSpecLock
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a pubSpecLockAnalyzer) Version() int {
|
||||||
|
return version
|
||||||
|
}
|
||||||
115
pkg/fanal/analyzer/language/dart/pub/pubspec_test.go
Normal file
115
pkg/fanal/analyzer/language/dart/pub/pubspec_test.go
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
package pub
|
||||||
|
|
||||||
|
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"
|
||||||
|
"sort"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_pubSpecLockAnalyzer_Analyze(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
inputFile string
|
||||||
|
want *analyzer.AnalysisResult
|
||||||
|
wantErr assert.ErrorAssertionFunc
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "happy path",
|
||||||
|
inputFile: "testdata/happy.lock",
|
||||||
|
want: &analyzer.AnalysisResult{
|
||||||
|
Applications: []types.Application{
|
||||||
|
{
|
||||||
|
Type: types.Pub,
|
||||||
|
FilePath: "testdata/happy.lock",
|
||||||
|
Libraries: []types.Package{
|
||||||
|
{
|
||||||
|
ID: "crypto@3.0.2",
|
||||||
|
Name: "crypto",
|
||||||
|
Version: "3.0.2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "flutter_test@0.0.0",
|
||||||
|
Name: "flutter_test",
|
||||||
|
Version: "0.0.0",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "uuid@3.0.6",
|
||||||
|
Name: "uuid",
|
||||||
|
Version: "3.0.6",
|
||||||
|
Indirect: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantErr: assert.NoError,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "empty file",
|
||||||
|
inputFile: "testdata/empty.lock",
|
||||||
|
wantErr: assert.NoError,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "broken file",
|
||||||
|
inputFile: "testdata/broken.lock",
|
||||||
|
wantErr: assert.Error,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
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 := pubSpecLockAnalyzer{}
|
||||||
|
got, err := a.Analyze(nil, analyzer.AnalysisInput{
|
||||||
|
FilePath: tt.inputFile,
|
||||||
|
Content: f,
|
||||||
|
})
|
||||||
|
|
||||||
|
if got != nil {
|
||||||
|
for _, app := range got.Applications {
|
||||||
|
sort.Slice(app.Libraries, func(i, j int) bool {
|
||||||
|
return app.Libraries[i].ID < app.Libraries[j].ID
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !tt.wantErr(t, err, tt.inputFile) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
assert.Equal(t, tt.want, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_pubSpecLockAnalyzer_Required(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
filePath string
|
||||||
|
want bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "happy path",
|
||||||
|
filePath: "pubspec.lock",
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "sad path",
|
||||||
|
filePath: "test.txt",
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
a := pubSpecLockAnalyzer{}
|
||||||
|
got := a.Required(tt.filePath, nil)
|
||||||
|
assert.Equal(t, tt.want, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
1
pkg/fanal/analyzer/language/dart/pub/testdata/broken.lock
vendored
Normal file
1
pkg/fanal/analyzer/language/dart/pub/testdata/broken.lock
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
it is broken
|
||||||
6
pkg/fanal/analyzer/language/dart/pub/testdata/empty.lock
vendored
Normal file
6
pkg/fanal/analyzer/language/dart/pub/testdata/empty.lock
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# Generated by pub
|
||||||
|
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||||
|
packages:
|
||||||
|
sdks:
|
||||||
|
dart: ">=2.18.0 <3.0.0"
|
||||||
|
flutter: ">=3.3.0"
|
||||||
25
pkg/fanal/analyzer/language/dart/pub/testdata/happy.lock
vendored
Normal file
25
pkg/fanal/analyzer/language/dart/pub/testdata/happy.lock
vendored
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
# Generated by pub
|
||||||
|
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||||
|
packages:
|
||||||
|
crypto:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: crypto
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.2"
|
||||||
|
flutter_test:
|
||||||
|
dependency: "direct dev"
|
||||||
|
description: flutter
|
||||||
|
source: sdk
|
||||||
|
version: "0.0.0"
|
||||||
|
uuid:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: uuid
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.6"
|
||||||
|
sdks:
|
||||||
|
dart: ">=2.18.0 <3.0.0"
|
||||||
|
flutter: ">=3.3.0"
|
||||||
@@ -30,6 +30,7 @@ const (
|
|||||||
RustBinary = "rustbinary"
|
RustBinary = "rustbinary"
|
||||||
Conan = "conan"
|
Conan = "conan"
|
||||||
Cocoapods = "cocoapods"
|
Cocoapods = "cocoapods"
|
||||||
|
Pub = "pub"
|
||||||
Hex = "hex"
|
Hex = "hex"
|
||||||
|
|
||||||
// Config files
|
// Config files
|
||||||
@@ -75,5 +76,7 @@ const (
|
|||||||
|
|
||||||
CocoaPodsLock = "Podfile.lock"
|
CocoaPodsLock = "Podfile.lock"
|
||||||
|
|
||||||
|
PubSpecLock = "pubspec.lock"
|
||||||
|
|
||||||
MixLock = "mix.lock"
|
MixLock = "mix.lock"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -16,8 +16,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
TypeAPK = "apk" // not defined in github.com/package-url/packageurl-go
|
TypeAPK = "apk" // not defined in github.com/package-url/packageurl-go
|
||||||
TypeOCI = "oci"
|
TypeOCI = "oci"
|
||||||
|
TypeDart = "dart"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PackageURL struct {
|
type PackageURL struct {
|
||||||
@@ -98,6 +99,8 @@ func (p *PackageURL) PackageType() string {
|
|||||||
return ftypes.Cocoapods
|
return ftypes.Cocoapods
|
||||||
case packageurl.TypeHex:
|
case packageurl.TypeHex:
|
||||||
return ftypes.Hex
|
return ftypes.Hex
|
||||||
|
case TypeDart: // TODO: replace with packageurl.TypeDart once they add it.
|
||||||
|
return ftypes.Pub
|
||||||
}
|
}
|
||||||
return p.Type
|
return p.Type
|
||||||
}
|
}
|
||||||
@@ -312,6 +315,8 @@ func purlType(t string) string {
|
|||||||
return packageurl.TypeSwift
|
return packageurl.TypeSwift
|
||||||
case ftypes.Hex:
|
case ftypes.Hex:
|
||||||
return packageurl.TypeHex
|
return packageurl.TypeHex
|
||||||
|
case ftypes.Pub:
|
||||||
|
return TypeDart // TODO: replace with packageurl.TypeDart once they add it.
|
||||||
case os.Alpine:
|
case os.Alpine:
|
||||||
return TypeAPK
|
return TypeAPK
|
||||||
case os.Debian, os.Ubuntu:
|
case os.Debian, os.Ubuntu:
|
||||||
|
|||||||
@@ -183,6 +183,21 @@ func TestNewPackageURL(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "dart package",
|
||||||
|
typ: ftypes.Pub,
|
||||||
|
pkg: ftypes.Package{
|
||||||
|
Name: "http",
|
||||||
|
Version: "0.13.2",
|
||||||
|
},
|
||||||
|
want: purl.PackageURL{
|
||||||
|
PackageURL: packageurl.PackageURL{
|
||||||
|
Type: purl.TypeDart,
|
||||||
|
Name: "http",
|
||||||
|
Version: "0.13.2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "os package",
|
name: "os package",
|
||||||
typ: os.RedHat,
|
typ: os.RedHat,
|
||||||
@@ -393,6 +408,18 @@ func TestFromString(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "happy path for dart",
|
||||||
|
purl: "pkg:dart/http@0.13.2",
|
||||||
|
want: purl.PackageURL{
|
||||||
|
PackageURL: packageurl.PackageURL{
|
||||||
|
Type: purl.TypeDart,
|
||||||
|
Name: "http",
|
||||||
|
Version: "0.13.2",
|
||||||
|
Qualifiers: packageurl.Qualifiers{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "happy path for apk",
|
name: "happy path for apk",
|
||||||
purl: "pkg:apk/alpine/alpine-baselayout@3.2.0-r16?distro=3.14.2",
|
purl: "pkg:apk/alpine/alpine-baselayout@3.2.0-r16?distro=3.14.2",
|
||||||
|
|||||||
Reference in New Issue
Block a user