diff --git a/plugins/rest/auth.go b/plugins/rest/auth.go index a28f21782a..3cae61ebff 100644 --- a/plugins/rest/auth.go +++ b/plugins/rest/auth.go @@ -708,6 +708,7 @@ type awsSigningAuthPlugin struct { AWSService string `json:"service,omitempty"` AWSSignatureVersion string `json:"signature_version,omitempty"` + host string ecrAuthPlugin *ecrAuthPlugin kmsSignPlugin *awsKMSSignPlugin @@ -827,6 +828,13 @@ func (ap *awsSigningAuthPlugin) NewClient(c Config) (*http.Client, error) { return nil, err } + url, err := url.Parse(c.URL) + if err != nil { + return nil, err + } + + ap.host = url.Host + if ap.logger == nil { ap.logger = c.logger } @@ -839,6 +847,13 @@ func (ap *awsSigningAuthPlugin) NewClient(c Config) (*http.Client, error) { } func (ap *awsSigningAuthPlugin) Prepare(req *http.Request) error { + if ap.host != req.URL.Host { + // Return early if the host does not match. + // This can happen when the OCI registry responded with a redirect to another host. + // For instance, ECR redirects to S3 and the ECR auth header should not be included in the S3 request. + return nil + } + switch ap.AWSService { case "ecr": return ap.ecrAuthPlugin.Prepare(req) diff --git a/plugins/rest/aws_test.go b/plugins/rest/aws_test.go index ebd743f89b..25c7f339f0 100644 --- a/plugins/rest/aws_test.go +++ b/plugins/rest/aws_test.go @@ -1586,6 +1586,54 @@ func TestECRAuthPluginRequestsAuthorizationToken(t *testing.T) { } } +func TestECRAuthPluginRequestsRedirection(t *testing.T) { + // Environment credentials to sign the ecr get authorization token request + t.Setenv(accessKeyEnvVar, "blablabla") + t.Setenv(secretKeyEnvVar, "tatata") + t.Setenv(awsRegionEnvVar, "us-east-1") + t.Setenv(sessionTokenEnvVar, "lalala") + + ap := awsSigningAuthPlugin{ + logger: logging.NewNoOpLogger(), + AWSEnvironmentCredentials: &awsEnvironmentCredentialService{}, + host: "somewhere.com", + AWSService: "ecr", + } + + apECR := newECRAuthPlugin(&ap) + apECR.ecr = &ecrStub{token: aws.ECRAuthorizationToken{ + AuthorizationToken: "secret", + }} + + ap.ecrAuthPlugin = apECR + + // Request to the host specified in the plugin configuration + req := httptest.NewRequest("", "http://somewhere.com", nil) + + if err := ap.Prepare(req); err != nil { + t.Errorf("ecrAuthPlugin.Prepare() = %q", err) + } + + got := req.Header.Get("Authorization") + want := "Basic secret" + if got != want { + t.Errorf("req.Header.Get(\"Authorization\") = %q, want %q", got, want) + } + + // Redirection to another host + req = httptest.NewRequest("", "http://somewhere-else.com", nil) + + if err := ap.Prepare(req); err != nil { + t.Errorf("ecrAuthPlugin.Prepare() = %q", err) + } + + got = req.Header.Get("Authorization") + want = "" + if got != want { + t.Errorf("req.Header.Get(\"Authorization\") = %q, want %q", got, want) + } +} + type ecrStub struct { token aws.ECRAuthorizationToken }