Skip to content
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

Conversation

manan-pancholi
Copy link

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 class BlockPublicAccess set to true. However if some properties are set to false during initialization, then all remaining properties are also set to false. Reason for this is because the unspecified properties are treated as undefined, which evaluates to false. This causes an inconsistent behavior and leads to confusion.

Description of changes

Inside the constructor of BlockPublicAccess class in aws-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 to true. This will create a consistent default for those properties to true.

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

@github-actions github-actions bot added beginning-contributor [Pilot] contributed between 0-2 PRs to the CDK bug This issue is a bug. effort/small Small work item – less than a day of effort p2 labels Jan 17, 2025
@aws-cdk-automation aws-cdk-automation requested a review from a team January 17, 2025 22:57
Copy link
Collaborator

@aws-cdk-automation aws-cdk-automation left a 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.

@manan-pancholi manan-pancholi changed the title chore(aws-s3): default BlockPublicAccess class properties to true chore(s3): default BlockPublicAccess class properties to true Jan 17, 2025
@aws-cdk-automation aws-cdk-automation dismissed their stale review January 17, 2025 23:06

✅ Updated pull request passes all PRLinter validations. Dismissing previous PRLinter review.

@aws-cdk-automation aws-cdk-automation added the pr/needs-community-review This PR needs a review from a Trusted Community Member or Core Team Member. label Jan 17, 2025
Copy link
Contributor

@lpizzinidev lpizzinidev left a 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:

  1. I think the PR should be classified as a fix and an integration test should be created/updated to cover the scenario.
  2. More importantly, I assume this could change the visibility of deployed buckets without users noticing. If so, a feature flag is needed.

@manan-pancholi
Copy link
Author

Thanks @lpizzinidev for reviewing the change. I'll make the suggested changes and send out a revision.

@manan-pancholi manan-pancholi changed the title chore(s3): default BlockPublicAccess class properties to true fix(s3): default BlockPublicAccess class properties to true Jan 22, 2025
@manan-pancholi manan-pancholi changed the title fix(s3): default BlockPublicAccess class properties to true fix(s3): default BlockPublicAccess class properties to true (under feature flag) Jan 22, 2025
@aws-cdk-automation aws-cdk-automation removed the pr/needs-community-review This PR needs a review from a Trusted Community Member or Core Team Member. label Jan 22, 2025
Copy link
Contributor

@lpizzinidev lpizzinidev left a 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.

this.blockPublicPolicy = options.blockPublicPolicy;
this.ignorePublicAcls = options.ignorePublicAcls;
this.restrictPublicBuckets = options.restrictPublicBuckets;
this.blockPublicAcls = options.blockPublicAcls ?? true;
Copy link
Contributor

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;

Copy link
Author

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.

@aws-cdk-automation
Copy link
Collaborator

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.

Copy link
Contributor

@gracelu0 gracelu0 left a 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) {
Copy link
Contributor

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;
}

Copy link
Author

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.

Copy link
Author

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', {
Copy link
Contributor

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.

Copy link

codecov bot commented Jan 30, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 80.83%. Comparing base (bc82f57) to head (25436a4).
Report is 17 commits behind head on main.

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           
Flag Coverage Δ
suite.unit 80.83% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
packages/aws-cdk 79.57% <ø> (ø)
packages/aws-cdk-lib/core 82.20% <ø> (ø)

@aws-cdk-automation
Copy link
Collaborator

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
@aws-cdk-automation
Copy link
Collaborator

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.

@aws-cdk-automation
Copy link
Collaborator

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.

@aws-cdk-automation
Copy link
Collaborator

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.

@aws-cdk-automation
Copy link
Collaborator

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.

@mergify mergify bot dismissed gracelu0’s stale review February 6, 2025 11:41

Pull request has been modified.

@QuantumNeuralCoder QuantumNeuralCoder self-assigned this Feb 6, 2025
@@ -970,6 +970,34 @@ describe('bucket', () => {
});
});

test('unspecified blockPublicAccess properties should default to true', () => {
Copy link
Contributor

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;
Copy link
Contributor

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,
      }),
    });

Copy link
Author

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.

Copy link
Contributor

@QuantumNeuralCoder QuantumNeuralCoder left a 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.

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\`.
Copy link
Contributor

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', {
Copy link
Contributor

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.

Copy link
Contributor

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;
Copy link
Contributor

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.

@aws-cdk-automation
Copy link
Collaborator

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.

@mergify mergify bot dismissed QuantumNeuralCoder’s stale review February 24, 2025 17:52

Pull request has been modified.

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • CodeBuild project: AutoBuildv2Project1C6BFA3F-wQm2hXv2jqQv
  • Commit ID: c69b118
  • Result: FAILED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@manan-pancholi
Copy link
Author

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 BlockPublicAccess class. The fix for the original issue must be implemented in a different way, and I suspect will not be as straightforward as we originally anticipated. Considering this, I am closing this request. I will create a new one if I get enough bandwidth to work on this again.

@manan-pancholi manan-pancholi deleted the default-block-public-access-properties-to-true branch February 24, 2025 19:38
Copy link

Comments on closed issues and PRs are hard for our team to see.
If you need help, please open a new issue that references this one.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 24, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
beginning-contributor [Pilot] contributed between 0-2 PRs to the CDK bug This issue is a bug. effort/small Small work item – less than a day of effort p2
Projects
None yet
Development

Successfully merging this pull request may close these issues.

aws-s3: blockPublicAccess has a counterintuitive behaviour
6 participants