[#656] Don't ignore Expect header in sigv4
All checks were successful
/ DCO (pull_request) Successful in 53s
/ Vulncheck (pull_request) Successful in 1m14s
/ Builds (pull_request) Successful in 1m43s
/ OCI image (pull_request) Successful in 2m15s
/ Lint (pull_request) Successful in 3m17s
/ Tests (pull_request) Successful in 2m51s
/ Vulncheck (push) Successful in 1m5s
/ Builds (push) Successful in 54s
/ OCI image (push) Successful in 2m32s
/ Lint (push) Successful in 2m36s
/ Tests (push) Successful in 1m14s

Signed-off-by: Denis Kirillov <d.kirillov@yadro.com>
This commit is contained in:
Denis Kirillov 2025-03-10 11:55:47 +03:00
parent 079fd20513
commit 1fac8e3ef2
4 changed files with 78 additions and 7 deletions

View file

@ -40,6 +40,9 @@ var (
postPolicyCredentialRegexp = regexp.MustCompile(`(?P<access_key_id>[^/]+)/(?P<date>[^/]+)/(?P<region>[^/]*)/(?P<service>[^/]+)/aws4_request`)
)
// need for tests.
var timeNow = time.Now
type (
Center struct {
reg *RegexpSubmatcher
@ -470,7 +473,7 @@ func (c *Center) checkSign(ctx context.Context, authHeader *AuthHeader, box *acc
}
func checkPresignedDate(authHeader *AuthHeader, signatureDateTime time.Time) error {
now := time.Now()
now := timeNow()
if signatureDateTime.Add(authHeader.Expiration).Before(now) {
return fmt.Errorf("%w: expired: now %s, signature %s", apierr.GetAPIError(apierr.ErrExpiredPresignRequest),
now.Format(time.RFC3339), signatureDateTime.Format(time.RFC3339))

View file

@ -182,6 +182,71 @@ func TestSignatureV4(t *testing.T) {
require.Equal(t, signature, signatureComputed, "signature mismatched")
}
func TestSignExpectHeader(t *testing.T) {
timeNow = func() time.Time {
return time.Date(2025, 3, 10, 11, 0, 0, 0, time.UTC)
}
t.Cleanup(func() {
timeNow = time.Now
})
ctx := context.Background()
key, err := keys.NewPrivateKey()
require.NoError(t, err)
cfg := &cache.Config{
Size: 10,
Lifetime: 24 * time.Hour,
Logger: zaptest.NewLogger(t),
}
gateData := []*accessbox.GateData{{
BearerToken: &bearer.Token{},
GateKey: key.PublicKey(),
}}
accessBox, _, err := accessbox.PackTokens(gateData, []byte("0a85c05b993e7663bdd245aa780569ee8abbdc1d9d9a9e185395ff87dffb0105"), true)
require.NoError(t, err)
data, err := accessBox.Marshal()
require.NoError(t, err)
var obj object.Object
obj.SetPayload(data)
var addr oid.Address
err = addr.DecodeString("2t6v52sJdxN2NV2bFfYnuTSQiYkbcDQ2yMKHfGSsjHiv/HbUvXKFK7meCQWoo1Es3oGSMQFbFK7Np82JVEMbCM48d")
require.NoError(t, err)
frostfs := newFrostFSMock()
frostfs.objects[getAccessKeyID(addr)] = &obj
tknCfg := tokens.Config{
FrostFS: frostfs,
Key: key,
CacheConfig: cfg,
}
creds := tokens.New(tknCfg)
cntr := New(creds, nil, &centerSettingsMock{})
body := bytes.NewBufferString("")
req, err := http.NewRequest("PUT", "http://localhost:8184/test/tmp.txt", body)
require.NoError(t, err)
req.Header.Set("Authorization", "AWS4-HMAC-SHA256 Credential=2t6v52sJdxN2NV2bFfYnuTSQiYkbcDQ2yMKHfGSsjHiv0HbUvXKFK7meCQWoo1Es3oGSMQFbFK7Np82JVEMbCM48d/20250310/us-east-2/s3/aws4_request, SignedHeaders=expect;host;x-amz-content-sha256;x-amz-date, Signature=966bda3d22213ae3f10d82b302041d2fc1c18804e8c02ca7d9bd35b6bcb8c161")
req.Header.Set("Expect", "100-continue")
req.Header.Set("X-Amz-Content-Sha256", UnsignedPayload)
req.Header.Set("X-Amz-Date", "20250310T082808Z")
_, err = cntr.Authenticate(ctx, req)
require.NoError(t, err)
req2, err := http.NewRequest("PUT", "http://localhost:8184/test/tmp.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=2t6v52sJdxN2NV2bFfYnuTSQiYkbcDQ2yMKHfGSsjHiv0HbUvXKFK7meCQWoo1Es3oGSMQFbFK7Np82JVEMbCM48d%2F20250310%2Fru%2Fs3%2Faws4_request&X-Amz-Date=20250310T083436Z&X-Amz-Expires=43200&X-Amz-SignedHeaders=expect%3Bhost&X-Amz-Signature=42c3dbe45842fdfd62d78632e135f5460e3f709ab6b949e257de30168946859b", body)
require.NoError(t, err)
req2.Header.Set("Expect", "100-continue")
_, err = cntr.Authenticate(ctx, req2)
require.NoError(t, err)
}
func TestCheckFormatContentSHA256(t *testing.T) {
defaultErr := errors.GetAPIError(errors.ErrContentSHA256Mismatch)

View file

@ -1,6 +1,7 @@
// This is https://github.com/aws/aws-sdk-go-v2/blob/a2b751d1ba71f59175a41f9cae5f159f1044360f/aws/signer/internal/v4/header.go
// with changes:
// * drop User-Agent header from ignored
// * drop Expect header from ignored
package v4
@ -11,7 +12,7 @@ var IgnoredPresignedHeaders = Rules{
"Authorization": struct{}{},
"User-Agent": struct{}{},
"X-Amzn-Trace-Id": struct{}{},
"Expect": struct{}{},
//"Expect": struct{}{},
},
},
}
@ -24,7 +25,7 @@ var IgnoredHeaders = Rules{
"Authorization": struct{}{},
//"User-Agent": struct{}{},
"X-Amzn-Trace-Id": struct{}{},
"Expect": struct{}{},
//"Expect": struct{}{},
},
},
}

View file

@ -1,4 +1,6 @@
// This is https://github.com/aws/aws-sdk-go-v2/blob/a2b751d1ba71f59175a41f9cae5f159f1044360f/aws/signer/internal/v4/header_test.go
// with changes:
// * drop Expect header from ignored
package v4
@ -41,10 +43,10 @@ func TestIgnoredHeaders(t *testing.T) {
Header string
ExpectIgnored bool
}{
"expect": {
Header: "Expect",
ExpectIgnored: true,
},
//"expect": {
// Header: "Expect",
// ExpectIgnored: true,
//},
"authorization": {
Header: "Authorization",
ExpectIgnored: true,