CVE-2023-42816: Insufficient Information (NVD-CWE-noinfo)
value: Kyverno is a policy engine designed for Kubernetes. A security vulnerability was found in Kyverno where an attacker could cause denial of service of Kyverno. The vulnerability was in Kyvernos Notary verifier. An attacker would need control over the registry from which Kyverno would fetch signatures. With such a position, the attacker could return a malicious response to Kyverno, when Kyverno would send a request to the registry. The malicious response would cause denial of service of Kyverno, such that other users' admission requests would be blocked from being processed. This is a vulnerability in a new component released in v1.11.0. The only users affected by this are those that have been building Kyverno from source at the main branch which is not encouraged. Users consuming official Kyverno releases are not affected. There are no known cases of this vulnerability being exploited in the wild.
CWE description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
CVSS v3 base score: 5.3
Published: 2023-11-13T21:15Z
Repository: https://github.com/kyverno/kyverno
Language: Go
Files changed: pkg/notary/notary.go, pkg/notary/repository.go
Commit date: 2023-09-18 15:02:31 +0800
Commit message: fix: address vulnerability issues in notary implementations (#8428)

* fix: set max limit on referrers count

Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com>

* feat: add limit to max size of payload

Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com>

* feat: add max count limit on listsignatures

Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com>

* feat: add max signature size limit in FetchSignatureBlob

Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com>

---------

Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com>
Co-authored-by: shuting <shuting@nirmata.com>
Diff: diff --git a/pkg/notary/notary.go b/pkg/notary/notary.go
index 2d60dc5f8..38dff2a66 100644
--- a/pkg/notary/notary.go
+++ b/pkg/notary/notary.go
@@ -22,10 +22,15 @@ import (
 	"github.com/pkg/errors"
 	"github.com/sigstore/sigstore/pkg/cryptoutils"
 	"go.uber.org/multierr"
 )
 
+var (
+	maxReferrersCount = 50
+	maxPayloadSize    = 10 * 1000 * 1000 // 10 MB
+)
+
 func NewVerifier() images.ImageVerifier {
 	return &notaryVerifier{
 		log: logging.WithName("Notary"),
 	}
 }
@@ -160,10 +165,15 @@ func (v *notaryVerifier) FetchAttestations(ctx context.Context, opts images.Opti
 	referrersDescs, err := referrers.IndexManifest()
 	if err != nil {
 		return nil, err
 	}
 
+	// See: https://github.com/kyverno/kyverno/security/advisories/GHSA-9g37-h7p2-2c6r
+	if len(referrersDescs.Manifests) > maxReferrersCount {
+		return nil, fmt.Errorf("failed to fetch referrers: to many referrers found, max limit is %d", maxReferrersCount)
+	}
+
 	v.log.V(4).Info("fetched referrers", "referrers", referrersDescs)
 
 	var statements []map[string]interface{}
 
 	for _, referrer := range referrersDescs.Manifests {
@@ -306,10 +316,15 @@ func extractStatement(ctx context.Context, repoRef name.Reference, desc v1.Descr
 	if len(manifest.Layers) > 1 {
 		return nil, fmt.Errorf("multiple layers in predicate not supported: %+v", manifest)
 	}
 	predicateDesc := manifest.Layers[0]
 
+	// See: https://github.com/kyverno/kyverno/security/advisories/GHSA-wc3x-5rfv-hh5v
+	if predicateDesc.Size > int64(maxPayloadSize) {
+		return nil, fmt.Errorf("payload size is too large, max size is %d: %+v", maxPayloadSize, predicateDesc)
+	}
+
 	layer, err := gcrremote.Layer(ref.Context().Digest(predicateDesc.Digest.String()), remoteOpts...)
 	if err != nil {
 		return nil, err
 	}
 	ioPredicate, err := layer.Uncompressed()
diff --git a/pkg/notary/repository.go b/pkg/notary/repository.go
index 6b02a83a1..7ffebe457 100644
--- a/pkg/notary/repository.go
+++ b/pkg/notary/repository.go
@@ -48,10 +48,15 @@ func (c *repositoryClient) ListSignatures(ctx context.Context, desc ocispec.Desc
 	referrersDescs, err := referrers.IndexManifest()
 	if err != nil {
 		return err
 	}
 
+	// See: https://github.com/kyverno/kyverno/security/advisories/GHSA-hjpv-68f4-2262
+	if len(referrersDescs.Manifests) > maxReferrersCount {
+		return fmt.Errorf("failed to fetch referrers: to many referrers found, max limit is %d", maxReferrersCount)
+	}
+
 	descList := []ocispec.Descriptor{}
 	for _, d := range referrersDescs.Manifests {
 		if d.ArtifactType == notationregistry.ArtifactTypeNotation {
 			descList = append(descList, v1ToOciSpecDescriptor(d))
 		}
@@ -79,10 +84,15 @@ func (c *repositoryClient) FetchSignatureBlob(ctx context.Context, desc ocispec.
 	if err := json.Unmarshal(manifestBytes, &manifest); err != nil {
 		return nil, ocispec.Descriptor{}, err
 	}
 	manifestDesc := manifest.Layers[0]
 
+	// See: https://github.com/kyverno/kyverno/security/advisories/GHSA-4mp4-46gq-hv3r
+	if manifestDesc.Size > int64(maxPayloadSize) {
+		return nil, ocispec.Descriptor{}, fmt.Errorf("payload size is too large, max size is %d: %+v", maxPayloadSize, manifestDesc)
+	}
+
 	signatureBlobRef, err := name.ParseReference(c.getReferenceFromDescriptor(manifestDesc))
 	if err != nil {
 		return nil, ocispec.Descriptor{}, err
 	}
 

Fixed code: var (
	maxReferrersCount = 50
	maxPayloadSize    = 10 * 1000 * 1000 // 10 MB
)

	// See: https://github.com/kyverno/kyverno/security/advisories/GHSA-9g37-h7p2-2c6r
	if len(referrersDescs.Manifests) > maxReferrersCount {
		return nil, fmt.Errorf("failed to fetch referrers: to many referrers found, max limit is %d", maxReferrersCount)
	}

	// See: https://github.com/kyverno/kyverno/security/advisories/GHSA-wc3x-5rfv-hh5v
	if predicateDesc.Size > int64(maxPayloadSize) {
		return nil, fmt.Errorf("payload size is too large, max size is %d: %+v", maxPayloadSize, predicateDesc)
	}

	// See: https://github.com/kyverno/kyverno/security/advisories/GHSA-hjpv-68f4-2262
	if len(referrersDescs.Manifests) > maxReferrersCount {
		return fmt.Errorf("failed to fetch referrers: to many referrers found, max limit is %d", maxReferrersCount)
	}

	// See: https://github.com/kyverno/kyverno/security/advisories/GHSA-4mp4-46gq-hv3r
	if manifestDesc.Size > int64(maxPayloadSize) {
		return nil, ocispec.Descriptor{}, fmt.Errorf("payload size is too large, max size is %d: %+v", maxPayloadSize, manifestDesc)
	}