-
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(s3): default BlockPublicAccess class properties to true (under feature flag) #33001
fix(s3): default BlockPublicAccess class properties to true (under feature flag) #33001
Conversation
… consistent behavior
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.
The pull request linter fails with the following errors:
❌ The title of the pull request should omit 'aws-' from the name of modified packages. Use 's3' instead of 'aws-s3'.
If you believe this pull request should receive an exemption, please comment and provide a justification. A comment requesting an exemption should contain the text Exemption Request
. Additionally, if clarification is needed, add Clarification Request
to a comment.
✅ Updated pull request passes all PRLinter validations. Dismissing previous PRLinter review.
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.
Thanks 👍
A couple of notes:
- I think the PR should be classified as a
fix
and an integration test should be created/updated to cover the scenario. - More importantly, I assume this could change the visibility of deployed buckets without users noticing. If so, a feature flag is needed.
Thanks @lpizzinidev for reviewing the change. I'll make the suggested changes and send out a revision. |
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.
Thanks for the adjustment 👍 Left comments for minor syntax adjustments.
Thanks for the suggestion. Co-authored-by: Luca Pizzini <[email protected]>
Co-authored-by: Luca Pizzini <[email protected]>
Co-authored-by: Luca Pizzini <[email protected]>
this.blockPublicPolicy = options.blockPublicPolicy; | ||
this.ignorePublicAcls = options.ignorePublicAcls; | ||
this.restrictPublicBuckets = options.restrictPublicBuckets; | ||
this.blockPublicAcls = options.blockPublicAcls ?? true; |
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.
nit the docstrings for these don't have a default it looks like
/**
* Whether to block public ACLs
*
* @default true
* @see https://docs.aws.amazon.com/AmazonS3/latest/dev/access-control-block-public-access.html#access-control-block-public-access-options
*/
readonly blockPublicAcls?: boolean;
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.
@aaythapa - Could you please elaborate on your comment? I'm unable to understand the suggested change.
This PR cannot be merged because it has conflicts. Please resolve them. The PR will be considered stale and closed if it remains in an unmergeable state. |
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.
Thanks for working on this!
@@ -1093,10 +1093,10 @@ export class BlockPublicAccess { | |||
public restrictPublicBuckets: boolean | undefined; | |||
|
|||
constructor(options: BlockPublicAccessOptions) { |
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.
These new defaults should be set depending on the feature flag, e.g.:
constructor(options: BlockPublicAccessOptions) {
const defaultToTrue = FeatureFlags.of(this).isEnabled(cxapi.S3_BUCKET_DEFAULT_BLOCK_PUBLIC_ACCESS_PROPERTIES_TO_TRUE);
this.blockPublicAcls = defaultToTrue ? options.blockPublicAcls ?? true : options.blockPublicAcls;
this.blockPublicPolicy = defaultToTrue ? options.blockPublicPolicy ?? true : options.blockPublicPolicy;
this.ignorePublicAcls = defaultToTrue ? options.ignorePublicAcls ?? true : options.ignorePublicAcls;
this.restrictPublicBuckets = defaultToTrue ? options.restrictPublicBuckets ?? true : options.restrictPublicBuckets;
}
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.
Good catch, will update in the next commit.
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.
@gracelu0 - FeatureFlags.of(this)
- I could not use this
because the current context, i.e. class BlockPublicAccess doesn't implement IConstruct
. In my latest commit, I've used a workaround where in I declare a top level variable to represent the feature flag, modify it inside the Bucket
constructor and then use its value inside BlockPublicAccess
class constructor. I know it doesn't look neat, but could not think of a better way. Let me know if you have a better suggestion.
}), | ||
}); | ||
|
||
new IntegTest(app, 'cdk-integ-s3-bucket-block-public-access', { |
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.
could we add an assertion to this test to check that the BucketWithPartialBlockAccess
sets the unspecified properties to true
? From docs it seems like
PUT Bucket ACL and PUT Object ACL calls fail if the specified ACL is public.
PUT Object calls fail if the request includes a public ACL.
PUT Bucket calls fail if the request includes a public ACL.
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #33001 +/- ##
=======================================
Coverage 80.83% 80.83%
=======================================
Files 236 236
Lines 14253 14253
Branches 2490 2490
=======================================
Hits 11522 11522
Misses 2446 2446
Partials 285 285
Flags with carried forward coverage won't be shown. Click here to find out more.
|
This PR cannot be merged because it has conflicts. Please resolve them. The PR will be considered stale and closed if it remains in an unmergeable state. |
4 similar comments
This PR cannot be merged because it has conflicts. Please resolve them. The PR will be considered stale and closed if it remains in an unmergeable state. |
This PR cannot be merged because it has conflicts. Please resolve them. The PR will be considered stale and closed if it remains in an unmergeable state. |
This PR cannot be merged because it has conflicts. Please resolve them. The PR will be considered stale and closed if it remains in an unmergeable state. |
This PR cannot be merged because it has conflicts. Please resolve them. The PR will be considered stale and closed if it remains in an unmergeable state. |
Pull request has been modified.
@@ -970,6 +970,34 @@ describe('bucket', () => { | |||
}); | |||
}); | |||
|
|||
test('unspecified blockPublicAccess properties should default to true', () => { |
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.
The test is failing since this does not take into account the feature flag. Please refactor to something like this.
Note that you will need to create a new bucket since re-using an already created bucket in tests above will fail the test and is not a true test of this feature.
test('featureFlag @aws-cdk/aws-s3:blockPublicAccessPropertiesDefaultToTrue unspecified blockPublicAccess properties should default to true', () => {
// GIVEN
const app = new cdk.App({
context: {
'@aws-cdk/aws-s3:blockPublicAccessPropertiesDefaultToTrue': true,
},
});
// WHEN
const stack = new cdk.Stack(app);
new s3.Bucket(stack, 'MyBucketNewDefaults', {
blockPublicAccess: new s3.BlockPublicAccess({
blockPublicPolicy: false,
restrictPublicBuckets: false,
}),
});
// THEN
Template.fromStack(stack).templateMatches({
'Resources': {
'MyBucketNewDefaultsC1A67BCD': {
'Type': 'AWS::S3::Bucket',
'Properties': {
'PublicAccessBlockConfiguration': {
'BlockPublicAcls': true,
'BlockPublicPolicy': false,
'IgnorePublicAcls': true,
'RestrictPublicBuckets': false,
},
},
'DeletionPolicy': 'Retain',
'UpdateReplacePolicy': 'Retain',
},
},
});
});
this.blockPublicPolicy = options.blockPublicPolicy; | ||
this.ignorePublicAcls = options.ignorePublicAcls; | ||
this.restrictPublicBuckets = options.restrictPublicBuckets; | ||
const defaultToTrue = s3BucketDefaultBlockPublicAccessPropertiesToTrueFeatureFlag; |
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.
This implementation has a problem as revealed when you run the test.
For a test code like below, note the order of call flow of the constructors.
new s3.BlockPublicAccess
is called before
new s3.Bucket()
This leads to defaultToTrue being false regardless of the value in the feature flag.
new s3.Bucket(stack, 'MyBucketNewDefaults', {
blockPublicAccess: new s3.BlockPublicAccess({
blockPublicPolicy: false,
restrictPublicBuckets: false,
}),
});
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.
Thanks for reviewing and pointing this out - I need to update the implementation for feature flag, will send out an updated revision.
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.
Please note the changes requested. Summarily, the implementation has issues and the test doesnt pass. Please take a look.
Pull request has been modified.
When the property value is not specified, then all the 4 member properties (\`blockPublicAcls\`, | ||
\`ignorePublicAcls\`, \`blockPublicPolicy\` and \`restrictPublicBuckets\`) will default to \`true\`. However, in | ||
cases where selected properties are explicitly set to \`false\`, the remaining properties for which no value | ||
was specified will also default to \`false\`. |
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.
default to `true` I believe...
@@ -970,6 +970,34 @@ describe('bucket', () => { | |||
}); | |||
}); | |||
|
|||
test('unspecified blockPublicAccess properties should default to true', () => { | |||
const stack = new cdk.Stack(); | |||
new s3.Bucket(stack, 'MyBucket', { |
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.
Can we create a new bucket please. MyBucket is already being created as a part of other tests and the test might become flaky in future.
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.
I also dont see the feature flag being set in the test. does this work?
@@ -2188,6 +2190,10 @@ export class Bucket extends BucketBase { | |||
// Enhanced CDK Analytics Telemetry | |||
addConstructMetadata(this, props); | |||
|
|||
// Set the S3_BUCKET_DEFAULT_BLOCK_PUBLIC_ACCESS_PROPERTIES_TO_TRUE feature flag | |||
s3BucketDefaultBlockPublicAccessPropertiesToTrueFeatureFlag = FeatureFlags.of(this) | |||
.isEnabled(cxapi.S3_BUCKET_DEFAULT_BLOCK_PUBLIC_ACCESS_PROPERTIES_TO_TRUE) ?? false; |
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.
??false is not required as the api guarantees the return value.
This PR cannot be merged because it has conflicts. Please resolve them. The PR will be considered stale and closed if it remains in an unmergeable state. |
Pull request has been modified.
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
The proposed logic in this PR will not work with a corresponding feature flag. To access the feature flag setting, we need access to the scope, however we cannot get a scope instance inside the |
Comments on closed issues and PRs are hard for our team to see. |
Issue # aws-s3: blockPublicAccess has a counterintuitive behaviour #32811
Closes #32811.
Reason for this change
S3 Bucket construct when initialized without specifying the
blockPublicAccess
property results in all the members of classBlockPublicAccess
set totrue
. However if some properties are set tofalse
during initialization, then all remaining properties are also set tofalse
. Reason for this is because the unspecified properties are treated asundefined
, which evaluates tofalse
. This causes an inconsistent behavior and leads to confusion.Description of changes
Inside the constructor of
BlockPublicAccess
class inaws-s3/lib/bucket.ts
, we use the nullish coalescing operator??
to check if the properties are not explicitly set by the customer. If they are not, then we set them totrue
. This will create a consistent default for those properties totrue
.Description of how you validated changes
Added a unit test to validate the changes.
Checklist
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license