Add aws:Referer condition key support. (#3641)

This change implements bucket policy enhancements required to restrict access based on HTTP referer.
See https://docs.aws.amazon.com/AmazonS3/latest/dev/example-bucket-policies.html#example-bucket-policies-use-case-4 for more information.

Fixes #3540
This commit is contained in:
Krishnan Parthasarathi
2017-01-30 09:15:11 +05:30
committed by Harshavardhana
parent 69b81af93e
commit b408d0e87d
8 changed files with 181 additions and 42 deletions
+10 -5
View File
@@ -33,7 +33,7 @@ import (
// http://docs.aws.amazon.com/AmazonS3/latest/dev/using-with-s3-actions.html
// Enforces bucket policies for a bucket for a given tatusaction.
func enforceBucketPolicy(bucket string, action string, reqURL *url.URL) (s3Error APIErrorCode) {
func enforceBucketPolicy(bucket, action, resource, referer string, queryParams url.Values) (s3Error APIErrorCode) {
// Verify if bucket actually exists
if err := checkBucketExist(bucket, newObjectLayerFn()); err != nil {
err = errorCause(err)
@@ -57,16 +57,21 @@ func enforceBucketPolicy(bucket string, action string, reqURL *url.URL) (s3Error
}
// Construct resource in 'arn:aws:s3:::examplebucket/object' format.
resource := bucketARNPrefix + strings.TrimSuffix(strings.TrimPrefix(reqURL.Path, "/"), "/")
arn := bucketARNPrefix + strings.TrimSuffix(strings.TrimPrefix(resource, "/"), "/")
// Get conditions for policy verification.
conditionKeyMap := make(map[string]set.StringSet)
for queryParam := range reqURL.Query() {
conditionKeyMap[queryParam] = set.CreateStringSet(reqURL.Query().Get(queryParam))
for queryParam := range queryParams {
conditionKeyMap[queryParam] = set.CreateStringSet(queryParams.Get(queryParam))
}
// Add request referer to conditionKeyMap if present.
if referer != "" {
conditionKeyMap["referer"] = set.CreateStringSet(referer)
}
// Validate action, resource and conditions with current policy statements.
if !bucketPolicyEvalStatements(action, resource, conditionKeyMap, policy.Statements) {
if !bucketPolicyEvalStatements(action, arn, conditionKeyMap, policy.Statements) {
return ErrAccessDenied
}
return ErrNone