CVE-2024-35192: Insufficient Information (NVD-CWE-noinfo)
value: 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.
CWE description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
Published: 2024-05-20T21:15Z
Repository: https://github.com/aquasecurity/trivy
Language: Go
Files changed: pkg/fanal/image/registry/azure/azure.go, pkg/fanal/image/registry/azure/azure_test.go, pkg/fanal/image/registry/ecr/ecr.go, pkg/fanal/image/registry/ecr/ecr_test.go, pkg/fanal/image/registry/google/google.go, pkg/fanal/image/registry/google/google_test.go
Commit date: 2024-05-20 07:10:09 +0400
Commit message: 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
Diff: diff --git a/pkg/fanal/image/registry/azure/azure.go b/pkg/fanal/image/registry/azure/azure.go
index 491fce4e..fe348eaa 100644
--- a/pkg/fanal/image/registry/azure/azure.go
+++ b/pkg/fanal/image/registry/azure/azure.go
@@ -18,11 +18,11 @@ import (
 type Registry struct {
 	domain string
 }
 
 const (
-	azureURL = "azurecr.io"
+	azureURL = ".azurecr.io"
 	scope    = "https://management.azure.com/.default"
 	scheme   = "https"
 )
 
 func (r *Registry) CheckOptions(domain string, _ types.RegistryOptions) error {
diff --git a/pkg/fanal/image/registry/azure/azure_test.go b/pkg/fanal/image/registry/azure/azure_test.go
index ae823b82..dc4d03fc 100644
--- a/pkg/fanal/image/registry/azure/azure_test.go
+++ b/pkg/fanal/image/registry/azure/azure_test.go
@@ -17,10 +17,15 @@ 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",
 			wantErr: "Azure registry: invalid url pattern",
 		},
diff --git a/pkg/fanal/image/registry/ecr/ecr.go b/pkg/fanal/image/registry/ecr/ecr.go
index e675ed47..90dc4ef6 100644
--- a/pkg/fanal/image/registry/ecr/ecr.go
+++ b/pkg/fanal/image/registry/ecr/ecr.go
@@ -12,11 +12,12 @@ import (
 	"golang.org/x/xerrors"
 
 	"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)
 }
 
@@ -35,11 +36,11 @@ func getSession(option types.RegistryOptions) (aws.Config, error) {
 	}
 	return config.LoadDefaultConfig(context.TODO())
 }
 
 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)
 	}
 
 	cfg, err := getSession(option)
 	if err != nil {
diff --git a/pkg/fanal/image/registry/ecr/ecr_test.go b/pkg/fanal/image/registry/ecr/ecr_test.go
index 63ae1858..f968cf1d 100644
--- a/pkg/fanal/image/registry/ecr/ecr_test.go
+++ b/pkg/fanal/image/registry/ecr/ecr_test.go
@@ -19,10 +19,18 @@ func TestCheckOptions(t *testing.T) {
 	}{
 		"InvalidURL": {
 			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",
 		},
 	}
 
diff --git a/pkg/fanal/image/registry/google/google.go b/pkg/fanal/image/registry/google/google.go
index f4e7a741..fe52c85f 100644
--- a/pkg/fanal/image/registry/google/google.go
+++ b/pkg/fanal/image/registry/google/google.go
@@ -16,17 +16,18 @@ type Registry struct {
 	Store  store.GCRCredStore
 	domain string
 }
 
 // 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
 	if option.GCPCredPath != "" {
 		g.Store = store.NewGCRCredStore(option.GCPCredPath)
diff --git a/pkg/fanal/image/registry/google/google_test.go b/pkg/fanal/image/registry/google/google_test.go
index 62a2b1f5..2e4ba64d 100644
--- a/pkg/fanal/image/registry/google/google_test.go
+++ b/pkg/fanal/image/registry/google/google_test.go
@@ -19,10 +19,14 @@ func TestCheckOptions(t *testing.T) {
 	}{
 		"InvalidURL": {
 			domain:  "alpine:3.9",
 			wantErr: types.InvalidURLPattern,
 		},
+		"InvalidDomain": {
+			domain:  "not-gcr.io",
+			wantErr: types.InvalidURLPattern,
+		},
 		"NoOption": {
 			domain: "gcr.io",
 			gcr:    &Registry{domain: "gcr.io"},
 		},
 		"CredOption": {

Vulnerable code: 	azureURL = "azurecr.io"
const ecrURL = "amazonaws.com"
	if !strings.HasSuffix(domain, ecrURL) {
const gcrURL = "gcr.io"
const garURL = "docker.pkg.dev"
	if !strings.HasSuffix(domain, gcrURL) && !strings.HasSuffix(domain, garURL) {
Fixed code: 	azureURL = ".azurecr.io"
		{
			name:    "invalidURL",
			domain:  "not-azurecr.io",
			wantErr: "Azure registry: invalid url pattern",
		},
const ecrURLSuffix = ".amazonaws.com"
const ecrURLPartial = ".dkr.ecr"
	if !strings.HasSuffix(domain, ecrURLSuffix) && !strings.Contains(domain, ecrURLPartial)  {
		"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,
		},
const gcrURLDomain = "gcr.io"
const gcrURLSuffix = ".gcr.io"
const garURLSuffix = "-docker.pkg.dev"
	if domain != gcrURLDomain && !strings.HasSuffix(domain, gcrURLSuffix) && !strings.HasSuffix(domain, garURLSuffix) {
		"InvalidDomain": {
			domain:  "not-gcr.io",
			wantErr: types.InvalidURLPattern,
		},