[#339] v4: Don't duplicate content-length as signed header
Some checks failed
/ DCO (pull_request) Successful in 2m35s
/ Vulncheck (pull_request) Successful in 2m46s
/ Builds (pull_request) Successful in 1m54s
/ Lint (pull_request) Successful in 3m10s
/ Tests (pull_request) Successful in 1m56s
/ Vulncheck (push) Successful in 1m17s
/ Builds (push) Has been cancelled
/ Lint (push) Has been cancelled
/ Tests (push) Has been cancelled
Some checks failed
/ DCO (pull_request) Successful in 2m35s
/ Vulncheck (pull_request) Successful in 2m46s
/ Builds (pull_request) Successful in 1m54s
/ Lint (pull_request) Successful in 3m10s
/ Tests (pull_request) Successful in 1m56s
/ Vulncheck (push) Successful in 1m17s
/ Builds (push) Has been cancelled
/ Lint (push) Has been cancelled
/ Tests (push) Has been cancelled
Signed-off-by: Denis Kirillov <d.kirillov@yadro.com>
This commit is contained in:
parent
11c1a86404
commit
9395b5f39d
3 changed files with 54 additions and 10 deletions
|
@ -139,6 +139,45 @@ Testing with the {sdk-java}
|
|||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestSignatureV4(t *testing.T) {
|
||||
signer := v4.NewSigner(func(options *v4.SignerOptions) {
|
||||
options.DisableURIPathEscaping = true
|
||||
options.Logger = zaptest.NewLogger(t)
|
||||
options.LogSigning = true
|
||||
})
|
||||
|
||||
creds := aws.Credentials{
|
||||
AccessKeyID: "9CBEGH8T9XfLin2pg7LG8ZxBH1PnZc1yoioViKngrUnu0CbC2mcjpcw9t4Y7AS6zsF5cJGkDhXAx5hxFDKwfZzgj7",
|
||||
SecretAccessKey: "8742218da7f905de24f633f44efe02f82c6d2a317ed6f99592627215d17816e3",
|
||||
}
|
||||
|
||||
bodyStr := `tmp2
|
||||
`
|
||||
body := bytes.NewBufferString(bodyStr)
|
||||
|
||||
req, err := http.NewRequest("PUT", "http://localhost:8084/main/tmp2", body)
|
||||
require.NoError(t, err)
|
||||
req.Header.Set("Authorization", "AWS4-HMAC-SHA256 Credential=9CBEGH8T9XfLin2pg7LG8ZxBH1PnZc1yoioViKngrUnu0CbC2mcjpcw9t4Y7AS6zsF5cJGkDhXAx5hxFDKwfZzgj7/20241210/ru/s3/aws4_request, SignedHeaders=content-md5;host;x-amz-content-sha256;x-amz-date, Signature=945664a5bccfd37a1167ca5e718e2b883f68a7ccf7f1044768e7fe58b737b7ed")
|
||||
req.Header.Set("Content-Length", "5")
|
||||
req.Header.Set("User-Agent", "aws-cli/2.13.2 Python/3.11.4 Linux/6.4.5-x64v1-xanmod1 exe/x86_64.debian.11 prompt/off command/s3api.put-object")
|
||||
req.Header.Set("Content-MD5", "DstU4KxdzBj5jTGltfyqgA==")
|
||||
req.Header.Set("Expect", "101-continue")
|
||||
req.Header.Set("X-Amz-Content-Sha256", "1f9b7417ee5445c41dbe904c3651eb0ba1c12fecff16c1bccd8df3db6e390b5f")
|
||||
req.Header.Set("X-Amz-Date", "20241210T114611Z")
|
||||
|
||||
service := "s3"
|
||||
region := "ru"
|
||||
signature := "945664a5bccfd37a1167ca5e718e2b883f68a7ccf7f1044768e7fe58b737b7ed"
|
||||
signingTime, err := time.Parse("20060102T150405Z", "20241210T114611Z")
|
||||
require.NoError(t, err)
|
||||
cloned := cloneRequest(req, &AuthHeader{SignedFields: []string{"content-md5", "host", "x-amz-content-sha256", "x-amz-date"}})
|
||||
|
||||
err = signer.SignHTTP(cloned.Context(), creds, cloned, "1f9b7417ee5445c41dbe904c3651eb0ba1c12fecff16c1bccd8df3db6e390b5f", service, region, signingTime)
|
||||
require.NoError(t, err)
|
||||
signatureComputed := NewRegexpMatcher(AuthorizationFieldRegexp).GetSubmatches(cloned.Header.Get(AuthorizationHdr))["v4_signature"]
|
||||
require.Equal(t, signature, signatureComputed, "signature mismatched")
|
||||
}
|
||||
|
||||
func TestCheckFormatContentSHA256(t *testing.T) {
|
||||
defaultErr := errors.GetAPIError(errors.ErrContentSHA256Mismatch)
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// This is https://github.com/aws/aws-sdk-go-v2/blob/a2b751d1ba71f59175a41f9cae5f159f1044360f/aws/signer/v4/v4.go
|
||||
// with changes:
|
||||
// * using different headers for sign/presign
|
||||
// * don't duplicate content-length as signed header
|
||||
// * use copy of smithy-go encoding/httpbinding package
|
||||
// * use zap.Logger instead of smithy-go/logging
|
||||
|
||||
|
@ -54,7 +55,6 @@ import (
|
|||
"net/textproto"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
@ -440,20 +440,20 @@ func (s *httpSigner) buildCanonicalHeaders(host string, rule v4Internal.Rule, he
|
|||
headers = append(headers, hostHeader)
|
||||
signed[hostHeader] = append(signed[hostHeader], host)
|
||||
|
||||
const contentLengthHeader = "content-length"
|
||||
if length > 0 {
|
||||
headers = append(headers, contentLengthHeader)
|
||||
signed[contentLengthHeader] = append(signed[contentLengthHeader], strconv.FormatInt(length, 10))
|
||||
}
|
||||
//const contentLengthHeader = "content-length"
|
||||
//if length > 0 {
|
||||
// headers = append(headers, contentLengthHeader)
|
||||
// signed[contentLengthHeader] = append(signed[contentLengthHeader], strconv.FormatInt(length, 10))
|
||||
//}
|
||||
|
||||
for k, v := range header {
|
||||
if !rule.IsValid(k) {
|
||||
continue // ignored header
|
||||
}
|
||||
if strings.EqualFold(k, contentLengthHeader) {
|
||||
// prevent signing already handled content-length header.
|
||||
continue
|
||||
}
|
||||
//if strings.EqualFold(k, contentLengthHeader) {
|
||||
// // prevent signing already handled content-length header.
|
||||
// continue
|
||||
//}
|
||||
|
||||
lowerCaseKey := strings.ToLower(k)
|
||||
if _, ok := signed[lowerCaseKey]; ok {
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
// This is https://github.com/aws/aws-sdk-go-v2/blob/a2b751d1ba71f59175a41f9cae5f159f1044360f/aws/signer/v4/v4_test.go
|
||||
// with changes:
|
||||
// * don't duplicate content-length as signed header
|
||||
|
||||
package v4
|
||||
|
||||
|
@ -61,6 +63,7 @@ func buildRequestWithBodyReader(serviceName, region string, body io.Reader) (*ht
|
|||
|
||||
func TestPresignRequest(t *testing.T) {
|
||||
req, body := buildRequest("dynamodb", "us-east-1", "{}")
|
||||
req.Header.Set("Content-Length", "2")
|
||||
|
||||
query := req.URL.Query()
|
||||
query.Set("X-Amz-Expires", "300")
|
||||
|
@ -113,6 +116,7 @@ func TestPresignRequest(t *testing.T) {
|
|||
func TestPresignBodyWithArrayRequest(t *testing.T) {
|
||||
req, body := buildRequest("dynamodb", "us-east-1", "{}")
|
||||
req.URL.RawQuery = "Foo=z&Foo=o&Foo=m&Foo=a"
|
||||
req.Header.Set("Content-Length", "2")
|
||||
|
||||
query := req.URL.Query()
|
||||
query.Set("X-Amz-Expires", "300")
|
||||
|
@ -164,6 +168,7 @@ func TestPresignBodyWithArrayRequest(t *testing.T) {
|
|||
|
||||
func TestSignRequest(t *testing.T) {
|
||||
req, body := buildRequest("dynamodb", "us-east-1", "{}")
|
||||
req.Header.Set("Content-Length", "2")
|
||||
signer := NewSigner()
|
||||
err := signer.SignHTTP(context.Background(), testCredentials, req, body, "dynamodb", "us-east-1", time.Unix(0, 0))
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in a new issue