mirror of
https://github.com/minio/minio.git
synced 2024-12-24 06:05:55 -05:00
check if metadata headers/url values are equal with signed headers (#17737)
This commit is contained in:
parent
14ebd82dbd
commit
535f97ba61
@ -260,3 +260,28 @@ func signV4TrimAll(input string) string {
|
||||
// unicode.IsSpace() internally here) to one space and return
|
||||
return strings.Join(strings.Fields(input), " ")
|
||||
}
|
||||
|
||||
// checkMetaHeaders will check if the metadata from header/url is the same with the one from signed headers
|
||||
func checkMetaHeaders(signedHeadersMap http.Header, r *http.Request) APIErrorCode {
|
||||
// check values from http header
|
||||
for k, val := range r.Header {
|
||||
if stringsHasPrefixFold(k, "X-Amz-Meta-") {
|
||||
if signedHeadersMap.Get(k) == val[0] {
|
||||
continue
|
||||
}
|
||||
return ErrUnsignedHeaders
|
||||
}
|
||||
}
|
||||
|
||||
// check values from url, if no http header
|
||||
for k, val := range r.Form {
|
||||
if stringsHasPrefixFold(k, "x-amz-meta-") {
|
||||
if signedHeadersMap.Get(http.CanonicalHeaderKey(k)) == val[0] {
|
||||
continue
|
||||
}
|
||||
return ErrUnsignedHeaders
|
||||
}
|
||||
}
|
||||
|
||||
return ErrNone
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
// Copyright (c) 2015-2023 MinIO, Inc.
|
||||
//
|
||||
// This file is part of MinIO Object Storage stack
|
||||
//
|
||||
@ -339,3 +339,72 @@ func TestGetContentSha256Cksum(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test TestCheckMetaHeaders tests the logic of checkMetaHeaders() function
|
||||
func TestCheckMetaHeaders(t *testing.T) {
|
||||
signedHeadersMap := map[string][]string{
|
||||
"X-Amz-Meta-Test": {"test"},
|
||||
"X-Amz-Meta-Extension": {"png"},
|
||||
"X-Amz-Meta-Name": {"imagepng"},
|
||||
}
|
||||
expectedMetaTest := "test"
|
||||
expectedMetaExtension := "png"
|
||||
expectedMetaName := "imagepng"
|
||||
r, err := http.NewRequest(http.MethodPut, "http://play.min.io:9000", nil)
|
||||
if err != nil {
|
||||
t.Fatal("Unable to create http.Request :", err)
|
||||
}
|
||||
|
||||
// Creating input http header.
|
||||
inputHeader := r.Header
|
||||
inputHeader.Set("X-Amz-Meta-Test", expectedMetaTest)
|
||||
inputHeader.Set("X-Amz-Meta-Extension", expectedMetaExtension)
|
||||
inputHeader.Set("X-Amz-Meta-Name", expectedMetaName)
|
||||
// calling the function being tested.
|
||||
errCode := checkMetaHeaders(signedHeadersMap, r)
|
||||
if errCode != ErrNone {
|
||||
t.Fatalf("Expected the APIErrorCode to be %d, but got %d", ErrNone, errCode)
|
||||
}
|
||||
|
||||
// Add new metadata in inputHeader
|
||||
inputHeader.Set("X-Amz-Meta-Clone", "fail")
|
||||
// calling the function being tested.
|
||||
errCode = checkMetaHeaders(signedHeadersMap, r)
|
||||
if errCode != ErrUnsignedHeaders {
|
||||
t.Fatalf("Expected the APIErrorCode to be %d, but got %d", ErrUnsignedHeaders, errCode)
|
||||
}
|
||||
|
||||
// Delete extra metadata from header to don't affect other test
|
||||
inputHeader.Del("X-Amz-Meta-Clone")
|
||||
// calling the function being tested.
|
||||
errCode = checkMetaHeaders(signedHeadersMap, r)
|
||||
if errCode != ErrNone {
|
||||
t.Fatalf("Expected the APIErrorCode to be %d, but got %d", ErrNone, errCode)
|
||||
}
|
||||
|
||||
// Creating input url values
|
||||
r, err = http.NewRequest(http.MethodPut, "http://play.min.io:9000?x-amz-meta-test=test&x-amz-meta-extension=png&x-amz-meta-name=imagepng", nil)
|
||||
if err != nil {
|
||||
t.Fatal("Unable to create http.Request :", err)
|
||||
}
|
||||
|
||||
r.ParseForm()
|
||||
// calling the function being tested.
|
||||
errCode = checkMetaHeaders(signedHeadersMap, r)
|
||||
if errCode != ErrNone {
|
||||
t.Fatalf("Expected the APIErrorCode to be %d, but got %d", ErrNone, errCode)
|
||||
}
|
||||
|
||||
// Add extra metadata in url values
|
||||
r, err = http.NewRequest(http.MethodPut, "http://play.min.io:9000?x-amz-meta-test=test&x-amz-meta-extension=png&x-amz-meta-name=imagepng&x-amz-meta-clone=fail", nil)
|
||||
if err != nil {
|
||||
t.Fatal("Unable to create http.Request :", err)
|
||||
}
|
||||
|
||||
r.ParseForm()
|
||||
// calling the function being tested.
|
||||
errCode = checkMetaHeaders(signedHeadersMap, r)
|
||||
if errCode != ErrUnsignedHeaders {
|
||||
t.Fatalf("Expected the APIErrorCode to be %d, but got %d", ErrUnsignedHeaders, errCode)
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||
// Copyright (c) 2015-2023 MinIO, Inc.
|
||||
//
|
||||
// This file is part of MinIO Object Storage stack
|
||||
//
|
||||
@ -229,6 +229,12 @@ func doesPresignedSignatureMatch(hashedPayload string, r *http.Request, region s
|
||||
return errCode
|
||||
}
|
||||
|
||||
// Check if the metadata headers are equal with signedheaders
|
||||
errMetaCode := checkMetaHeaders(extractedSignedHeaders, r)
|
||||
if errMetaCode != ErrNone {
|
||||
return errMetaCode
|
||||
}
|
||||
|
||||
// If the host which signed the request is slightly ahead in time (by less than globalMaxSkewTime) the
|
||||
// request should still be allowed.
|
||||
if pSignValues.Date.After(UTCNow().Add(globalMaxSkewTime)) {
|
||||
|
Loading…
Reference in New Issue
Block a user