feat(vex): VEX Repository support (#7206)

Signed-off-by: knqyf263 <knqyf263@gmail.com>
Co-authored-by: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com>
This commit is contained in:
Teppei Fukuda
2024-07-25 16:18:37 +04:00
committed by GitHub
parent 174b1e3515
commit 88ba46047c
77 changed files with 3505 additions and 651 deletions

View File

@@ -28,11 +28,13 @@ import (
"github.com/aquasecurity/trivy-db/pkg/metadata"
"github.com/aquasecurity/trivy/internal/dbtest"
"github.com/aquasecurity/trivy/internal/testutil"
"github.com/aquasecurity/trivy/pkg/clock"
"github.com/aquasecurity/trivy/pkg/commands"
"github.com/aquasecurity/trivy/pkg/db"
"github.com/aquasecurity/trivy/pkg/types"
"github.com/aquasecurity/trivy/pkg/uuid"
"github.com/aquasecurity/trivy/pkg/vex/repo"
_ "modernc.org/sqlite"
)
@@ -68,6 +70,43 @@ func initDB(t *testing.T) string {
return cacheDir
}
func initVEXRepository(t *testing.T, homeDir, cacheDir string) {
t.Helper()
// Copy config directory
configSrc := "testdata/fixtures/vex/config/repository.yaml"
configDst := filepath.Join(homeDir, ".trivy", "vex", "repository.yaml")
testutil.CopyFile(t, configSrc, configDst)
// Copy repository directory
repoSrc := "testdata/fixtures/vex/repositories"
repoDst := filepath.Join(cacheDir, "vex", "repositories")
testutil.CopyDir(t, repoSrc, repoDst)
// Copy VEX file
vexSrc := "testdata/fixtures/vex/file/openvex.json"
repoDir := filepath.Join(repoDst, "default")
vexDst := filepath.Join(repoDir, "0.1", "openvex.json")
testutil.CopyFile(t, vexSrc, vexDst)
// Write a dummy cache metadata
testutil.MustWriteJSON(t, filepath.Join(repoDir, "cache.json"), repo.CacheMetadata{
UpdatedAt: time.Now(),
})
// Verify that necessary files exist
requiredFiles := []string{
configDst,
filepath.Join(repoDir, "vex-repository.json"),
filepath.Join(repoDir, "0.1", "index.json"),
filepath.Join(repoDir, "0.1", "openvex.json"),
}
for _, file := range requiredFiles {
require.FileExists(t, file)
}
}
func getFreePort() (int, error) {
addr, err := net.ResolveTCPAddr("tcp", "localhost:0")
if err != nil {

View File

@@ -8,9 +8,10 @@ import (
"strings"
"testing"
"github.com/stretchr/testify/require"
"github.com/aquasecurity/trivy/pkg/fanal/artifact"
"github.com/aquasecurity/trivy/pkg/types"
"github.com/stretchr/testify/require"
)
// TestRepository tests `trivy repo` with the local code repositories
@@ -32,6 +33,7 @@ func TestRepository(t *testing.T) {
format types.Format
includeDevDeps bool
parallel int
vex string
}
tests := []struct {
name string
@@ -74,6 +76,24 @@ func TestRepository(t *testing.T) {
},
golden: "testdata/gomod.json.golden",
},
{
name: "gomod with local VEX file",
args: args{
scanner: types.VulnerabilityScanner,
input: "testdata/fixtures/repo/gomod",
vex: "testdata/fixtures/vex/file/openvex.json",
},
golden: "testdata/gomod-vex.json.golden",
},
{
name: "gomod with VEX repository",
args: args{
scanner: types.VulnerabilityScanner,
input: "testdata/fixtures/repo/gomod",
vex: "repo",
},
golden: "testdata/gomod-vex.json.golden",
},
{
name: "npm",
args: args{
@@ -437,9 +457,15 @@ func TestRepository(t *testing.T) {
// Set up testing DB
cacheDir := initDB(t)
// Set a temp dir so that modules will not be loaded
// Set up VEX
initVEXRepository(t, cacheDir, cacheDir)
// Set a temp dir so that the VEX config will be loaded and modules will not be loaded
t.Setenv("XDG_DATA_HOME", cacheDir)
// Disable Go license detection
t.Setenv("GOPATH", cacheDir)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
command := "repo"
@@ -532,6 +558,10 @@ func TestRepository(t *testing.T) {
osArgs = append(osArgs, "--secret-config", tt.args.secretConfig)
}
if tt.args.vex != "" {
osArgs = append(osArgs, "--vex", tt.args.vex)
}
runTest(t, osArgs, tt.golden, "", format, runOptions{
fakeUUID: "3ff14136-e09f-4df9-80ea-%012d",
override: tt.override,

View File

@@ -0,0 +1,4 @@
repositories:
- name: default
url: https://localhost
enabled: true

View File

@@ -0,0 +1,23 @@
{
"@context": "https://openvex.dev/ns/v0.2.0",
"@id": "aquasecurity/trivy:613fd55abbc2857b5ca28b07a26f3cd4c8b0ddc4c8a97c57497a2d4c4880d7fc",
"author": "Aqua Security",
"timestamp": "2024-07-09T11:38:00.115697+04:00",
"version": 1,
"statements": [
{
"vulnerability": { "@id": "CVE-2022-23628" },
"products": [
{
"@id": "pkg:golang/github.com/testdata/testdata",
"subcomponents": [
{ "@id": "pkg:golang/github.com/open-policy-agent/opa@0.35.0" }
]
}
],
"status": "not_affected",
"justification": "vulnerable_code_not_in_execute_path",
"impact_statement": "The vulnerable code isn't called"
}
]
}

View File

@@ -0,0 +1,9 @@
{
"version": 1,
"packages": [
{
"ID": "pkg:golang/github.com/testdata/testdata",
"Location": "./openvex.json"
}
]
}

View File

@@ -0,0 +1,15 @@
{
"name": "Test VEX Repository",
"description": "VEX Repository for Testing",
"versions": [
{
"spec_version": "0.1",
"locations": [
{
"url": "never used"
}
],
"update_interval": "24h"
}
]
}

View File

@@ -0,0 +1,148 @@
{
"SchemaVersion": 2,
"CreatedAt": "2021-08-25T12:20:30.000000005Z",
"ArtifactName": "testdata/fixtures/repo/gomod",
"ArtifactType": "repository",
"Metadata": {
"ImageConfig": {
"architecture": "",
"created": "0001-01-01T00:00:00Z",
"os": "",
"rootfs": {
"type": "",
"diff_ids": null
},
"config": {}
}
},
"Results": [
{
"Target": "go.mod",
"Class": "lang-pkgs",
"Type": "gomod",
"Vulnerabilities": [
{
"VulnerabilityID": "GMS-2022-20",
"PkgID": "github.com/docker/distribution@v2.7.1+incompatible",
"PkgName": "github.com/docker/distribution",
"PkgIdentifier": {
"PURL": "pkg:golang/github.com/docker/distribution@2.7.1%2Bincompatible",
"UID": "de19cd663ca047a8"
},
"InstalledVersion": "2.7.1+incompatible",
"FixedVersion": "v2.8.0",
"Status": "fixed",
"Layer": {},
"DataSource": {
"ID": "ghsa",
"Name": "GitHub Security Advisory Go",
"URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Ago"
},
"Title": "OCI Manifest Type Confusion Issue",
"Description": "### Impact\n\nSystems that rely on digest equivalence for image attestations may be vulnerable to type confusion.",
"Severity": "UNKNOWN",
"References": [
"https://github.com/advisories/GHSA-qq97-vm5h-rrhg",
"https://github.com/distribution/distribution/commit/b59a6f827947f9e0e67df0cfb571046de4733586",
"https://github.com/distribution/distribution/security/advisories/GHSA-qq97-vm5h-rrhg",
"https://github.com/opencontainers/image-spec/pull/411"
]
},
{
"VulnerabilityID": "CVE-2021-38561",
"PkgID": "golang.org/x/text@v0.3.6",
"PkgName": "golang.org/x/text",
"PkgIdentifier": {
"PURL": "pkg:golang/golang.org/x/text@0.3.6",
"UID": "825dc613c0f39d45"
},
"InstalledVersion": "0.3.6",
"FixedVersion": "0.3.7",
"Status": "fixed",
"Layer": {},
"PrimaryURL": "https://avd.aquasec.com/nvd/cve-2021-38561",
"DataSource": {
"ID": "ghsa",
"Name": "GitHub Security Advisory Go",
"URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Ago"
},
"Description": "Due to improper index calculation, an incorrectly formatted language tag can cause Parse\nto panic via an out of bounds read. If Parse is used to process untrusted user inputs,\nthis may be used as a vector for a denial of service attack.\n",
"Severity": "UNKNOWN",
"References": [
"https://go-review.googlesource.com/c/text/+/340830",
"https://go.googlesource.com/text/+/383b2e75a7a4198c42f8f87833eefb772868a56f",
"https://pkg.go.dev/vuln/GO-2021-0113"
]
}
]
},
{
"Target": "submod/go.mod",
"Class": "lang-pkgs",
"Type": "gomod",
"Vulnerabilities": [
{
"VulnerabilityID": "GMS-2022-20",
"PkgID": "github.com/docker/distribution@v2.7.1+incompatible",
"PkgName": "github.com/docker/distribution",
"PkgIdentifier": {
"PURL": "pkg:golang/github.com/docker/distribution@2.7.1%2Bincompatible",
"UID": "94376dc37054a7e8"
},
"InstalledVersion": "2.7.1+incompatible",
"FixedVersion": "v2.8.0",
"Status": "fixed",
"Layer": {},
"DataSource": {
"ID": "ghsa",
"Name": "GitHub Security Advisory Go",
"URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Ago"
},
"Title": "OCI Manifest Type Confusion Issue",
"Description": "### Impact\n\nSystems that rely on digest equivalence for image attestations may be vulnerable to type confusion.",
"Severity": "UNKNOWN",
"References": [
"https://github.com/advisories/GHSA-qq97-vm5h-rrhg",
"https://github.com/distribution/distribution/commit/b59a6f827947f9e0e67df0cfb571046de4733586",
"https://github.com/distribution/distribution/security/advisories/GHSA-qq97-vm5h-rrhg",
"https://github.com/opencontainers/image-spec/pull/411"
]
}
]
},
{
"Target": "submod2/go.mod",
"Class": "lang-pkgs",
"Type": "gomod",
"Vulnerabilities": [
{
"VulnerabilityID": "GMS-2022-20",
"PkgID": "github.com/docker/distribution@v2.7.1+incompatible",
"PkgName": "github.com/docker/distribution",
"PkgIdentifier": {
"PURL": "pkg:golang/github.com/docker/distribution@2.7.1%2Bincompatible",
"UID": "94306cdcf85fb50a"
},
"InstalledVersion": "2.7.1+incompatible",
"FixedVersion": "v2.8.0",
"Status": "fixed",
"Layer": {},
"DataSource": {
"ID": "ghsa",
"Name": "GitHub Security Advisory Go",
"URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Ago"
},
"Title": "OCI Manifest Type Confusion Issue",
"Description": "### Impact\n\nSystems that rely on digest equivalence for image attestations may be vulnerable to type confusion.",
"Severity": "UNKNOWN",
"References": [
"https://github.com/advisories/GHSA-qq97-vm5h-rrhg",
"https://github.com/distribution/distribution/commit/b59a6f827947f9e0e67df0cfb571046de4733586",
"https://github.com/distribution/distribution/security/advisories/GHSA-qq97-vm5h-rrhg",
"https://github.com/opencontainers/image-spec/pull/411"
]
}
]
}
]
}