Skip to content

Commit

Permalink
fix: move openvex packages as subcomponents (#366)
Browse files Browse the repository at this point in the history
Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
  • Loading branch information
sozercan committed Oct 16, 2023
1 parent 1a7c070 commit f893559
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 65 deletions.
11 changes: 4 additions & 7 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,6 @@ require (
google.golang.org/grpc v1.58.2
)

require (
github.com/sagikazarmark/locafero v0.3.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
)

require (
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
Expand Down Expand Up @@ -102,9 +95,12 @@ require (
github.com/prometheus/client_model v0.4.0 // indirect
github.com/prometheus/common v0.44.0 // indirect
github.com/prometheus/procfs v0.10.1 // indirect
github.com/sagikazarmark/locafero v0.3.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/samber/lo v1.38.1 // indirect
github.com/secure-systems-lab/go-securesystemslib v0.7.0 // indirect
github.com/shibumi/go-pathspec v1.3.0 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spdx/tools-golang v0.5.1 // indirect
github.com/spf13/afero v1.10.0 // indirect
github.com/spf13/cast v1.5.1 // indirect
Expand All @@ -123,6 +119,7 @@ require (
go.opentelemetry.io/otel/sdk v1.14.0 // indirect
go.opentelemetry.io/otel/trace v1.14.0 // indirect
go.opentelemetry.io/proto/otlp v0.19.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/crypto v0.13.0 // indirect
golang.org/x/mod v0.12.0 // indirect
golang.org/x/net v0.15.0 // indirect
Expand Down
2 changes: 1 addition & 1 deletion pkg/patch/patch.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ func patchWithContext(ctx context.Context, image, reportFile, patchedTag, workin
}
// vex document must contain at least one statement
if output != "" && len(validatedManifest.Updates) > 0 {
return vex.TryOutputVexDocument(validatedManifest, pkgmgr, format, output)
return vex.TryOutputVexDocument(validatedManifest, pkgmgr, patchedImageName, format, output)
}
return nil
}
6 changes: 3 additions & 3 deletions pkg/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ type UpdatePackage struct {
Name string `json:"name"`
InstalledVersion string `json:"installedVersion"`
FixedVersion string `json:"fixedVersion"`
VulnerabilityID string `json:"vulnerability"`
VulnerabilityID string `json:"vulnerabilityID"`
}

type UpdatePackages []UpdatePackage

type UpdateManifest struct {
OSType string `json:"ostype"`
OSVersion string `json:"osversion"`
OSType string `json:"osType"`
OSVersion string `json:"osVersion"`
Arch string `json:"arch"`
Updates UpdatePackages `json:"updates"`
}
23 changes: 16 additions & 7 deletions pkg/vex/openvex.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,11 @@ var (

type OpenVex struct{}

func (o *OpenVex) CreateVEXDocument(updates *types.UpdateManifest, pkgmgr pkgmgr.PackageManager) (string, error) {
func (o *OpenVex) CreateVEXDocument(
updates *types.UpdateManifest,
patchedImageName string,
pkgmgr pkgmgr.PackageManager,
) (string, error) {
t := now()
doc := v
doc.Timestamp = &t
Expand All @@ -43,9 +47,15 @@ func (o *OpenVex) CreateVEXDocument(updates *types.UpdateManifest, pkgmgr pkgmgr
}
doc.Metadata.ID = id

imageProduct := vex.Product{
Component: vex.Component{
ID: "pkg:oci/" + patchedImageName,
},
}

pkgType := pkgmgr.GetPackageType()
for _, u := range updates.Updates {
product := vex.Product{
subComponent := vex.Subcomponent{
Component: vex.Component{
// syntax is "pkg:<pkgType>/<osType>/<packageName>@<installedVersion>?arch=<arch>"
ID: "pkg:" + pkgType + "/" + updates.OSType + "/" + u.Name + "@" + u.FixedVersion + "?arch=" + updates.Arch,
Expand All @@ -57,22 +67,21 @@ func (o *OpenVex) CreateVEXDocument(updates *types.UpdateManifest, pkgmgr pkgmgr
for i := range doc.Statements {
if doc.Statements[i].Vulnerability.ID == u.VulnerabilityID {
found = true
doc.Statements[i].Products = append(doc.Statements[i].Products, product)
doc.Statements[i].Products[0].Subcomponents = append(doc.Statements[i].Products[0].Subcomponents, subComponent)
}
}
if found {
continue
}

// otherwise, create new statement
imageProduct.Subcomponents = []vex.Subcomponent{subComponent}
doc.Statements = append(doc.Statements, vex.Statement{
Vulnerability: vex.Vulnerability{
ID: u.VulnerabilityID,
},
Products: []vex.Product{
product,
},
Status: "fixed",
Products: []vex.Product{imageProduct},
Status: "fixed",
})
}

Expand Down
37 changes: 28 additions & 9 deletions pkg/vex/openvex_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ func TestOpenVex_CreateVEXDocument(t *testing.T) {
workingFolder := "/tmp"
alpineManager, _ := pkgmgr.GetPackageManager("alpine", config, workingFolder)
debianManager, _ := pkgmgr.GetPackageManager("debian", config, workingFolder)
patchedImageName := "foo.io/bar:latest"
t.Setenv("COPA_VEX_AUTHOR", "test author")

// mock time
Expand All @@ -24,8 +25,9 @@ func TestOpenVex_CreateVEXDocument(t *testing.T) {
id = func() (string, error) { return "https://openvex.dev/test", nil }

type args struct {
updates *types.UpdateManifest
pkgmgr pkgmgr.PackageManager
updates *types.UpdateManifest
pkgmgr pkgmgr.PackageManager
patchedImageName string
}
tests := []struct {
name string
Expand All @@ -38,6 +40,7 @@ func TestOpenVex_CreateVEXDocument(t *testing.T) {
name: "valid openvex document",
o: &OpenVex{},
args: args{
patchedImageName: patchedImageName,
updates: &types.UpdateManifest{
Updates: []types.UpdatePackage{
{
Expand Down Expand Up @@ -66,7 +69,12 @@ func TestOpenVex_CreateVEXDocument(t *testing.T) {
},
"products": [
{
"@id": "pkg:apk/alpine/test1@1.1?arch=x86_64"
"@id": "pkg:oci/foo.io/bar:latest",
"subcomponents": [
{
"@id": "pkg:apk/alpine/test1@1.1?arch=x86_64"
}
]
}
],
"status": "fixed"
Expand All @@ -80,6 +88,7 @@ func TestOpenVex_CreateVEXDocument(t *testing.T) {
name: "valid openvex document with multiple statements and multiple vulnerabilities",
o: &OpenVex{},
args: args{
patchedImageName: patchedImageName,
updates: &types.UpdateManifest{
Updates: []types.UpdatePackage{
{
Expand Down Expand Up @@ -114,10 +123,15 @@ func TestOpenVex_CreateVEXDocument(t *testing.T) {
},
"products": [
{
"@id": "pkg:apk/alpine/test1@1.1?arch=x86_64"
},
{
"@id": "pkg:deb/debian/test2@1.2?arch=x86_64"
"@id": "pkg:oci/foo.io/bar:latest",
"subcomponents": [
{
"@id": "pkg:apk/alpine/test1@1.1?arch=x86_64"
},
{
"@id": "pkg:deb/debian/test2@1.2?arch=x86_64"
}
]
}
],
"status": "fixed"
Expand All @@ -128,7 +142,12 @@ func TestOpenVex_CreateVEXDocument(t *testing.T) {
},
"products": [
{
"@id": "pkg:deb/debian/test3@1.3?arch=x86_64"
"@id": "pkg:oci/foo.io/bar:latest",
"subcomponents": [
{
"@id": "pkg:deb/debian/test3@1.3?arch=x86_64"
}
]
}
],
"status": "fixed"
Expand All @@ -142,7 +161,7 @@ func TestOpenVex_CreateVEXDocument(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
o := &OpenVex{}
got, err := o.CreateVEXDocument(tt.args.updates, tt.args.pkgmgr)
got, err := o.CreateVEXDocument(tt.args.updates, tt.args.patchedImageName, tt.args.pkgmgr)
if (err != nil) != tt.wantErr {
t.Errorf("OpenVex.CreateVEXDocument() error = %v, wantErr %v", err, tt.wantErr)
return
Expand Down
6 changes: 3 additions & 3 deletions pkg/vex/vex.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,17 @@ import (
)

type Vex interface {
CreateVEXDocument(updates *types.UpdateManifest, pkgmgr pkgmgr.PackageManager) (string, error)
CreateVEXDocument(updates *types.UpdateManifest, patchedImageName string, pkgmgr pkgmgr.PackageManager) (string, error)
}

func TryOutputVexDocument(updates *types.UpdateManifest, pkgmgr pkgmgr.PackageManager, format, file string) error {
func TryOutputVexDocument(updates *types.UpdateManifest, pkgmgr pkgmgr.PackageManager, patchedImageName, format, file string) error {
var doc string
var err error

switch format {
case "openvex":
ov := &OpenVex{}
doc, err = ov.CreateVEXDocument(updates, pkgmgr)
doc, err = ov.CreateVEXDocument(updates, patchedImageName, pkgmgr)
if err != nil {
return err
}
Expand Down
30 changes: 17 additions & 13 deletions pkg/vex/vex_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ func TestTryOutputVexDocument(t *testing.T) {
config := &buildkit.Config{}
workingFolder := "/tmp"
alpineManager, _ := pkgmgr.GetPackageManager("alpine", config, workingFolder)
patchedImageName := "patched"

type args struct {
updates *types.UpdateManifest
pkgmgr pkgmgr.PackageManager
format string
file string
updates *types.UpdateManifest
pkgmgr pkgmgr.PackageManager
patchedImageName string
format string
file string
}
tests := []struct {
name string
Expand All @@ -27,27 +29,29 @@ func TestTryOutputVexDocument(t *testing.T) {
{
name: "invalid format",
args: args{
updates: &types.UpdateManifest{},
pkgmgr: nil,
format: "fakevex",
file: "",
updates: &types.UpdateManifest{},
pkgmgr: nil,
patchedImageName: patchedImageName,
format: "fakevex",
file: "",
},
wantErr: true,
},
{
name: "valid format",
args: args{
updates: &types.UpdateManifest{},
pkgmgr: alpineManager,
format: "openvex",
file: "/tmp/test",
updates: &types.UpdateManifest{},
pkgmgr: alpineManager,
patchedImageName: patchedImageName,
format: "openvex",
file: "/tmp/test",
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := TryOutputVexDocument(tt.args.updates, tt.args.pkgmgr, tt.args.format, tt.args.file); (err != nil) != tt.wantErr {
if err := TryOutputVexDocument(tt.args.updates, tt.args.pkgmgr, tt.args.patchedImageName, tt.args.format, tt.args.file); (err != nil) != tt.wantErr {
t.Errorf("TryOutputVexDocument() error = %v, wantErr %v", err, tt.wantErr)
}
})
Expand Down
34 changes: 12 additions & 22 deletions website/docs/output.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,37 +35,27 @@ This will generate a VEX Document that looks like:
```json
{
"@context": "https://openvex.dev/ns",
"@id": "https://openvex.dev/docs/public/vex-6f15c26e0410a4d44e0af4062f4b883fbc19a98e57baf131715d942213e5002a",
"@id": "https://openvex.dev/docs/public/vex-a6c44ec1d79e9dd4190dc01b4ecf7527ebb26bd37c01e32e6efcd203ae00d2a5",
"author": "Project Copacetic",
"timestamp": "2023-08-25T21:40:23.891230545Z",
"timestamp": "2023-10-11T00:15:00.114768055Z",
"version": 1,
"tooling": "Project Copacetic",
"statements": [
{
"vulnerability": {
"@id": "CVE-2021-3995"
"@id": "CVE-2021-22945"
},
"products": [
{
"@id": "pkg:deb/debian/bsdutils@1:2.36.1-8?arch=amd64"
},
{
"@id": "pkg:deb/debian/libblkid1@2.36.1-8?arch=amd64"
},
{
"@id": "pkg:deb/debian/libmount1@2.36.1-8?arch=amd64"
},
{
"@id": "pkg:deb/debian/libsmartcols1@2.36.1-8?arch=amd64"
},
{
"@id": "pkg:deb/debian/libuuid1@2.36.1-8?arch=amd64"
},
{
"@id": "pkg:deb/debian/mount@2.36.1-8?arch=amd64"
},
{
"@id": "pkg:deb/debian/util-linux@2.36.1-8?arch=amd64"
"@id": "pkg:oci/docker.io/library/nginx:1.21.6-patched",
"subcomponents": [
{
"@id": "pkg:deb/debian/curl@7.74.0-1.3+deb11u2?arch=amd64"
},
{
"@id": "pkg:deb/debian/libcurl4@7.74.0-1.3+deb11u2?arch=amd64"
}
]
}
],
"status": "fixed"
Expand Down

0 comments on commit f893559

Please sign in to comment.