mirror of
https://github.com/minio/minio.git
synced 2025-01-25 21:53:16 -05:00
fix: check post policy like AWS S3 (#18074)
This commit is contained in:
parent
ac3a19138a
commit
6dec60b6e6
@ -598,6 +598,8 @@ func newPostRequestV2(endPoint, bucketName, objectName string, accessKey, secret
|
|||||||
"key": objectName + "/${filename}",
|
"key": objectName + "/${filename}",
|
||||||
"policy": encodedPolicy,
|
"policy": encodedPolicy,
|
||||||
"signature": signature,
|
"signature": signature,
|
||||||
|
"X-Amz-Ignore-signature": "",
|
||||||
|
"X-Amz-Ignore-AWSAccessKeyId": "",
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the multipart form.
|
// Create the multipart form.
|
||||||
|
@ -30,7 +30,9 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/bcicen/jstream"
|
"github.com/bcicen/jstream"
|
||||||
|
"github.com/minio/minio-go/v7/pkg/encrypt"
|
||||||
"github.com/minio/minio-go/v7/pkg/set"
|
"github.com/minio/minio-go/v7/pkg/set"
|
||||||
|
xhttp "github.com/minio/minio/internal/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
// startWithConds - map which indicates if a given condition supports starts-with policy operator
|
// startWithConds - map which indicates if a given condition supports starts-with policy operator
|
||||||
@ -51,6 +53,18 @@ var startsWithConds = map[string]bool{
|
|||||||
"$x-amz-date": false,
|
"$x-amz-date": false,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var postPolicyIgnoreKeys = map[string]bool{
|
||||||
|
"Policy": true,
|
||||||
|
xhttp.AmzSignature: true,
|
||||||
|
xhttp.ContentEncoding: true,
|
||||||
|
http.CanonicalHeaderKey(xhttp.AmzChecksumAlgo): true,
|
||||||
|
http.CanonicalHeaderKey(xhttp.AmzChecksumCRC32): true,
|
||||||
|
http.CanonicalHeaderKey(xhttp.AmzChecksumCRC32C): true,
|
||||||
|
http.CanonicalHeaderKey(xhttp.AmzChecksumSHA1): true,
|
||||||
|
http.CanonicalHeaderKey(xhttp.AmzChecksumSHA256): true,
|
||||||
|
http.CanonicalHeaderKey(xhttp.AmzChecksumMode): true,
|
||||||
|
}
|
||||||
|
|
||||||
// Add policy conditionals.
|
// Add policy conditionals.
|
||||||
const (
|
const (
|
||||||
policyCondEqual = "eq"
|
policyCondEqual = "eq"
|
||||||
@ -265,6 +279,22 @@ func checkPostPolicy(formValues http.Header, postPolicyForm PostPolicyForm) erro
|
|||||||
if !postPolicyForm.Expiration.After(UTCNow()) {
|
if !postPolicyForm.Expiration.After(UTCNow()) {
|
||||||
return fmt.Errorf("Invalid according to Policy: Policy expired")
|
return fmt.Errorf("Invalid according to Policy: Policy expired")
|
||||||
}
|
}
|
||||||
|
// check all formValues appear in postPolicyForm or return error. #https://github.com/minio/minio/issues/17391
|
||||||
|
checkHeader := map[string][]string{}
|
||||||
|
ignoreKeys := map[string]bool{}
|
||||||
|
for key, value := range formValues {
|
||||||
|
switch {
|
||||||
|
case ignoreKeys[key], postPolicyIgnoreKeys[key], strings.HasPrefix(key, encrypt.SseGenericHeader):
|
||||||
|
continue
|
||||||
|
case strings.HasPrefix(key, "X-Amz-Ignore-"):
|
||||||
|
ignoreKey := strings.Replace(key, "X-Amz-Ignore-", "", 1)
|
||||||
|
ignoreKeys[ignoreKey] = true
|
||||||
|
// if it have already
|
||||||
|
delete(checkHeader, ignoreKey)
|
||||||
|
default:
|
||||||
|
checkHeader[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
// map to store the metadata
|
// map to store the metadata
|
||||||
metaMap := make(map[string]string)
|
metaMap := make(map[string]string)
|
||||||
for _, policy := range postPolicyForm.Conditions.Policies {
|
for _, policy := range postPolicyForm.Conditions.Policies {
|
||||||
@ -292,6 +322,10 @@ func checkPostPolicy(formValues http.Header, postPolicyForm PostPolicyForm) erro
|
|||||||
formCanonicalName := http.CanonicalHeaderKey(strings.TrimPrefix(policy.Key, "$"))
|
formCanonicalName := http.CanonicalHeaderKey(strings.TrimPrefix(policy.Key, "$"))
|
||||||
// Operator for the current policy condition
|
// Operator for the current policy condition
|
||||||
op := policy.Operator
|
op := policy.Operator
|
||||||
|
// Multiple values should not occur
|
||||||
|
if len(checkHeader[formCanonicalName]) >= 2 {
|
||||||
|
return fmt.Errorf("Invalid according to Policy: Policy Condition failed: [%s, %s, %s]. FormValues have multiple values: [%s]", op, policy.Key, policy.Value, strings.Join(checkHeader[formCanonicalName], ", "))
|
||||||
|
}
|
||||||
// If the current policy condition is known
|
// If the current policy condition is known
|
||||||
if startsWithSupported, condFound := startsWithConds[policy.Key]; condFound {
|
if startsWithSupported, condFound := startsWithConds[policy.Key]; condFound {
|
||||||
// Check if the current condition supports starts-with operator
|
// Check if the current condition supports starts-with operator
|
||||||
@ -311,6 +345,15 @@ func checkPostPolicy(formValues http.Header, postPolicyForm PostPolicyForm) erro
|
|||||||
return fmt.Errorf("Invalid according to Policy: Policy Condition failed: [%s, %s, %s]", op, policy.Key, policy.Value)
|
return fmt.Errorf("Invalid according to Policy: Policy Condition failed: [%s, %s, %s]", op, policy.Key, policy.Value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
delete(checkHeader, formCanonicalName)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(checkHeader) != 0 {
|
||||||
|
logKeys := make([]string, 0, len(checkHeader))
|
||||||
|
for key := range checkHeader {
|
||||||
|
logKeys = append(logKeys, key)
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Each form field that you specify in a form (except %s) must appear in the list of conditions.", strings.Join(logKeys, ", "))
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
Loading…
x
Reference in New Issue
Block a user