mirror of
https://github.com/open-policy-agent/opa.git
synced 2026-08-12 19:32:48 -06:00
Disable the Authorization header for ECR redirects.
ECR uses S3 pre-signed URLs for OCI blobs. If the ECR auth header is added to the pre-signed URL, S3 returns a 400 error. We address the issue by checking whether the request host matches the one specified in the OCI configuration. Signed-off-by: Grégoire Payen de La Garanderie <gregoire.payen.de.la.garanderie@intel.com>
This commit is contained in:
committed by
Ashutosh Narkar
parent
92d631455f
commit
d5265896de
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user