diff --git a/.github/workflows/semantic-pr.yaml b/.github/workflows/semantic-pr.yaml index 8286e70cf1..7f57db1922 100644 --- a/.github/workflows/semantic-pr.yaml +++ b/.github/workflows/semantic-pr.yaml @@ -63,6 +63,7 @@ jobs: amazon suse photon + echo distroless windows @@ -121,7 +122,7 @@ jobs: # Convert env vars to regex alternatives, excluding comments and empty lines TYPES_REGEX=$(echo "$VALID_TYPES" | grep -v '^$' | paste -sd '|') SCOPES_REGEX=$(echo "$VALID_SCOPES" | grep -v '^$' | grep -v '^#' | paste -sd '|') - + # Basic format check (should match: type(scope): description or type: description) FORMAT_REGEX="^[a-z]+(\([a-z0-9+]+\))?!?: .+$" if ! echo "$PR_TITLE" | grep -qE "$FORMAT_REGEX"; then @@ -158,6 +159,6 @@ jobs: exit 1 fi fi - + echo "PR title validation passed ✅" echo "Current title: $PR_TITLE" diff --git a/docs/docs/coverage/os/echo.md b/docs/docs/coverage/os/echo.md new file mode 100644 index 0000000000..e46c480a99 --- /dev/null +++ b/docs/docs/coverage/os/echo.md @@ -0,0 +1,30 @@ +# Echo +Trivy supports these scanners for OS packages. + +| Scanner | Supported | +| :-----------: | :-------: | +| SBOM | ✓ | +| Vulnerability | ✓ | +| License | ✓ | + +The table below outlines the features offered by Trivy. + +| Feature | Supported | +|:------------------------------------:|:---------:| +| Unfixed vulnerabilities | ✓ | +| [Dependency graph][dependency-graph] | ✓ | + +## SBOM +Same as [Debian](debian.md#sbom). + +## Vulnerability +Echo offers its own security advisories, and these are utilized when scanning Echo for vulnerabilities. + +### Data Source +See [here](../../scanner/vulnerability.md#data-sources). + +## License +Same as [Debian](debian.md#license). + +[dependency-graph]: ../../configuration/reporting.md#show-origins-of-vulnerable-dependencies +[advisory]: https://advisory.echohq.com/data.json \ No newline at end of file diff --git a/docs/docs/coverage/os/index.md b/docs/docs/coverage/os/index.md index e82e680451..00e1967b7e 100644 --- a/docs/docs/coverage/os/index.md +++ b/docs/docs/coverage/os/index.md @@ -26,6 +26,7 @@ Trivy supports operating systems for | [SUSE Linux Enterprise](suse.md) | 11, 12, 15 | zypper/rpm | | [SUSE Linux Enterprise Micro](suse.md)| 5, 6 | zypper/rpm | | [Photon OS](photon.md) | 1.0, 2.0, 3.0, 4.0 | tndf/yum/rpm | +| [Echo](echo.md) | (n/a) | apt/dpkg | | [Debian GNU/Linux](debian.md) | 7, 8, 9, 10, 11, 12 | apt/dpkg | | [Ubuntu](ubuntu.md) | All versions supported by Canonical | apt/dpkg | | [Bottlerocket](bottlerocket.md) | 1.7.0 and upper | bottlerocket | diff --git a/docs/docs/references/configuration/cli/trivy_filesystem.md b/docs/docs/references/configuration/cli/trivy_filesystem.md index 908c6e0266..e736ad0f66 100644 --- a/docs/docs/references/configuration/cli/trivy_filesystem.md +++ b/docs/docs/references/configuration/cli/trivy_filesystem.md @@ -167,6 +167,7 @@ trivy filesystem [flags] PATH - chainguard - bitnami - govulndb + - echo - auto (default [auto]) ``` diff --git a/docs/docs/references/configuration/cli/trivy_image.md b/docs/docs/references/configuration/cli/trivy_image.md index 459775d1bf..35d20584c2 100644 --- a/docs/docs/references/configuration/cli/trivy_image.md +++ b/docs/docs/references/configuration/cli/trivy_image.md @@ -188,6 +188,7 @@ trivy image [flags] IMAGE_NAME - chainguard - bitnami - govulndb + - echo - auto (default [auto]) ``` diff --git a/docs/docs/references/configuration/cli/trivy_kubernetes.md b/docs/docs/references/configuration/cli/trivy_kubernetes.md index 5d8189e982..e00e4e745b 100644 --- a/docs/docs/references/configuration/cli/trivy_kubernetes.md +++ b/docs/docs/references/configuration/cli/trivy_kubernetes.md @@ -176,6 +176,7 @@ trivy kubernetes [flags] [CONTEXT] - chainguard - bitnami - govulndb + - echo - auto (default [auto]) ``` diff --git a/docs/docs/references/configuration/cli/trivy_repository.md b/docs/docs/references/configuration/cli/trivy_repository.md index 2f01be9a9a..ba05f75ff0 100644 --- a/docs/docs/references/configuration/cli/trivy_repository.md +++ b/docs/docs/references/configuration/cli/trivy_repository.md @@ -166,6 +166,7 @@ trivy repository [flags] (REPO_PATH | REPO_URL) - chainguard - bitnami - govulndb + - echo - auto (default [auto]) ``` diff --git a/docs/docs/references/configuration/cli/trivy_rootfs.md b/docs/docs/references/configuration/cli/trivy_rootfs.md index c601608a2c..f8917cbb5f 100644 --- a/docs/docs/references/configuration/cli/trivy_rootfs.md +++ b/docs/docs/references/configuration/cli/trivy_rootfs.md @@ -168,6 +168,7 @@ trivy rootfs [flags] ROOTDIR - chainguard - bitnami - govulndb + - echo - auto (default [auto]) ``` diff --git a/docs/docs/references/configuration/cli/trivy_sbom.md b/docs/docs/references/configuration/cli/trivy_sbom.md index 59f0d8d840..911bb2e90b 100644 --- a/docs/docs/references/configuration/cli/trivy_sbom.md +++ b/docs/docs/references/configuration/cli/trivy_sbom.md @@ -137,6 +137,7 @@ trivy sbom [flags] SBOM_PATH - chainguard - bitnami - govulndb + - echo - auto (default [auto]) ``` diff --git a/docs/docs/references/configuration/cli/trivy_vm.md b/docs/docs/references/configuration/cli/trivy_vm.md index 298e20cdac..9d6c2676ca 100644 --- a/docs/docs/references/configuration/cli/trivy_vm.md +++ b/docs/docs/references/configuration/cli/trivy_vm.md @@ -153,6 +153,7 @@ trivy vm [flags] VM_IMAGE - chainguard - bitnami - govulndb + - echo - auto (default [auto]) ``` diff --git a/docs/docs/scanner/vulnerability.md b/docs/docs/scanner/vulnerability.md index c8d6c54609..a7f0db4ff8 100644 --- a/docs/docs/scanner/vulnerability.md +++ b/docs/docs/scanner/vulnerability.md @@ -26,6 +26,7 @@ See [here](../coverage/os/index.md#supported-os) for the supported OSes. | Wolfi Linux | [secdb][wolfi] | | Chainguard | [secdb][chainguard] | | Amazon Linux | [Amazon Linux Security Center][amazon] | +| Echo | [Echo][echo] | | Debian | [Security Bug Tracker][debian-tracker] / [OVAL][debian-oval] | | Ubuntu | [Ubuntu CVE Tracker][ubuntu] | | RHEL/CentOS | [OVAL][rhel-oval] / [Security Data][rhel-api] | @@ -379,6 +380,7 @@ Example logic for the following vendor severity levels when scanning an Alpine i [wolfi]: https://packages.wolfi.dev/os/security.json [chainguard]: https://packages.cgr.dev/chainguard/security.json [amazon]: https://alas.aws.amazon.com/ +[echo]: https://advisory.echohq.com/data.json [debian-tracker]: https://security-tracker.debian.org/tracker/ [debian-oval]: https://www.debian.org/security/oval/ [ubuntu]: https://ubuntu.com/security/cve diff --git a/go.mod b/go.mod index 0b9b13319f..2bd14e4d5b 100644 --- a/go.mod +++ b/go.mod @@ -24,7 +24,7 @@ require ( github.com/aquasecurity/testdocker v0.0.0-20240730042311-4642e94c7fc8 github.com/aquasecurity/tml v0.6.1 github.com/aquasecurity/trivy-checks v1.10.0 - github.com/aquasecurity/trivy-db v0.0.0-20250227071930-8bd8a9b89e2d + github.com/aquasecurity/trivy-db v0.0.0-20250529090941-0ee57d439c7a github.com/aquasecurity/trivy-java-db v0.0.0-20240109071736-184bd7481d48 github.com/aquasecurity/trivy-kubernetes v0.9.0 github.com/aws/aws-sdk-go-v2 v1.36.3 @@ -352,7 +352,7 @@ require ( github.com/rubenv/sql-migrate v1.7.1 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sagikazarmark/locafero v0.7.0 // indirect - github.com/samber/oops v1.15.0 // indirect + github.com/samber/oops v1.16.1 // indirect github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect github.com/sassoftware/relic v7.2.1+incompatible // indirect github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect diff --git a/go.sum b/go.sum index c3aa044d11..38250d10f4 100644 --- a/go.sum +++ b/go.sum @@ -802,8 +802,8 @@ github.com/aquasecurity/tml v0.6.1 h1:y2ZlGSfrhnn7t4ZJ/0rotuH+v5Jgv6BDDO5jB6A9gw github.com/aquasecurity/tml v0.6.1/go.mod h1:OnYMWY5lvI9ejU7yH9LCberWaaTBW7hBFsITiIMY2yY= github.com/aquasecurity/trivy-checks v1.10.0 h1:Q0FWsYy/uwvr/icRSOzNu55yDZ1ME8hZlpglNs62ZfE= github.com/aquasecurity/trivy-checks v1.10.0/go.mod h1:/b633SOFNp8RjkxSq+FOg4SgxjklUp+BIQEyTWCnN1k= -github.com/aquasecurity/trivy-db v0.0.0-20250227071930-8bd8a9b89e2d h1:T16WrTi21YsMLQVhtp1r1hOIYK3x4BjnftpL9cp64Eo= -github.com/aquasecurity/trivy-db v0.0.0-20250227071930-8bd8a9b89e2d/go.mod h1:4bTsQPtMBN8v+UfUlE1aQBN1imftefnDafHBF85+aT8= +github.com/aquasecurity/trivy-db v0.0.0-20250529090941-0ee57d439c7a h1:VGmQ5tx5vVo4zBk8F8b/rf9s57C9bOEfWmIzF2kLFE8= +github.com/aquasecurity/trivy-db v0.0.0-20250529090941-0ee57d439c7a/go.mod h1:4zd4qZcjhNAHASz5I0O7qapv5h5gSJzSEaZXv/IPOGc= github.com/aquasecurity/trivy-java-db v0.0.0-20240109071736-184bd7481d48 h1:JVgBIuIYbwG+ekC5lUHUpGJboPYiCcxiz06RCtz8neI= github.com/aquasecurity/trivy-java-db v0.0.0-20240109071736-184bd7481d48/go.mod h1:Ldya37FLi0e/5Cjq2T5Bty7cFkzUDwTcPeQua+2M8i8= github.com/aquasecurity/trivy-kubernetes v0.9.0 h1:rp8RuXwKfFWUPR/ULksA2WpD0z6rslVkzLmPGQr61Wc= @@ -1777,8 +1777,8 @@ github.com/sagikazarmark/locafero v0.7.0 h1:5MqpDsTGNDhY8sGp0Aowyf0qKsPrhewaLSsF github.com/sagikazarmark/locafero v0.7.0/go.mod h1:2za3Cg5rMaTMoG/2Ulr9AwtFaIppKXTRYnozin4aB5k= github.com/samber/lo v1.50.0 h1:XrG0xOeHs+4FQ8gJR97zDz5uOFMW7OwFWiFVzqopKgY= github.com/samber/lo v1.50.0/go.mod h1:RjZyNk6WSnUFRKK6EyOhsRJMqft3G+pg7dCWHQCWvsc= -github.com/samber/oops v1.15.0 h1:/mF33KAqA2TugU6y/tomFpK6G6mJB7g0aqRyHkaSIeg= -github.com/samber/oops v1.15.0/go.mod h1:9LpLZkpjojEt/of7EpG5o65i/Lp23ddDvGhg2L871Ow= +github.com/samber/oops v1.16.1 h1:XlKkXsWM5g8hE4C+sEV9n0X282fZn3XabVmAKU2RiHI= +github.com/samber/oops v1.16.1/go.mod h1:8eXgMAJcDXRAijQsFRhfy/EHDOTiSvwkg6khFqFK078= github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4= github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY= github.com/sassoftware/go-rpmutils v0.4.0 h1:ojND82NYBxgwrV+mX1CWsd5QJvvEZTKddtCdFLPWhpg= diff --git a/mkdocs.yml b/mkdocs.yml index ea770c50e9..9d77eb502d 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -80,6 +80,7 @@ nav: - CentOS: docs/coverage/os/centos.md - Chainguard: docs/coverage/os/chainguard.md - Debian: docs/coverage/os/debian.md + - Echo: docs/coverage/os/echo.md - Oracle Linux: docs/coverage/os/oracle.md - Photon OS: docs/coverage/os/photon.md - Red Hat: docs/coverage/os/rhel.md diff --git a/pkg/detector/ospkg/detect.go b/pkg/detector/ospkg/detect.go index f83088f29a..21af822f8b 100644 --- a/pkg/detector/ospkg/detect.go +++ b/pkg/detector/ospkg/detect.go @@ -14,6 +14,7 @@ import ( "github.com/aquasecurity/trivy/pkg/detector/ospkg/bottlerocket" "github.com/aquasecurity/trivy/pkg/detector/ospkg/chainguard" "github.com/aquasecurity/trivy/pkg/detector/ospkg/debian" + "github.com/aquasecurity/trivy/pkg/detector/ospkg/echo" "github.com/aquasecurity/trivy/pkg/detector/ospkg/oracle" "github.com/aquasecurity/trivy/pkg/detector/ospkg/photon" "github.com/aquasecurity/trivy/pkg/detector/ospkg/redhat" @@ -50,6 +51,7 @@ var ( ftypes.Photon: photon.NewScanner(), ftypes.Wolfi: wolfi.NewScanner(), ftypes.Chainguard: chainguard.NewScanner(), + ftypes.Echo: echo.NewScanner(), } ) diff --git a/pkg/detector/ospkg/echo/echo.go b/pkg/detector/ospkg/echo/echo.go new file mode 100644 index 0000000000..2c53ed3ac4 --- /dev/null +++ b/pkg/detector/ospkg/echo/echo.go @@ -0,0 +1,80 @@ +package echo + +import ( + "context" + + version "github.com/knqyf263/go-deb-version" + "golang.org/x/xerrors" + + dbTypes "github.com/aquasecurity/trivy-db/pkg/types" + echoDb "github.com/aquasecurity/trivy-db/pkg/vulnsrc/echo" + "github.com/aquasecurity/trivy-db/pkg/vulnsrc/vulnerability" + ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" + "github.com/aquasecurity/trivy/pkg/log" + "github.com/aquasecurity/trivy/pkg/scan/utils" + "github.com/aquasecurity/trivy/pkg/types" +) + +type Scanner struct { + vs echoDb.VulnSrc +} + +func NewScanner() *Scanner { + return &Scanner{ + vs: echoDb.NewVulnSrc(), + } +} + +func (s *Scanner) Detect(ctx context.Context, _ string, _ *ftypes.Repository, pkgs []ftypes.Package) ([]types.DetectedVulnerability, error) { + log.InfoContext(ctx, "Detecting vulnerabilities...", log.Int("pkg_num", len(pkgs))) + var detectedVulns []types.DetectedVulnerability + for _, pkg := range pkgs { + advisories, err := s.vs.Get("", pkg.SrcName) + if err != nil { + return nil, xerrors.Errorf("failed to get echo advisories: %w", err) + } + formattedInstalledVersion := utils.FormatVersion(pkg) + installedVersion, err := version.NewVersion(formattedInstalledVersion) + if err != nil { + return nil, xerrors.Errorf("failed to parse installed version: %w", err) + } + for _, advisory := range advisories { + vuln := types.DetectedVulnerability{ + PkgID: pkg.ID, + VulnerabilityID: advisory.VulnerabilityID, + InstalledVersion: formattedInstalledVersion, + FixedVersion: advisory.FixedVersion, + PkgName: pkg.Name, + PkgIdentifier: pkg.Identifier, + Status: advisory.Status, + Layer: pkg.Layer, + Custom: advisory.Custom, + DataSource: advisory.DataSource, + } + + if advisory.Severity != dbTypes.SeverityUnknown { + vuln.SeveritySource = vulnerability.Echo + vuln.Vulnerability = dbTypes.Vulnerability{ + Severity: advisory.Severity.String(), + } + } + + if advisory.FixedVersion != "" { + fixedVersion, err := version.NewVersion(advisory.FixedVersion) + if err != nil { + return nil, xerrors.Errorf("failed to parse fixed version: %w", err) + } + if !installedVersion.LessThan(fixedVersion) { + continue + } + } + detectedVulns = append(detectedVulns, vuln) + } + } + return detectedVulns, nil +} + +// Echo is a rolling distro, meaning there are no versions, and therefor no need to check the version +func (s *Scanner) IsSupportedVersion(_ context.Context, _ ftypes.OSType, _ string) bool { + return true +} diff --git a/pkg/detector/ospkg/echo/echo_test.go b/pkg/detector/ospkg/echo/echo_test.go new file mode 100644 index 0000000000..22c50a3240 --- /dev/null +++ b/pkg/detector/ospkg/echo/echo_test.go @@ -0,0 +1,267 @@ +package echo + +import ( + "sort" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/aquasecurity/trivy-db/pkg/db" + dbTypes "github.com/aquasecurity/trivy-db/pkg/types" + "github.com/aquasecurity/trivy-db/pkg/vulnsrc/vulnerability" + "github.com/aquasecurity/trivy/internal/dbtest" + ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" + "github.com/aquasecurity/trivy/pkg/types" +) + +func TestScanner_Detect(t *testing.T) { + type args struct { + pkgs []ftypes.Package + } + tests := []struct { + name string + args args + want []types.DetectedVulnerability + wantErr string + fixtures []string + }{ + { + name: "happy path - detect vulnerabilities", + fixtures: []string{ + "testdata/fixtures/echo.yaml", + "testdata/fixtures/data-source.yaml", + }, + args: args{ + pkgs: []ftypes.Package{ + { + ID: "echo", + Name: "echo", + Version: "1.0.0", + SrcName: "echo", + SrcVersion: "1.0.0", + Layer: ftypes.Layer{ + DiffID: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", + }, + }, + { + ID: "python3", + Name: "python3", + Version: "3.6.8", + SrcName: "python3", + SrcVersion: "3.6.8", + Layer: ftypes.Layer{ + DiffID: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", + }, + }, + { + ID: "apache2", + Name: "htpasswd", + SrcName: "apache2", + Version: "2.4.24", + SrcVersion: "2.4.24", + Layer: ftypes.Layer{ + DiffID: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", + }, + }, + }, + }, + want: []types.DetectedVulnerability{ + { + VulnerabilityID: "CVE-2020-11985", + PkgID: "apache2", + InstalledVersion: "2.4.24", + FixedVersion: "2.4.25-1", + PkgName: "htpasswd", + Layer: ftypes.Layer{ + DiffID: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", + }, + Vulnerability: dbTypes.Vulnerability{ + Severity: "LOW", + }, + SeveritySource: vulnerability.Echo, + DataSource: &dbTypes.DataSource{ + ID: "echo", + Name: "Echo", + URL: "https://advisory.echohq.com/data.json", + }, + }, + { + VulnerabilityID: "CVE-2020-26116", + PkgID: "python3", + InstalledVersion: "3.6.8", + FixedVersion: "3.6.9", + Layer: ftypes.Layer{ + DiffID: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", + }, + Vulnerability: dbTypes.Vulnerability{ + Severity: "MEDIUM", + }, + PkgName: "python3", + SeveritySource: vulnerability.Echo, + DataSource: &dbTypes.DataSource{ + ID: "echo", + Name: "Echo", + URL: "https://advisory.echohq.com/data.json", + }, + }, + { + VulnerabilityID: "CVE-2021-11111", + PkgID: "apache2", + InstalledVersion: "2.4.24", + FixedVersion: "2.4.25-1", + PkgName: "htpasswd", + Layer: ftypes.Layer{ + DiffID: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", + }, + DataSource: &dbTypes.DataSource{ + ID: "echo", + Name: "Echo", + URL: "https://advisory.echohq.com/data.json", + }, + }, + { + VulnerabilityID: "CVE-2021-11113", + PkgID: "apache2", + InstalledVersion: "2.4.24", + FixedVersion: "", + PkgName: "htpasswd", + Layer: ftypes.Layer{ + DiffID: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", + }, + DataSource: &dbTypes.DataSource{ + ID: "echo", + Name: "Echo", + URL: "https://advisory.echohq.com/data.json", + }, + }, + }, + }, + { + name: "happy path - package with release", + fixtures: []string{ + "testdata/fixtures/echo.yaml", + "testdata/fixtures/data-source.yaml", + }, + args: args{ + pkgs: []ftypes.Package{ + { + ID: "nginx", + Name: "nginx", + Version: "1.14.2", + SrcName: "nginx", + SrcVersion: "1.14.2", + Release: "1ubuntu1", + Layer: ftypes.Layer{ + DiffID: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", + }, + }, + { + ID: "apache2", + Name: "apache2", + SrcName: "apache2", + Version: "2.4.24", + SrcVersion: "2.4.24", + Release: "2", + Layer: ftypes.Layer{ + DiffID: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", + }, + }, + }, + }, + want: []types.DetectedVulnerability{ + { + VulnerabilityID: "CVE-2020-11985", + PkgID: "apache2", + InstalledVersion: "2.4.24-2", + FixedVersion: "2.4.25-1", + PkgName: "apache2", + Layer: ftypes.Layer{ + DiffID: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", + }, + Vulnerability: dbTypes.Vulnerability{ + Severity: "LOW", + }, + SeveritySource: vulnerability.Echo, + DataSource: &dbTypes.DataSource{ + ID: "echo", + Name: "Echo", + URL: "https://advisory.echohq.com/data.json", + }, + }, + { + VulnerabilityID: "CVE-2021-11111", + PkgID: "apache2", + InstalledVersion: "2.4.24-2", + FixedVersion: "2.4.25-1", + PkgName: "apache2", + Layer: ftypes.Layer{ + DiffID: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", + }, + DataSource: &dbTypes.DataSource{ + ID: "echo", + Name: "Echo", + URL: "https://advisory.echohq.com/data.json", + }, + }, + + { + VulnerabilityID: "CVE-2021-11113", + PkgID: "apache2", + InstalledVersion: "2.4.24-2", + FixedVersion: "", + PkgName: "apache2", + Layer: ftypes.Layer{ + DiffID: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", + }, + DataSource: &dbTypes.DataSource{ + ID: "echo", + Name: "Echo", + URL: "https://advisory.echohq.com/data.json", + }, + }, + }, + }, + { + name: "happy path - no matching packages", + args: args{ + pkgs: []ftypes.Package{ + {ID: "echo", Version: "1.0.0"}, + }, + }, + want: nil, + }, + { + name: "sad path - invalid", + fixtures: []string{ + "testdata/fixtures/echo.yaml", + "testdata/fixtures/invalid.yaml", + }, + args: args{ + pkgs: []ftypes.Package{ + {SrcName: "apache2", Version: "1.0.0"}, + }, + }, + wantErr: "failed to get echo advisories", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _ = dbtest.InitDB(t, tt.fixtures) + defer db.Close() + + s := NewScanner() + got, err := s.Detect(t.Context(), "", nil, tt.args.pkgs) + if tt.wantErr != "" { + require.ErrorContains(t, err, tt.wantErr) + return + } + + sort.Slice(got, func(i, j int) bool { + return got[i].VulnerabilityID < got[j].VulnerabilityID + }) + require.NoError(t, err) + assert.Equal(t, tt.want, got) + }) + } +} diff --git a/pkg/detector/ospkg/echo/testdata/fixtures/data-source.yaml b/pkg/detector/ospkg/echo/testdata/fixtures/data-source.yaml new file mode 100644 index 0000000000..e278999148 --- /dev/null +++ b/pkg/detector/ospkg/echo/testdata/fixtures/data-source.yaml @@ -0,0 +1,7 @@ +- bucket: data-source + pairs: + - key: echo + value: + ID: "echo" + Name: "Echo" + URL: "https://advisory.echohq.com/data.json" diff --git a/pkg/detector/ospkg/echo/testdata/fixtures/echo.yaml b/pkg/detector/ospkg/echo/testdata/fixtures/echo.yaml new file mode 100644 index 0000000000..f4d5c9adc2 --- /dev/null +++ b/pkg/detector/ospkg/echo/testdata/fixtures/echo.yaml @@ -0,0 +1,22 @@ +- bucket: echo + pairs: + - bucket: python3 + pairs: + - key: CVE-2020-26116 + value: + FixedVersion: "3.6.9" + Severity: 2 + - bucket: apache2 + pairs: + - key: CVE-2020-11985 + value: + FixedVersion: "2.4.25-1" + Severity: 1 + - key: CVE-2021-11111 + value: + FixedVersion: "2.4.25-1" + - key: CVE-2021-11112 + value: + FixedVersion: "0" + - key: CVE-2021-11113 + value: diff --git a/pkg/detector/ospkg/echo/testdata/fixtures/invalid.yaml b/pkg/detector/ospkg/echo/testdata/fixtures/invalid.yaml new file mode 100644 index 0000000000..59ec8ad98a --- /dev/null +++ b/pkg/detector/ospkg/echo/testdata/fixtures/invalid.yaml @@ -0,0 +1,9 @@ +- bucket: echo + pairs: + - bucket: apache2 + pairs: + - key: CVE-2020-8177 + value: + FixedVersion: + - foo + - bar diff --git a/pkg/fanal/analyzer/os/release/release.go b/pkg/fanal/analyzer/os/release/release.go index 9e40758ff9..82deecfb84 100644 --- a/pkg/fanal/analyzer/os/release/release.go +++ b/pkg/fanal/analyzer/os/release/release.go @@ -74,6 +74,8 @@ func (a osReleaseAnalyzer) Analyze(_ context.Context, input analyzer.AnalysisInp family = types.Azure case "mariner": family = types.CBLMariner + case "echo": + family = types.Echo } if family != "" && versionID != "" { diff --git a/pkg/fanal/analyzer/os/release/release_test.go b/pkg/fanal/analyzer/os/release/release_test.go index 6ca42e3f7e..bf9fc12dfd 100644 --- a/pkg/fanal/analyzer/os/release/release_test.go +++ b/pkg/fanal/analyzer/os/release/release_test.go @@ -149,6 +149,16 @@ func Test_osReleaseAnalyzer_Analyze(t *testing.T) { }, }, }, + { + name: "Echo", + inputFile: "testdata/echo", + want: &analyzer.AnalysisResult{ + OS: types.OS{ + Family: types.Echo, + Name: "1", + }, + }, + }, { name: "Bottlerocket", inputFile: "testdata/bottlerocket", diff --git a/pkg/fanal/analyzer/os/release/testdata/echo b/pkg/fanal/analyzer/os/release/testdata/echo new file mode 100644 index 0000000000..9062610126 --- /dev/null +++ b/pkg/fanal/analyzer/os/release/testdata/echo @@ -0,0 +1,2 @@ +ID=echo +VERSION_ID=1 \ No newline at end of file diff --git a/pkg/fanal/types/const.go b/pkg/fanal/types/const.go index f7d5c53474..3151f1c5e1 100644 --- a/pkg/fanal/types/const.go +++ b/pkg/fanal/types/const.go @@ -30,6 +30,7 @@ const ( CentOS OSType = "centos" Chainguard OSType = "chainguard" Debian OSType = "debian" + Echo OSType = "echo" Fedora OSType = "fedora" OpenSUSE OSType = "opensuse" OpenSUSELeap OSType = "opensuse-leap" @@ -113,6 +114,7 @@ var ( CentOS, Chainguard, Debian, + Echo, Fedora, OpenSUSE, OpenSUSELeap, diff --git a/pkg/purl/purl.go b/pkg/purl/purl.go index 8dd8dc0a93..b691650508 100644 --- a/pkg/purl/purl.go +++ b/pkg/purl/purl.go @@ -482,7 +482,7 @@ func purlType(t ftypes.TargetType) string { return packageurl.TypeCargo case ftypes.Alpine, ftypes.Chainguard, ftypes.Wolfi: return packageurl.TypeApk - case ftypes.Debian, ftypes.Ubuntu: + case ftypes.Debian, ftypes.Ubuntu, ftypes.Echo: return packageurl.TypeDebian case ftypes.RedHat, ftypes.CentOS, ftypes.Rocky, ftypes.Alma, ftypes.Amazon, ftypes.Fedora, ftypes.Oracle, ftypes.OpenSUSE,