CVE-2024-35192 (published 2024-05-20T21:15Z)

Trivy is a security scanner. Prior to 0.51.2, if a malicious actor is able to trigger Trivy to scan container images from a crafted malicious registry, it could result in the leakage of credentials for legitimate registries such as AWS Elastic Container Registry (ECR), Google Cloud Artifact/Container Registry, or Azure Container Registry (ACR). These tokens can then be used to push/pull images from those registries to which the identity/user running Trivy has access. Systems are not affected if the default credential provider chain is unable to obtain valid credentials. This vulnerability only applies when scanning container images directly from a registry. This vulnerability is fixed in 0.51.2.


Weakness information:
cwe_id: NVD-CWE-noinfo
cwe_name: Insufficient Information
description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
extended_description: Insufficient Information

Fix information:
repo_url: https://github.com/aquasecurity/trivy
commit_details: repo_url: https://github.com/aquasecurity/trivy
author: Luke Young
author_date: 2024-05-19 20:10:09-07:00
msg: Merge pull request from GHSA-xcq4-m2r3-cmrj

* Update azure.go

* Update ecr.go

* Update google.go

* Update ecr_test.go

* Update azure_test.go

* Update google_test.go
repository: repo_url: https://github.com/aquasecurity/trivy
repo_name: aquasecurity/trivy
description: Find vulnerabilities, misconfigurations, secrets, SBOM in containers, Kubernetes, code repositories, clouds and more
repo_language: Go
owner: aquasecurity
file_changes: filename: azure.go
change_type: ModificationType.MODIFY
diff: @@ -20,7 +20,7 @@ type Registry struct {
 }
 
 const (
-	azureURL = "azurecr.io"
+	azureURL = ".azurecr.io"
 	scope    = "https://management.azure.com/.default"
 	scheme   = "https"
 )

programming_language: Go
filename: azure_test.go
change_type: ModificationType.MODIFY
diff: @@ -19,6 +19,11 @@ func TestRegistry_CheckOptions(t *testing.T) {
 			name:   "happy path",
 			domain: "test.azurecr.io",
 		},
+		{
+			name:    "invalidURL",
+			domain:  "not-azurecr.io",
+			wantErr: "Azure registry: invalid url pattern",
+		},
 		{
 			name:    "invalidURL",
 			domain:  "alpine:3.9",

programming_language: Go
filename: ecr.go
change_type: ModificationType.MODIFY
diff: @@ -14,7 +14,8 @@ import (
 	"github.com/aquasecurity/trivy/pkg/fanal/types"
 )
 
-const ecrURL = "amazonaws.com"
+const ecrURLSuffix = ".amazonaws.com"
+const ecrURLPartial = ".dkr.ecr"
 
 type ecrAPI interface {
 	GetAuthorizationToken(ctx context.Context, params *ecr.GetAuthorizationTokenInput, optFns ...func(*ecr.Options)) (*ecr.GetAuthorizationTokenOutput, error)
@@ -37,7 +38,7 @@ func getSession(option types.RegistryOptions) (aws.Config, error) {
 }
 
 func (e *ECR) CheckOptions(domain string, option types.RegistryOptions) error {
-	if !strings.HasSuffix(domain, ecrURL) {
+	if !strings.HasSuffix(domain, ecrURLSuffix) && !strings.Contains(domain, ecrURLPartial)  {
 		return xerrors.Errorf("ECR : %w", types.InvalidURLPattern)
 	}
 

programming_language: Go
filename: ecr_test.go
change_type: ModificationType.MODIFY
diff: @@ -21,6 +21,14 @@ func TestCheckOptions(t *testing.T) {
 			domain:  "alpine:3.9",
 			wantErr: types.InvalidURLPattern,
 		},
+		"InvalidDomain": {
+			domain: "xxx.ecr.ap-northeast-1.not-amazonaws.com",
+			wantErr: types.InvalidURLPattern,
+		},
+		"InvalidSubdomain": {
+			domain: "xxx.s3.ap-northeast-1.amazonaws.com",
+			wantErr: types.InvalidURLPattern,
+		},
 		"NoOption": {
 			domain: "xxx.ecr.ap-northeast-1.amazonaws.com",
 		},

programming_language: Go
filename: google.go
change_type: ModificationType.MODIFY
diff: @@ -18,13 +18,14 @@ type Registry struct {
 }
 
 // Google container registry
-const gcrURL = "gcr.io"
+const gcrURLDomain = "gcr.io"
+const gcrURLSuffix = ".gcr.io"
 
 // Google artifact registry
-const garURL = "docker.pkg.dev"
+const garURLSuffix = "-docker.pkg.dev"
 
 func (g *Registry) CheckOptions(domain string, option types.RegistryOptions) error {
-	if !strings.HasSuffix(domain, gcrURL) && !strings.HasSuffix(domain, garURL) {
+	if domain != gcrURLDomain && !strings.HasSuffix(domain, gcrURLSuffix) && !strings.HasSuffix(domain, garURLSuffix) {
 		return xerrors.Errorf("Google registry: %w", types.InvalidURLPattern)
 	}
 	g.domain = domain

programming_language: Go
filename: google_test.go
change_type: ModificationType.MODIFY
diff: @@ -21,6 +21,10 @@ func TestCheckOptions(t *testing.T) {
 			domain:  "alpine:3.9",
 			wantErr: types.InvalidURLPattern,
 		},
+		"InvalidDomain": {
+			domain:  "not-gcr.io",
+			wantErr: types.InvalidURLPattern,
+		},
 		"NoOption": {
 			domain: "gcr.io",
 			gcr:    &Registry{domain: "gcr.io"},

programming_language: Go