mirror of
https://github.com/minio/minio.git
synced 2025-11-09 21:49:46 -05:00
SignatureV4 validation with Metadata in the presignedUrl (#5894)
The `X-Amz-Meta-`/`X-Minio-Meta-` will now be recognized in query string also. Fixes #5857 #5950
This commit is contained in:
committed by
kannappanr
parent
c9bc7e47b9
commit
44865596db
@@ -114,40 +114,54 @@ var userMetadataKeyPrefixes = []string{
|
||||
"X-Minio-Meta-",
|
||||
}
|
||||
|
||||
// extractMetadataFromHeader extracts metadata from HTTP header.
|
||||
func extractMetadataFromHeader(ctx context.Context, header http.Header) (map[string]string, error) {
|
||||
if header == nil {
|
||||
logger.LogIf(ctx, errInvalidArgument)
|
||||
return nil, errInvalidArgument
|
||||
// extractMetadata extracts metadata from HTTP header and HTTP queryString.
|
||||
func extractMetadata(ctx context.Context, r *http.Request) (metadata map[string]string, err error) {
|
||||
query := r.URL.Query()
|
||||
header := r.Header
|
||||
metadata = make(map[string]string)
|
||||
// Extract all query values.
|
||||
err = extractMetadataFromMap(ctx, query, metadata)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
metadata := make(map[string]string)
|
||||
|
||||
// Extract all header values.
|
||||
err = extractMetadataFromMap(ctx, header, metadata)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Success.
|
||||
return metadata, nil
|
||||
}
|
||||
|
||||
// extractMetadata extracts metadata from map values.
|
||||
func extractMetadataFromMap(ctx context.Context, v map[string][]string, m map[string]string) error {
|
||||
if v == nil {
|
||||
logger.LogIf(ctx, errInvalidArgument)
|
||||
return errInvalidArgument
|
||||
}
|
||||
// Save all supported headers.
|
||||
for _, supportedHeader := range supportedHeaders {
|
||||
canonicalHeader := http.CanonicalHeaderKey(supportedHeader)
|
||||
// HTTP headers are case insensitive, look for both canonical
|
||||
// and non canonical entries.
|
||||
if _, ok := header[canonicalHeader]; ok {
|
||||
metadata[supportedHeader] = header.Get(canonicalHeader)
|
||||
} else if _, ok := header[supportedHeader]; ok {
|
||||
metadata[supportedHeader] = header.Get(supportedHeader)
|
||||
if value, ok := v[http.CanonicalHeaderKey(supportedHeader)]; ok {
|
||||
m[supportedHeader] = value[0]
|
||||
} else if value, ok := v[supportedHeader]; ok {
|
||||
m[supportedHeader] = value[0]
|
||||
}
|
||||
}
|
||||
|
||||
// Go through all other headers for any additional headers that needs to be saved.
|
||||
for key := range header {
|
||||
if key != http.CanonicalHeaderKey(key) {
|
||||
logger.LogIf(ctx, errInvalidArgument)
|
||||
return nil, errInvalidArgument
|
||||
}
|
||||
for key := range v {
|
||||
for _, prefix := range userMetadataKeyPrefixes {
|
||||
if strings.HasPrefix(key, prefix) {
|
||||
metadata[key] = header.Get(key)
|
||||
if !strings.HasPrefix(strings.ToLower(key), strings.ToLower(prefix)) {
|
||||
continue
|
||||
}
|
||||
value, ok := v[key]
|
||||
if ok {
|
||||
m[key] = value[0]
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return metadata, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// The Query string for the redirect URL the client is
|
||||
|
||||
Reference in New Issue
Block a user