Skip to content

Commit

Permalink
plugins/rest/aws: Include port in Host header
Browse files Browse the repository at this point in the history
The AWS v4 signing feature for bundle requests would automatically
add a `Host` header by using the URL hostname. This would break for
URLs that specified a port number (eg: https://127.0.0.1:9000/). That
causes issues with sending a valid request.

This commit changes to use the `URL.Host` which will have the full
`host:port` string, when a port was specified.

Fixes: open-policy-agent#2568
Signed-off-by: Patrick East <east.patrick@gmail.com>
  • Loading branch information
patrick-east committed Jul 22, 2020
1 parent 01b6e21 commit 20afe41
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 3 deletions.
6 changes: 3 additions & 3 deletions plugins/rest/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -286,11 +286,11 @@ func signV4(req *http.Request, credService awsCredentialService, theTime time.Ti
dateNow := now.Format("20060102")
iso8601Now := now.Format("20060102T150405Z")

// certain mandatory headers for V4 signing
awsHeaders := map[string]string{
"host": req.URL.Hostname(),
"host": req.URL.Host,
"x-amz-content-sha256": bodyHexHash,
"x-amz-date": iso8601Now}
"x-amz-date": iso8601Now,
}

// the security token header is necessary for ephemeral credentials, e.g. from
// the EC2 metadata service
Expand Down
35 changes: 35 additions & 0 deletions plugins/rest/aws_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,41 @@ func TestV4Signing(t *testing.T) {
assertEq(req.Header.Get("X-Amz-Security-Token"), "MYAWSSECURITYTOKENGOESHERE", t)
}

func TestV4SigningCustomPort(t *testing.T) {
ts := credTestServer{}
ts.start()
defer ts.stop()

cs := &awsMetadataCredentialService{
RoleName: "my_iam_role", // not present
RegionName: "us-east-1",
credServicePath: ts.server.URL + "/latest/meta-data/iam/security-credentials/",
tokenPath: ts.server.URL + "/latest/api/token"}
ts.payload = metadataPayload{
AccessKeyID: "MYAWSACCESSKEYGOESHERE",
SecretAccessKey: "MYAWSSECRETACCESSKEYGOESHERE",
Code: "Success",
Token: "MYAWSSECURITYTOKENGOESHERE",
Expiration: time.Now().UTC().Add(time.Minute * 2)}
req, _ := http.NewRequest("GET", "https://custom.s3.server:9000/bundle.tar.gz", strings.NewReader(""))
err := signV4(req, cs, time.Unix(1556129697, 0))

if err != nil {
t.Error("unexpected error during signing")
}

// expect mandatory headers
assertEq(req.Header.Get("Host"), "custom.s3.server:9000", t)
assertEq(req.Header.Get("Authorization"),
"AWS4-HMAC-SHA256 Credential=MYAWSACCESSKEYGOESHERE/20190424/us-east-1/s3/aws4_request,"+
"SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token,"+
"Signature=765b67c6b136f99d9b769171c9939fc444021f7d17e4fbe6e1ab8b1926713c2b", t)
assertEq(req.Header.Get("X-Amz-Content-Sha256"),
"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", t)
assertEq(req.Header.Get("X-Amz-Date"), "20190424T181457Z", t)
assertEq(req.Header.Get("X-Amz-Security-Token"), "MYAWSSECURITYTOKENGOESHERE", t)
}

// simulate EC2 metadata service
type credTestServer struct {
t *testing.T
Expand Down

0 comments on commit 20afe41

Please sign in to comment.