From 0f1ab16e8fb2a5b77919a9032d8018d0d6138e46 Mon Sep 17 00:00:00 2001 From: Armando Luja Date: Wed, 17 Jul 2024 11:41:10 -0700 Subject: [PATCH] fix: enforce ssl on s3 deployment bucket --- .../resources/rootStackTemplate.json | 47 +++++++++++++++++++ .../root-stack-builder.test.ts.snap | 47 +++++++++++++++++++ .../root-stack-transform.test.ts.snap | 47 +++++++++++++++++++ .../root-stack-builder/root-stack-builder.ts | 22 ++++++++- 4 files changed, 162 insertions(+), 1 deletion(-) diff --git a/packages/amplify-provider-awscloudformation/resources/rootStackTemplate.json b/packages/amplify-provider-awscloudformation/resources/rootStackTemplate.json index 9cffcbd2436..824e122dd48 100644 --- a/packages/amplify-provider-awscloudformation/resources/rootStackTemplate.json +++ b/packages/amplify-provider-awscloudformation/resources/rootStackTemplate.json @@ -26,6 +26,53 @@ } } }, + "DeploymentBucketBlockHTTP": { + "Type": "AWS::S3::BucketPolicy", + "Properties": { + "Bucket": { + "Ref": "DeploymentBucketName" + }, + "PolicyDocument": { + "Statement": [ + { + "Action": "s3:*", + "Effect": "Deny", + "Principal": "*", + "Resource": [ + { + "Fn::Join": [ + "", + [ + "arn:aws:s3:::", + { + "Ref": "DeploymentBucketName" + }, + "/*" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:s3:::", + { + "Ref": "DeploymentBucketName" + } + ] + ] + } + ], + "Condition": { + "Bool": { + "aws:SecureTransport": false + } + } + } + ] + } + } + }, "AuthRole": { "Type": "AWS::IAM::Role", "Properties": { diff --git a/packages/amplify-provider-awscloudformation/src/__tests__/root-stack-builder/__snapshots__/root-stack-builder.test.ts.snap b/packages/amplify-provider-awscloudformation/src/__tests__/root-stack-builder/__snapshots__/root-stack-builder.test.ts.snap index aae597fc838..f42389ce694 100644 --- a/packages/amplify-provider-awscloudformation/src/__tests__/root-stack-builder/__snapshots__/root-stack-builder.test.ts.snap +++ b/packages/amplify-provider-awscloudformation/src/__tests__/root-stack-builder/__snapshots__/root-stack-builder.test.ts.snap @@ -104,6 +104,53 @@ exports[`Check RootStack Template generates root stack Template 1`] = ` "Type": "AWS::S3::Bucket", "UpdateReplacePolicy": "Retain", }, + "DeploymentBucketBlockHTTP": { + "Properties": { + "Bucket": { + "Ref": "DeploymentBucketName", + }, + "PolicyDocument": { + "Statement": [ + { + "Action": "s3:*", + "Condition": { + "Bool": { + "aws:SecureTransport": false, + }, + }, + "Effect": "Deny", + "Principal": "*", + "Resource": [ + { + "Fn::Join": [ + "", + [ + "arn:aws:s3:::", + { + "Ref": "DeploymentBucketName", + }, + "/*", + ], + ], + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:s3:::", + { + "Ref": "DeploymentBucketName", + }, + ], + ], + }, + ], + }, + ], + }, + }, + "Type": "AWS::S3::BucketPolicy", + }, "UnauthRole": { "Properties": { "AssumeRolePolicyDocument": { diff --git a/packages/amplify-provider-awscloudformation/src/__tests__/root-stack-builder/__snapshots__/root-stack-transform.test.ts.snap b/packages/amplify-provider-awscloudformation/src/__tests__/root-stack-builder/__snapshots__/root-stack-transform.test.ts.snap index 8ac23826971..9ce1d17b0c3 100644 --- a/packages/amplify-provider-awscloudformation/src/__tests__/root-stack-builder/__snapshots__/root-stack-transform.test.ts.snap +++ b/packages/amplify-provider-awscloudformation/src/__tests__/root-stack-builder/__snapshots__/root-stack-transform.test.ts.snap @@ -125,6 +125,53 @@ exports[`Root stack template tests Generated root stack template during init 1`] "Type": "AWS::S3::Bucket", "UpdateReplacePolicy": "Retain", }, + "DeploymentBucketBlockHTTP": { + "Properties": { + "Bucket": { + "Ref": "DeploymentBucketName", + }, + "PolicyDocument": { + "Statement": [ + { + "Action": "s3:*", + "Condition": { + "Bool": { + "aws:SecureTransport": false, + }, + }, + "Effect": "Deny", + "Principal": "*", + "Resource": [ + { + "Fn::Join": [ + "", + [ + "arn:aws:s3:::", + { + "Ref": "DeploymentBucketName", + }, + "/*", + ], + ], + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:s3:::", + { + "Ref": "DeploymentBucketName", + }, + ], + ], + }, + ], + }, + ], + }, + }, + "Type": "AWS::S3::BucketPolicy", + }, "UnauthRole": { "Properties": { "AssumeRolePolicyDocument": { diff --git a/packages/amplify-provider-awscloudformation/src/root-stack-builder/root-stack-builder.ts b/packages/amplify-provider-awscloudformation/src/root-stack-builder/root-stack-builder.ts index 12dec774474..2f97d295c9d 100644 --- a/packages/amplify-provider-awscloudformation/src/root-stack-builder/root-stack-builder.ts +++ b/packages/amplify-provider-awscloudformation/src/root-stack-builder/root-stack-builder.ts @@ -90,12 +90,32 @@ export class AmplifyRootStack extends cdk.Stack implements AmplifyRootStackTempl } generateRootStackResources = async (): Promise => { + const bucketName = this._cfnParameterMap.get('DeploymentBucketName').valueAsString; this.deploymentBucket = new s3.CfnBucket(this, 'DeploymentBucket', { - bucketName: this._cfnParameterMap.get('DeploymentBucketName').valueAsString, + bucketName: bucketName, }); this.deploymentBucket.applyRemovalPolicy(cdk.RemovalPolicy.RETAIN); + new s3.CfnBucketPolicy(this, 'DeploymentBucketBlockHTTP', { + bucket: bucketName, + policyDocument: { + Statement: [ + { + Action: 's3:*', + Effect: 'Deny', + Principal: '*', + Resource: [`arn:aws:s3:::${bucketName}/*`, `arn:aws:s3:::${bucketName}`], + Condition: { + Bool: { + 'aws:SecureTransport': false, + }, + }, + }, + ], + }, + }); + this.authRole = new iam.CfnRole(this, 'AuthRole', { roleName: this._cfnParameterMap.get('AuthRoleName').valueAsString, assumeRolePolicyDocument: {