-
Notifications
You must be signed in to change notification settings - Fork 4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(cloudfront): bucket policy for Origin Access Identities is overly permissive #13087
Conversation
… permissive For both `CloudFrontWebDistribution` and `Distribution`, if an origin access identity (OAI) is used to access a S3 bucket origin, the default `bucket.grantRead()` method is used to grant read access to the bucket for the OAI. `grantRead` will create a statement in the bucket policy that grants: `s3:GetObject*`, `s3:GetBucket*`, and `s3:List*` to the OAI. The (official documentation)[https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html] in the developer guide states that to allow the OAI to read objects in the bucket, only `s3:GetObject` is necessary. The impact of the additional permissions is that if a user navigates to the root of the distribution (e.g., https://d12345abcdef.cloudfront.net/) *AND* no default root object (e.g., index.html) is set for the distribution, the user will receive an XML list of the objects in the bucket. This is likely undesired behavior, and potential information leakage. This same policy has been the behavior for OAI + S3 buckets since the first introduction of the `CloudFrontWebDistribution` construct years ago. However, the `CloudFrontWebDistribution` also always defaults the root object to 'index.html' (see #3486 for discussion on that). The side-effect of this is that unless the user selects to use an OAI and overrides the default root object to an empty string, visiting the root will result either in valid content or an AccessDenied message. However, since the `Distribution` constructs do *not* default the root object, exposing the bucket index becomes much more likely. This change restricts the permissions granted to the OAI user to just the necessary `s3:GetObject` permissions. fixes #13086 --- **NOTE:** This PR corrects the behavior without introducing a new feature flag. Any customers who rely on the bucket listing behavior would be broken by this change. However, I anticipate that represents a very small minority, versus the number of customers who may accidentally expose their bucket contents. I would very much like to have a discussion about whether this is the correct choice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! I agree with you that I don't think we need a feature flag for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feature flag is definitely the safest option here. If we feel that customers are unlikely to depend on this behaviour, it might be prudent to skip this.
Could we at least provide an option on the Distribution
construct for users to restore the old behaviour?
@@ -79,7 +80,16 @@ class S3BucketOrigin extends cloudfront.OriginBase { | |||
this.originAccessIdentity = new cloudfront.OriginAccessIdentity(oaiScope, oaiId, { | |||
comment: `Identity for ${options.originId}`, | |||
}); | |||
this.bucket.grantRead(this.originAccessIdentity); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't there a grant() API on bucket that takes a list of actions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a private
one:
https://github.com/aws/aws-cdk/blob/master/packages/@aws-cdk/aws-s3/lib/bucket.ts#L716
I briefly toyed with the idea of adding a grantReadObject
method, but felt it was a bit niche.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a common pattern for constructs to expose a grant(grantee, ...actions)
API for such niche use cases.
I'd rather not, unless we get significant pushback. Exposing the bucket contents at the distribution root doesn't seem like a typically-desirable behavior, and there's a reasonable workaround. // Before - Does the bucket listing by default
const bucket = new s3.Bucket(this, 'Bucket');
const s3Origin = new origins.S3Origin(this, 'S3Origin', { bucket });
// After - Customers who want to intentionally have the bucket listing
const bucket = new s3.Bucket(this, 'Bucket');
const originAccessIdentity = new cloudfront.OriginAccessIdentity(this, 'OAI');
bucket.grantRead(originAccessIdentity);
const s3Origin = new origins.S3Origin(this, 'S3Origin', { bucket, originAccessIdentity }); |
Thank you for contributing! Your pull request will be updated from master and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
Thank you for contributing! Your pull request will be updated from master and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
… permissive (aws#13087) For both `CloudFrontWebDistribution` and `Distribution`, if an origin access identity (OAI) is used to access a S3 bucket origin, the default `bucket.grantRead()` method is used to grant read access to the bucket for the OAI. `grantRead` will create a statement in the bucket policy that grants: `s3:GetObject*`, `s3:GetBucket*`, and `s3:List*` to the OAI. The [official documentation](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html) in the developer guide states that to allow the OAI to read objects in the bucket, only `s3:GetObject` is necessary. The impact of the additional permissions is that if a user navigates to the root of the distribution (e.g., https://d12345abcdef.cloudfront.net/) *AND* no default root object (e.g., index.html) is set for the distribution, the user will receive an XML list of the objects in the bucket. This is likely undesired behavior. This same policy has been the behavior for OAI + S3 buckets since the first introduction of the `CloudFrontWebDistribution` construct years ago. However, the `CloudFrontWebDistribution` also always defaults the root object to 'index.html' (see aws#3486 for discussion on that). The side-effect of this is that unless the user selects to use an OAI and overrides the default root object to an empty string, visiting the root will result either in valid content or an AccessDenied message. However, since the `Distribution` constructs do *not* default the root object, exposing the bucket index becomes much more likely. This change restricts the permissions granted to the OAI user to just the necessary `s3:GetObject` permissions. fixes aws#13086 --- **NOTE:** This PR corrects the behavior without introducing a new feature flag. Any customers who rely on the bucket listing behavior would be broken by this change. However, I anticipate that represents a very small minority, versus the number of customers who may accidentally expose their bucket contents. I would very much like to have a discussion about whether this is the correct choice. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
… permissive (#13087) For both `CloudFrontWebDistribution` and `Distribution`, if an origin access identity (OAI) is used to access a S3 bucket origin, the default `bucket.grantRead()` method is used to grant read access to the bucket for the OAI. `grantRead` will create a statement in the bucket policy that grants: `s3:GetObject*`, `s3:GetBucket*`, and `s3:List*` to the OAI. The [official documentation](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html) in the developer guide states that to allow the OAI to read objects in the bucket, only `s3:GetObject` is necessary. The impact of the additional permissions is that if a user navigates to the root of the distribution (e.g., https://d12345abcdef.cloudfront.net/) *AND* no default root object (e.g., index.html) is set for the distribution, the user will receive an XML list of the objects in the bucket. This is likely undesired behavior. This same policy has been the behavior for OAI + S3 buckets since the first introduction of the `CloudFrontWebDistribution` construct years ago. However, the `CloudFrontWebDistribution` also always defaults the root object to 'index.html' (see #3486 for discussion on that). The side-effect of this is that unless the user selects to use an OAI and overrides the default root object to an empty string, visiting the root will result either in valid content or an AccessDenied message. However, since the `Distribution` constructs do *not* default the root object, exposing the bucket index becomes much more likely. This change restricts the permissions granted to the OAI user to just the necessary `s3:GetObject` permissions. fixes #13086 --- **NOTE:** This PR corrects the behavior without introducing a new feature flag. Any customers who rely on the bucket listing behavior would be broken by this change. However, I anticipate that represents a very small minority, versus the number of customers who may accidentally expose their bucket contents. I would very much like to have a discussion about whether this is the correct choice. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
For both
CloudFrontWebDistribution
andDistribution
, if an origin accessidentity (OAI) is used to access a S3 bucket origin, the default
bucket.grantRead()
method is used to grant read access to the bucket for theOAI.
grantRead
will create a statement in the bucket policy that grants:s3:GetObject*
,s3:GetBucket*
, ands3:List*
to the OAI.
The official documentation in the developer guide
states that to allow the OAI to read objects in the bucket, only
s3:GetObject
is necessary.
The impact of the additional permissions is that if a user navigates to the root
of the distribution (e.g., https://d12345abcdef.cloudfront.net/) AND no default
root object (e.g., index.html) is set for the distribution, the user will receive
an XML list of the objects in the bucket. This is likely undesired behavior.
This same policy has been the behavior for OAI + S3 buckets since the first
introduction of the
CloudFrontWebDistribution
construct years ago. However,the
CloudFrontWebDistribution
also always defaults the root object to'index.html' (see #3486 for discussion on that). The side-effect of this is
that unless the user selects to use an OAI and overrides the default root object
to an empty string, visiting the root will result either in valid content or an
AccessDenied message.
However, since the
Distribution
constructs do not default the root object,exposing the bucket index becomes much more likely.
This change restricts the permissions granted to the OAI user to just the
necessary
s3:GetObject
permissions.fixes #13086
NOTE: This PR corrects the behavior without introducing a new feature flag.
Any customers who rely on the bucket listing behavior would be broken by this
change. However, I anticipate that represents a very small minority, versus the
number of customers who may accidentally expose their bucket contents. I would
very much like to have a discussion about whether this is the correct choice.
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license