feat: add support for mix.lock files for elixir language (#3328)

Co-authored-by: knqyf263 <knqyf263@gmail.com>
This commit is contained in:
DmitriyLewen
2022-12-29 16:18:51 +03:00
committed by GitHub
parent a888440922
commit eaa5bcf7d2
22 changed files with 451 additions and 26 deletions

View File

@@ -70,6 +70,7 @@ jobs:
go
c
c++
elixir
os
lang

View File

@@ -80,6 +80,7 @@ language:
- dotnet
- java
- go
- elixir
vuln:

View File

@@ -20,23 +20,24 @@
# Programming Language
| 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] | ✅ | - |
| | [Open Source Vulnerabilities (PyPI)][python-osv] | ✅ | - |
| Ruby | [Ruby Advisory Database][ruby] | ✅ | - |
| | [GitHub Advisory Database (RubyGems)][ruby-ghsa] | ✅ | - |
| Node.js | [Ecosystem Security Working Group][nodejs] | ✅ | - |
| | [GitHub Advisory Database (npm)][nodejs-ghsa] | ✅ | - |
| Java | [GitLab Advisories Community][gitlab] | ✅ | 1 month |
| | [GitHub Advisory Database (Maven)][java-ghsa] | ✅ | - |
| Go | [GitLab Advisories Community][gitlab] | ✅ | 1 month |
| | [The Go Vulnerability Database][go] | ✅ | - |
| Rust | [Open Source Vulnerabilities (crates.io)][rust-osv] | ✅ | - |
| .NET | [GitHub Advisory Database (NuGet)][dotnet-ghsa] | ✅ | - |
| C/C++ | [GitLab Advisories Community][gitlab] | ✅ | 1 month |
| 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] | | - |
| | [Open Source Vulnerabilities (PyPI)][python-osv] | | - |
| Ruby | [Ruby Advisory Database][ruby] | | - |
| | [GitHub Advisory Database (RubyGems)][ruby-ghsa] | | - |
| Node.js | [Ecosystem Security Working Group][nodejs] | | - |
| | [GitHub Advisory Database (npm)][nodejs-ghsa] | | - |
| Java | [GitLab Advisories Community][gitlab] | ✅ | 1 month |
| | [GitHub Advisory Database (Maven)][java-ghsa] | | - |
| Go | [GitLab Advisories Community][gitlab] | ✅ | 1 month |
| | [The Go Vulnerability Database][go] | | - |
| Rust | [Open Source Vulnerabilities (crates.io)][rust-osv] | | - |
| .NET | [GitHub Advisory Database (NuGet)][dotnet-ghsa] | | - |
| C/C++ | [GitLab Advisories Community][gitlab] | ✅ | 1 month |
| Elixir | [GitHub Advisory Database (Erlang)][erlang-ghsa] | ✅ | |
[^1]: Intentional delay between vulnerability disclosure and registration in the DB
@@ -78,6 +79,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
[java-ghsa]: https://github.com/advisories?query=ecosystem%3Amaven
[dotnet-ghsa]: https://github.com/advisories?query=ecosystem%3Anuget
[erlang-ghsa]: https://github.com/advisories?query=ecosystem%3Aerlang
[php]: https://github.com/FriendsOfPHP/security-advisories
[ruby]: https://github.com/rubysec/ruby-advisory-db

View File

@@ -27,6 +27,7 @@
| Rust | Cargo.lock | ✅ | ✅ | ✅ | ✅ | included | - |
| | Binaries built with [cargo-auditable](https://github.com/rust-secure-code/cargo-auditable) | ✅ | ✅ | - | - | excluded | - |
| C/C++ | conan.lock[^13] | - | - | ✅ | ✅ | excluded | - |
| Elixir | mix.lock[^13] | - | - | ✅ | ✅ | excluded | ✅ |
The path of these files does not matter.
@@ -44,4 +45,4 @@ Example: [Dockerfile](https://github.com/aquasecurity/trivy-ci-test/blob/main/Do
[^10]: ✅ means "enabled" and `-` means "disabled" in the filesystem scanning
[^11]: ✅ means "enabled" and `-` means "disabled" in the git repository scanning
[^12]: ✅ means that Trivy detects line numbers where each dependency is declared in the scanned file. Only supported in [json](../examples/report.md#json) and [sarif](../examples/report.md#sarif) formats. SARIF uses `startline == 1 and endline == 1` for unsupported file types
[^13]: To scan a filename other than the default filename(`conan.lock`) use [file-patterns](../examples/others.md#file-patterns)
[^13]: To scan a filename other than the default filename use [file-patterns](../examples/others.md#file-patterns)

4
go.mod
View File

@@ -9,7 +9,7 @@ require (
github.com/alicebob/miniredis/v2 v2.23.0
github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986
github.com/aquasecurity/defsec v0.82.7-0.20221225070347-3a6cfb67e460
github.com/aquasecurity/go-dep-parser v0.0.0-20221208150335-299772f066c4
github.com/aquasecurity/go-dep-parser v0.0.0-20221227140654-09a64a5d9b51
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
@@ -19,7 +19,7 @@ require (
github.com/aquasecurity/table v1.8.0
github.com/aquasecurity/testdocker v0.0.0-20210911155206-e1e85f5a1516
github.com/aquasecurity/tml v0.6.1
github.com/aquasecurity/trivy-db v0.0.0-20221208102935-e829718a223f
github.com/aquasecurity/trivy-db v0.0.0-20221227141502-af78ecb7db4c
github.com/aquasecurity/trivy-kubernetes v0.3.1-0.20221021174315-8d74450b4506
github.com/aws/aws-sdk-go v1.44.136
github.com/aws/aws-sdk-go-v2 v1.17.1

8
go.sum
View File

@@ -195,8 +195,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.82.7-0.20221225070347-3a6cfb67e460 h1:XHYo9HDWlrn3l+GH1ZTVUQAeP//r/iyEVUoP4Rmhuuw=
github.com/aquasecurity/defsec v0.82.7-0.20221225070347-3a6cfb67e460/go.mod h1:sUdW6pzASralDcs+CDOE+QpWfBJt3/PY1Qbg8CS5flg=
github.com/aquasecurity/go-dep-parser v0.0.0-20221208150335-299772f066c4 h1:cFQv/JghmN6dC/vuu6JbDkziwhBgLPfQvyi/TxJN+6I=
github.com/aquasecurity/go-dep-parser v0.0.0-20221208150335-299772f066c4/go.mod h1:ZCiGJgdQxCateSw3nPMwZvp9J/+nU8/3DcGY/NO71e4=
github.com/aquasecurity/go-dep-parser v0.0.0-20221227140654-09a64a5d9b51 h1:1mbTWnP/NzDrbyYaDzS2xIxuoAuhY3N62qZCTuSqfSo=
github.com/aquasecurity/go-dep-parser v0.0.0-20221227140654-09a64a5d9b51/go.mod h1:ZCiGJgdQxCateSw3nPMwZvp9J/+nU8/3DcGY/NO71e4=
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-20220726154943-99847deb62b0 h1:tihCUjLWkF0b1SAjAKcFltUs3SpsqGrLtI+Frye0D10=
@@ -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/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-20221208102935-e829718a223f h1:M0nc6W/uVEGXSG3iHEEGujJB2vtMNx21iIeP6OM5Cb4=
github.com/aquasecurity/trivy-db v0.0.0-20221208102935-e829718a223f/go.mod h1:/nULgnDeq/JMPMVwE1dmf4kWlYn++7VrM3O2naj4BHA=
github.com/aquasecurity/trivy-db v0.0.0-20221227141502-af78ecb7db4c h1:CgJiXxVxgFOQ4btP97LEYqEHnx++FRpf2IJEXJV+xHs=
github.com/aquasecurity/trivy-db v0.0.0-20221227141502-af78ecb7db4c/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/go.mod h1:xXd1m0iRJrz3ISbOXVDaR4hCWoSrF4RbIfNTN4dTrjY=
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q=

View File

@@ -147,6 +147,15 @@ func TestFilesystem(t *testing.T) {
},
golden: "testdata/cocoapods.json.golden",
},
{
name: "mix.lock",
args: args{
securityChecks: "vuln",
listAllPkgs: true,
input: "testdata/fixtures/fs/mixlock",
},
golden: "testdata/mix.lock.json.golden",
},
{
name: "dockerfile",
args: args{

View File

@@ -30,6 +30,11 @@
ID: "ghsa"
Name: "GitHub Security Advisory RubyGems"
URL: "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Arubygems"
- key: "erlang::GitHub Security Advisory Erlang"
value:
ID: "ghsa"
Name: "GitHub Security Advisory Erlang"
URL: "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Aerlang"
- key: Oracle Linux 8
value:
ID: "oracle-oval"

View File

@@ -0,0 +1,10 @@
- bucket: erlang::GitHub Security Advisory Erlang
pairs:
- bucket: phoenix
pairs:
- key: CVE-2022-42975
value:
PatchedVersions:
- 1.6.14
VulnerableVersions:
- "<= 1.6.14"

View File

@@ -1253,6 +1253,24 @@
- https://alephsecurity.com/vulns/aleph-2018004
PublishedDate: "2022-06-22T15:08:47Z"
LastModifiedDate: "2022-06-27T18:37:23Z"
- key: CVE-2022-42975
value:
Title: "Phoenix before 1.6.14 mishandles check_origin wildcarding"
Description: "socket/transport.ex in Phoenix before 1.6.14 mishandles check_origin wildcarding. NOTE: LiveView applications are unaffected by default because of the presence of a LiveView CSRF token."
Severity: HIGH
VendorSeverity:
ghsa: 3
CVSS:
ghsa:
V3Vector: "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N"
V3Score: 7.5
References:
- https://nvd.nist.gov/vuln/detail/CVE-2022-42975
- https://github.com/phoenixframework/phoenix/commit/6e7185b33a59e0b1d1c0b4223adf340a73e963ae
- https://hexdocs.pm/phoenix/1.6.14/changelog.html#1-6-14-2022-10-10
- https://github.com/advisories/GHSA-p8f7-22gq-m7j9
PublishedDate: "2022-10-17T12:00:27Z"
LastModifiedDate: "2022-10-18T18:01:44Z"
- key: CVE-2022-22965
value:
Title: "spring-framework: RCE via Data Binding on JDK 9+"

View File

@@ -0,0 +1,12 @@
%{
"castore": {:hex, :castore, "0.1.18", "deb5b9ab02400561b6f5708f3e7660fc35ca2d51bfc6a940d2f513f89c2975fc", [:mix], [], "hexpm", "61bbaf6452b782ef80b33cdb45701afbcf0a918a45ebe7e73f1130d661e66a06"},
"jason": {:hex, :jason, "1.4.0", "e855647bc964a44e2f67df589ccf49105ae039d4179db7f6271dfd3843dc27e6", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "79a3791085b2a0f743ca04cec0f7be26443738779d09302e01318f97bdb82121"},
"phoenix": {:hex, :phoenix, "1.6.13", "0a1d96bbc10747fd83525370d691953cdb6f3ccbac61aa01b4acb012474b047d", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 1.0 or ~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "d70ab9fbf6b394755ea88b644d34d79d8b146e490973151f248cacd122d20672"},
"phoenix_html": {:hex, :phoenix_html, "3.2.0", "1c1219d4b6cb22ac72f12f73dc5fad6c7563104d083f711c3fcd8551a1f4ae11", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "36ec97ba56d25c0136ef1992c37957e4246b649d620958a1f9fa86165f8bc54f"},
"phoenix_pubsub": {:hex, :phoenix_pubsub, "2.1.1", "ba04e489ef03763bf28a17eb2eaddc2c20c6d217e2150a61e3298b0f4c2012b5", [:mix], [], "hexpm", "81367c6d1eea5878ad726be80808eb5a787a23dee699f96e72b1109c57cdd8d9"},
"phoenix_template": {:hex, :phoenix_template, "1.0.0", "c57bc5044f25f007dc86ab21895688c098a9f846a8dda6bc40e2d0ddc146e38f", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "1b066f99a26fd22064c12b2600a9a6e56700f591bf7b20b418054ea38b4d4357"},
"phoenix_view": {:hex, :phoenix_view, "2.0.1", "a653e3d9d944aace0a064e4a13ad473ffa68f7bc4ca42dbf83cc1d464f1fb295", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}], "hexpm", "6c358e2cefc5f341c728914b867c556bbfd239fed9e881bac257d70cb2b8a6f6"},
"plug": {:hex, :plug, "1.14.0", "ba4f558468f69cbd9f6b356d25443d0b796fbdc887e03fa89001384a9cac638f", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "bf020432c7d4feb7b3af16a0c2701455cbbbb95e5b6866132cb09eb0c29adc14"},
"plug_crypto": {:hex, :plug_crypto, "1.2.3", "8f77d13aeb32bfd9e654cb68f0af517b371fb34c56c9f2b58fe3df1235c1251a", [:mix], [], "hexpm", "b5672099c6ad5c202c45f5a403f21a3411247f164e4a8fab056e5cd8a290f4a2"},
"telemetry": {:hex, :telemetry, "1.1.0", "a589817034a27eab11144ad24d5c0f9fab1f58173274b1e9bae7074af9cbee51", [:rebar3], [], "hexpm", "b727b2a1f75614774cff2d7565b64d0dfa5bd52ba517f16543e6fc7efcc0df48"},
}

View File

@@ -0,0 +1,180 @@
{
"SchemaVersion": 2,
"ArtifactName": "testdata/fixtures/fs/mixlock",
"ArtifactType": "filesystem",
"Metadata": {
"ImageConfig": {
"architecture": "",
"created": "0001-01-01T00:00:00Z",
"os": "",
"rootfs": {
"type": "",
"diff_ids": null
},
"config": {}
}
},
"Results": [
{
"Target": "mix.lock",
"Class": "lang-pkgs",
"Type": "hex",
"Packages": [
{
"ID": "castore@0.1.18",
"Name": "castore",
"Version": "0.1.18",
"Layer": {},
"Locations": [
{
"StartLine": 2,
"EndLine": 2
}
]
},
{
"ID": "jason@1.4.0",
"Name": "jason",
"Version": "1.4.0",
"Layer": {},
"Locations": [
{
"StartLine": 3,
"EndLine": 3
}
]
},
{
"ID": "phoenix@1.6.13",
"Name": "phoenix",
"Version": "1.6.13",
"Layer": {},
"Locations": [
{
"StartLine": 4,
"EndLine": 4
}
]
},
{
"ID": "phoenix_html@3.2.0",
"Name": "phoenix_html",
"Version": "3.2.0",
"Layer": {},
"Locations": [
{
"StartLine": 5,
"EndLine": 5
}
]
},
{
"ID": "phoenix_pubsub@2.1.1",
"Name": "phoenix_pubsub",
"Version": "2.1.1",
"Layer": {},
"Locations": [
{
"StartLine": 6,
"EndLine": 6
}
]
},
{
"ID": "phoenix_template@1.0.0",
"Name": "phoenix_template",
"Version": "1.0.0",
"Layer": {},
"Locations": [
{
"StartLine": 7,
"EndLine": 7
}
]
},
{
"ID": "phoenix_view@2.0.1",
"Name": "phoenix_view",
"Version": "2.0.1",
"Layer": {},
"Locations": [
{
"StartLine": 8,
"EndLine": 8
}
]
},
{
"ID": "plug@1.14.0",
"Name": "plug",
"Version": "1.14.0",
"Layer": {},
"Locations": [
{
"StartLine": 9,
"EndLine": 9
}
]
},
{
"ID": "plug_crypto@1.2.3",
"Name": "plug_crypto",
"Version": "1.2.3",
"Layer": {},
"Locations": [
{
"StartLine": 10,
"EndLine": 10
}
]
},
{
"ID": "telemetry@1.1.0",
"Name": "telemetry",
"Version": "1.1.0",
"Layer": {},
"Locations": [
{
"StartLine": 11,
"EndLine": 11
}
]
}
],
"Vulnerabilities": [
{
"VulnerabilityID": "CVE-2022-42975",
"PkgName": "phoenix",
"PkgID": "phoenix@1.6.13",
"InstalledVersion": "1.6.13",
"FixedVersion": "1.6.14",
"Layer": {},
"SeveritySource": "ghsa",
"PrimaryURL": "https://avd.aquasec.com/nvd/cve-2022-42975",
"DataSource": {
"ID": "ghsa",
"Name": "GitHub Security Advisory Erlang",
"URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Aerlang"
},
"Title": "Phoenix before 1.6.14 mishandles check_origin wildcarding",
"Description": "socket/transport.ex in Phoenix before 1.6.14 mishandles check_origin wildcarding. NOTE: LiveView applications are unaffected by default because of the presence of a LiveView CSRF token.",
"Severity": "HIGH",
"CVSS": {
"ghsa": {
"V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N",
"V3Score": 7.5
}
},
"References": [
"https://nvd.nist.gov/vuln/detail/CVE-2022-42975",
"https://github.com/phoenixframework/phoenix/commit/6e7185b33a59e0b1d1c0b4223adf340a73e963ae",
"https://hexdocs.pm/phoenix/1.6.14/changelog.html#1-6-14-2022-10-10",
"https://github.com/advisories/GHSA-p8f7-22gq-m7j9"
],
"PublishedDate": "2022-10-17T12:00:27Z",
"LastModifiedDate": "2022-10-18T18:01:44Z"
}
]
}
]
}

View File

@@ -51,6 +51,9 @@ func NewDriver(libType string) (Driver, error) {
case ftypes.Pipenv, ftypes.Poetry, ftypes.Pip, ftypes.PythonPkg:
ecosystem = vulnerability.Pip
comparer = pep440.Comparer{}
case ftypes.Hex:
ecosystem = vulnerability.Erlang
comparer = compare.GenericComparer{}
case ftypes.Conan:
ecosystem = vulnerability.Conan
// Only semver can be used for version ranges

View File

@@ -8,6 +8,7 @@ import (
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/c/conan"
_ "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/elixir/mix"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/golang/binary"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/golang/mod"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/java/gradle"

View File

@@ -74,6 +74,9 @@ const (
// C/C++
TypeConanLock Type = "conan-lock"
// Elixir
TypeMixLock Type = "mix-lock"
// Swift
TypeCocoaPods Type = "cocoapods"
@@ -128,14 +131,14 @@ var (
TypeBundler, TypeGemSpec, TypeCargo, TypeComposer, TypeJar, TypePom, TypeGradleLock,
TypeNpmPkgLock, TypeNodePkg, TypeYarn, TypePnpm, TypeNuget, TypeDotNetCore,
TypePythonPkg, TypePip, TypePipenv, TypePoetry, TypeGoBinary, TypeGoMod, TypeRustBinary, TypeConanLock,
TypeCocoaPods,
TypeCocoaPods, TypeMixLock,
}
// TypeLockfiles has all lock file analyzers
TypeLockfiles = []Type{
TypeBundler, TypeNpmPkgLock, TypeYarn,
TypePnpm, TypePip, TypePipenv, TypePoetry, TypeGoMod, TypePom, TypeConanLock, TypeGradleLock,
TypeCocoaPods,
TypeCocoaPods, TypeMixLock,
}
// TypeIndividualPkgs has all analyzers for individual packages

View File

@@ -0,0 +1,49 @@
package mix
import (
"context"
"os"
"path/filepath"
"golang.org/x/xerrors"
"github.com/aquasecurity/go-dep-parser/pkg/hex/mix"
"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(&mixLockAnalyzer{})
}
const (
version = 1
)
// mixLockAnalyzer analyzes 'mix.lock'
type mixLockAnalyzer struct{}
func (a mixLockAnalyzer) Analyze(_ context.Context, input analyzer.AnalysisInput) (*analyzer.AnalysisResult, error) {
p := mix.NewParser()
res, err := language.Analyze(types.Hex, input.FilePath, input.Content, p)
if err != nil {
return nil, xerrors.Errorf("%s parse error: %w", input.FilePath, err)
}
return res, nil
}
func (a mixLockAnalyzer) Required(filePath string, _ os.FileInfo) bool {
// Lock file name can be anything.
// cf. https://hexdocs.pm/mix/Mix.Project.html#module-configuration
// By default, we only check the default file name - `mix.lock`.
return filepath.Base(filePath) == types.MixLock
}
func (a mixLockAnalyzer) Type() analyzer.Type {
return analyzer.TypeMixLock
}
func (a mixLockAnalyzer) Version() int {
return version
}

View File

@@ -0,0 +1,89 @@
package mix
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_mixLockAnalyzer_Analyze(t *testing.T) {
tests := []struct {
name string
inputFile string
want *analyzer.AnalysisResult
}{
{
name: "happy path",
inputFile: "testdata/happy.mix.lock",
want: &analyzer.AnalysisResult{
Applications: []types.Application{
{
Type: types.Hex,
FilePath: "testdata/happy.mix.lock",
Libraries: []types.Package{
{
ID: "bunt@0.2.0",
Name: "bunt",
Version: "0.2.0",
Locations: []types.Location{{StartLine: 2, EndLine: 2}},
},
},
},
},
},
},
{
name: "empty file",
inputFile: "testdata/empty.mix.lock",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
f, err := os.Open(tt.inputFile)
require.NoError(t, err)
defer func() {
err = f.Close()
assert.NoError(t, err)
}()
a := mixLockAnalyzer{}
got, err := a.Analyze(nil, analyzer.AnalysisInput{
FilePath: tt.inputFile,
Content: f,
})
assert.NoError(t, err)
assert.Equal(t, tt.want, got)
})
}
}
func Test_mixLockAnalyzer_Required(t *testing.T) {
tests := []struct {
name string
filePath string
want bool
}{
{
name: "happy path",
filePath: "mix.lock",
want: true,
},
{
name: "sad path",
filePath: "test.txt",
want: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
a := mixLockAnalyzer{}
got := a.Required(tt.filePath, nil)
assert.Equal(t, tt.want, got)
})
}
}

View File

@@ -0,0 +1,2 @@
%{
}

View File

@@ -0,0 +1,3 @@
%{
"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm", "7af5c7e09fe1d40f76c8e4f9dd2be7cebd83909f31fee7cd0e9eadc567da8353"},
}

View File

@@ -30,6 +30,7 @@ const (
RustBinary = "rustbinary"
Conan = "conan"
Cocoapods = "cocoapods"
Hex = "hex"
// Config files
YAML = "yaml"
@@ -73,4 +74,6 @@ const (
ConanLock = "conan.lock"
CocoaPodsLock = "Podfile.lock"
MixLock = "mix.lock"
)

View File

@@ -96,6 +96,8 @@ func (p *PackageURL) PackageType() string {
return ftypes.NuGet
case packageurl.TypeSwift:
return ftypes.Cocoapods
case packageurl.TypeHex:
return ftypes.Hex
}
return p.Type
}
@@ -308,6 +310,8 @@ func purlType(t string) string {
return packageurl.TypeNPM
case ftypes.Cocoapods:
return packageurl.TypeSwift
case ftypes.Hex:
return packageurl.TypeHex
case os.Alpine:
return TypeAPK
case os.Debian, os.Ubuntu:

View File

@@ -166,6 +166,23 @@ func TestNewPackageURL(t *testing.T) {
},
},
},
{
name: "hex package",
typ: ftypes.Hex,
pkg: ftypes.Package{
ID: "bunt@0.2.0",
Name: "bunt",
Version: "0.2.0",
Locations: []ftypes.Location{{StartLine: 2, EndLine: 2}},
},
want: purl.PackageURL{
PackageURL: packageurl.PackageURL{
Type: packageurl.TypeHex,
Name: "bunt",
Version: "0.2.0",
},
},
},
{
name: "os package",
typ: os.RedHat,
@@ -364,6 +381,18 @@ func TestFromString(t *testing.T) {
},
},
},
{
name: "happy path for hex",
purl: "pkg:hex/plug@1.14.0",
want: purl.PackageURL{
PackageURL: packageurl.PackageURL{
Type: packageurl.TypeHex,
Name: "plug",
Version: "1.14.0",
Qualifiers: packageurl.Qualifiers{},
},
},
},
{
name: "happy path for apk",
purl: "pkg:apk/alpine/alpine-baselayout@3.2.0-r16?distro=3.14.2",