Skip to content

Commit

Permalink
Merge pull request #1 from kyverno/GHSA-vfp6-jrw2-99g9-fix-in-cosign-…
Browse files Browse the repository at this point in the history
…v1.13.1

feat: add GHSA-vfp6-jrw2-99g9 fixes in cosign v1.13.1
  • Loading branch information
realshuting authored Nov 9, 2023
2 parents d1c6336 + 7b8a21d commit 5912cb3
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 3 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/kind-verify-attestation.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:

env:
KO_DOCKER_REPO: "registry.local:5000/policy-controller"
SCAFFOLDING_RELEASE_VERSION: "v0.4.8"
SCAFFOLDING_RELEASE_VERSION: "v0.6.8"
GO111MODULE: on
GOFLAGS: -ldflags=-s -ldflags=-w
KOCACHE: ~/ko
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,9 @@ ko-sget:
.PHONY: ko-local
ko-local:
$(create_kocache_path)
LDFLAGS="$(LDFLAGS)" GIT_HASH=$(GIT_HASH) GIT_VERSION=$(GIT_VERSION) \
KO_DOCKER_REPO=ko.local LDFLAGS="$(LDFLAGS)" GIT_HASH=$(GIT_HASH) GIT_VERSION=$(GIT_VERSION) \
KOCACHE=$(KOCACHE_PATH) ko build --base-import-paths \
--tags $(GIT_VERSION) --tags $(GIT_HASH) --local \
--tags $(GIT_VERSION) --tags $(GIT_HASH) \
$(ARTIFACT_HUB_LABELS) \
github.com/sigstore/cosign/cmd/cosign

Expand Down
10 changes: 10 additions & 0 deletions pkg/cosign/fetch.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import (
"golang.org/x/sync/errgroup"
)

const maxAllowedSigsOrAtts = 100

type SignedPayload struct {
Base64Signature string
Payload []byte
Expand Down Expand Up @@ -78,6 +80,10 @@ func FetchSignaturesForReference(ctx context.Context, ref name.Reference, opts .
return nil, fmt.Errorf("no signatures associated with %s", ref)
}

if len(l) > maxAllowedSigsOrAtts {
return nil, fmt.Errorf("maximum number of signatures on an image is %d, found %d", maxAllowedSigsOrAtts, len(l))
}

signatures := make([]SignedPayload, len(l))
var g errgroup.Group
g.SetLimit(runtime.NumCPU())
Expand Down Expand Up @@ -130,6 +136,10 @@ func FetchAttestationsForReference(ctx context.Context, ref name.Reference, opts
return nil, fmt.Errorf("no attestations associated with %s", ref)
}

if len(l) > maxAllowedSigsOrAtts {
return nil, fmt.Errorf("maximum number of attestations on an image is %d, found %d", maxAllowedSigsOrAtts, len(l))
}

attestations := make([]AttestationPayload, len(l))
var g errgroup.Group
g.SetLimit(runtime.NumCPU())
Expand Down
104 changes: 104 additions & 0 deletions test/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,81 @@ func TestAttestationReplaceCreate(t *testing.T) {
}
}

func TestExcessiveAttestations(t *testing.T) {
repo, stop := reg(t)
defer stop()
td := t.TempDir()

imgName := path.Join(repo, "cosign-attest-download-e2e")

_, _, cleanup := mkimage(t, imgName)
defer cleanup()

_, privKeyPath, _ := keypair(t, td)
ko := options.KeyOpts{KeyRef: privKeyPath, PassFunc: passFunc}

ctx := context.Background()

slsaAttestation := `{ "buildType": "x", "builder": { "id": "2" }, "recipe": {} }`
slsaAttestationPath := filepath.Join(td, "attestation.slsa.json")
if err := os.WriteFile(slsaAttestationPath, []byte(slsaAttestation), 0600); err != nil {
t.Fatal(err)
}

vulnAttestation := `
{
"invocation": {
"parameters": null,
"uri": "invocation.example.com/cosign-testing",
"event_id": "",
"builder.id": ""
},
"scanner": {
"uri": "fakescanner.example.com/cosign-testing",
"version": "",
"db": {
"uri": "",
"version": ""
},
"result": null
},
"metadata": {
"scanStartedOn": "2022-04-12T00:00:00Z",
"scanFinishedOn": "2022-04-12T00:10:00Z"
}
}
`
ref, err := name.ParseReference(imgName)
if err != nil {
t.Fatal(err)
}
regOpts := options.RegistryOptions{}
ociremoteOpts, err := regOpts.ClientOpts(ctx)
if err != nil {
t.Fatal(err)
}

for i := 0; i < 102; i++ {
vulnAttestationPath := filepath.Join(td, fmt.Sprintf("attestation-%d.vuln.json", i))
if err := os.WriteFile(vulnAttestationPath, []byte(vulnAttestation), 0600); err != nil {
t.Fatal(err)
}

// Attest again with replace=true, replacing the previous attestation
must(attest.AttestCmd(ctx, ko, options.RegistryOptions{}, imgName, "", "", false, vulnAttestationPath, false,
"vuln", false, 30*time.Second, false), t)
}

_, err = cosign.FetchAttestationsForReference(ctx, ref, ociremoteOpts...)
if err == nil {
t.Fatalf("Expected an error, but 'err' was 'nil'")
}
expectedError := "maximum number of attestations on an image is 100, found 102"
if err.Error() != expectedError {
t.Errorf("Exted the error to be: '%s' but it was '%s'", expectedError, err.Error())
}
}

func TestAttestationReplace(t *testing.T) {
repo, stop := reg(t)
defer stop()
Expand Down Expand Up @@ -505,6 +580,35 @@ func TestDuplicateSign(t *testing.T) {
}
}

func TestExcessiveSignatures(t *testing.T) {
repo, stop := reg(t)
defer stop()
td := t.TempDir()

imgName := path.Join(repo, "cosign-e2e")

_, _, cleanup := mkimage(t, imgName)
defer cleanup()

ctx := context.Background()

for i := 0; i < 102; i++ {
_, privKeyPath, _ := keypair(t, td)

// Sign the image
ko := options.KeyOpts{KeyRef: privKeyPath, PassFunc: passFunc}
must(sign.SignCmd(ro, ko, options.RegistryOptions{}, nil, []string{imgName}, "", "", true, "", "", "", false, false, "", false), t)
}
err := download.SignatureCmd(ctx, options.RegistryOptions{}, imgName)
if err == nil {
t.Fatal("Expected an error, but 'err' was 'nil'")
}
expectedErr := "maximum number of signatures on an image is 100, found 102"
if err.Error() != expectedErr {
t.Fatalf("Expected the error '%s', but got the error '%s'", expectedErr, err.Error())
}
}

func TestKeyURLVerify(t *testing.T) {
// TODO: re-enable once distroless images are being signed by the new client
t.Skip()
Expand Down

0 comments on commit 5912cb3

Please sign in to comment.