From 403475eed4126de3d8aca26e919d2ed46ace76f4 Mon Sep 17 00:00:00 2001 From: auvred <61150013+auvred@users.noreply.github.com> Date: Fri, 7 Jul 2023 16:36:55 +0300 Subject: [PATCH] feat(cloudfront): add denyList to OriginRequestPolicy behaviors (#25767) Added static method `denyList` for * `OriginRequestCookieBehavior` * `OriginRequestHeaderBehavior` * `OriginRequestQueryStringBehavior` Due to recent CloudFormation update: the `allExcept` allowed behavior was added to * [`CookieBehavior`](https://github.com/awsdocs/aws-cloudformation-user-guide/commit/a38f2735de1b0b34a4feac1c7bde47524e0966b5#diff-630d84276f15d7dbe9836107b0c289d8692c9279ae10adacf34344273f28fcecR33) * [`HeaderBehavior`](https://github.com/awsdocs/aws-cloudformation-user-guide/commit/a38f2735de1b0b34a4feac1c7bde47524e0966b5#diff-83c67e21c489d688c4da6943452187182e96e8974f447bd3479044da752fe43bR34) * [`QueryStringBehavior`](https://github.com/awsdocs/aws-cloudformation-user-guide/commit/a38f2735de1b0b34a4feac1c7bde47524e0966b5#diff-96b632ead034b3554fb62969ffa46e799f53a1edfb3cfed5deba5df4d769aab1R34) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../integ-distribution-policies.assets.json | 4 ++-- .../integ-distribution-policies.template.json | 10 ++++++-- .../manifest.json | 2 +- .../tree.json | 18 +++++++++----- .../test/integ.distribution-policies.ts | 2 ++ .../lib/origin-request-policy.ts | 24 +++++++++++++++++++ .../test/origin-request-policy.test.ts | 22 +++++++++++++++++ 7 files changed, 71 insertions(+), 11 deletions(-) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront/test/integ.distribution-policies.js.snapshot/integ-distribution-policies.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront/test/integ.distribution-policies.js.snapshot/integ-distribution-policies.assets.json index e44559b37a911..5b83dcb119527 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront/test/integ.distribution-policies.js.snapshot/integ-distribution-policies.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront/test/integ.distribution-policies.js.snapshot/integ-distribution-policies.assets.json @@ -1,7 +1,7 @@ { "version": "32.0.0", "files": { - "01042f10dd3272da413b201384cdf825a7467030c0db8a2d5bcfe10b45a30ced": { + "17ab10021b77a5b225de54b10a02740bc6d638269786a643726871c66180f980": { "source": { "path": "integ-distribution-policies.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "01042f10dd3272da413b201384cdf825a7467030c0db8a2d5bcfe10b45a30ced.json", + "objectKey": "17ab10021b77a5b225de54b10a02740bc6d638269786a643726871c66180f980.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront/test/integ.distribution-policies.js.snapshot/integ-distribution-policies.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront/test/integ.distribution-policies.js.snapshot/integ-distribution-policies.template.json index ee81b98bb7ab4..68223f68acdef 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront/test/integ.distribution-policies.js.snapshot/integ-distribution-policies.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront/test/integ.distribution-policies.js.snapshot/integ-distribution-policies.template.json @@ -69,7 +69,10 @@ "Properties": { "OriginRequestPolicyConfig": { "CookiesConfig": { - "CookieBehavior": "none" + "CookieBehavior": "whitelist", + "Cookies": [ + "cookie1" + ] }, "HeadersConfig": { "HeaderBehavior": "allViewerAndWhitelistCloudFront", @@ -79,7 +82,10 @@ }, "Name": "ACustomOriginRequestPolicy", "QueryStringsConfig": { - "QueryStringBehavior": "none" + "QueryStringBehavior": "allExcept", + "QueryStrings": [ + "querystringparam" + ] } } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront/test/integ.distribution-policies.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront/test/integ.distribution-policies.js.snapshot/manifest.json index 757a340fd7db4..57c337faa9a04 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront/test/integ.distribution-policies.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront/test/integ.distribution-policies.js.snapshot/manifest.json @@ -17,7 +17,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/01042f10dd3272da413b201384cdf825a7467030c0db8a2d5bcfe10b45a30ced.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/17ab10021b77a5b225de54b10a02740bc6d638269786a643726871c66180f980.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront/test/integ.distribution-policies.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront/test/integ.distribution-policies.js.snapshot/tree.json index 4f286e7bc052b..8edffa12c5022 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront/test/integ.distribution-policies.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront/test/integ.distribution-policies.js.snapshot/tree.json @@ -145,7 +145,10 @@ "originRequestPolicyConfig": { "name": "ACustomOriginRequestPolicy", "cookiesConfig": { - "cookieBehavior": "none" + "cookieBehavior": "whitelist", + "cookies": [ + "cookie1" + ] }, "headersConfig": { "headerBehavior": "allViewerAndWhitelistCloudFront", @@ -154,7 +157,10 @@ ] }, "queryStringsConfig": { - "queryStringBehavior": "none" + "queryStringBehavior": "allExcept", + "queryStrings": [ + "querystringparam" + ] } } } @@ -244,7 +250,7 @@ "path": "integ-distribution-policies/Dist/Origin1", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.2.26" + "version": "10.2.52" } }, "Resource": { @@ -304,7 +310,7 @@ "path": "integ-distribution-policies/Dist-2/Origin1", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.2.26" + "version": "10.2.52" } }, "Resource": { @@ -388,7 +394,7 @@ "path": "DistributionPolicies/DefaultTest/Default", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.2.26" + "version": "10.2.52" } }, "DeployAssert": { @@ -434,7 +440,7 @@ "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.2.26" + "version": "10.2.52" } } }, diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront/test/integ.distribution-policies.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront/test/integ.distribution-policies.ts index 3ee022863c1bd..bfb5e2726633b 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront/test/integ.distribution-policies.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront/test/integ.distribution-policies.ts @@ -31,7 +31,9 @@ const cachePolicyWithRef = new cloudfront.CachePolicy(stack, 'CachePolicyWithRef const originRequestPolicy = new cloudfront.OriginRequestPolicy(stack, 'OriginRequestPolicy', { originRequestPolicyName: 'ACustomOriginRequestPolicy', + cookieBehavior: cloudfront.OriginRequestCookieBehavior.allowList('cookie1'), headerBehavior: cloudfront.OriginRequestHeaderBehavior.all('CloudFront-Forwarded-Proto'), + queryStringBehavior: cloudfront.OriginRequestQueryStringBehavior.denyList('querystringparam'), }); const responseHeadersPolicy = new cloudfront.ResponseHeadersPolicy(stack, 'ResponseHeadersPolicy', { diff --git a/packages/aws-cdk-lib/aws-cloudfront/lib/origin-request-policy.ts b/packages/aws-cdk-lib/aws-cloudfront/lib/origin-request-policy.ts index 324fbacbdd9c8..93878d28a368b 100644 --- a/packages/aws-cdk-lib/aws-cloudfront/lib/origin-request-policy.ts +++ b/packages/aws-cdk-lib/aws-cloudfront/lib/origin-request-policy.ts @@ -138,6 +138,14 @@ export class OriginRequestCookieBehavior { /** All cookies in viewer requests are included in requests that CloudFront sends to the origin. */ public static all() { return new OriginRequestCookieBehavior('all'); } + /** All cookies except the provided `cookies` are included in requests that CloudFront sends to the origin. */ + public static denyList(...cookies: string[]) { + if (cookies.length === 0) { + throw new Error('At least one cookie to deny must be provided'); + } + return new OriginRequestCookieBehavior('allExcept', cookies); + } + /** Only the provided `cookies` are included in requests that CloudFront sends to the origin. */ public static allowList(...cookies: string[]) { if (cookies.length === 0) { @@ -194,6 +202,14 @@ export class OriginRequestHeaderBehavior { return new OriginRequestHeaderBehavior('whitelist', headers); } + /** All headers except the provided `headers` are included in requests that CloudFront sends to the origin. */ + public static denyList(...headers: string[]) { + if (headers.length === 0) { + throw new Error('At least one header to deny must be provided'); + } + return new OriginRequestHeaderBehavior('allExcept', headers); + } + /** The behavior of headers: allow all, none or an allow list. */ public readonly behavior: string; /** The headers for the allow list or the included CloudFront headers, if applicable. */ @@ -227,6 +243,14 @@ export class OriginRequestQueryStringBehavior { return new OriginRequestQueryStringBehavior('whitelist', queryStrings); } + /** All query strings except the provided `queryStrings` are included in requests that CloudFront sends to the origin. */ + public static denyList(...queryStrings: string[]) { + if (queryStrings.length === 0) { + throw new Error('At least one query string to deny must be provided'); + } + return new OriginRequestQueryStringBehavior('allExcept', queryStrings); + } + /** The behavior of query strings -- allow all, none, or only an allow list. */ public readonly behavior: string; /** The query strings to allow, if the behavior is an allow list. */ diff --git a/packages/aws-cdk-lib/aws-cloudfront/test/origin-request-policy.test.ts b/packages/aws-cdk-lib/aws-cloudfront/test/origin-request-policy.test.ts index f8ea37de19ac8..234c406851bfa 100644 --- a/packages/aws-cdk-lib/aws-cloudfront/test/origin-request-policy.test.ts +++ b/packages/aws-cdk-lib/aws-cloudfront/test/origin-request-policy.test.ts @@ -141,6 +141,17 @@ describe.each([ test('allowList() throws if list is empty', () => { expect(() => clazz.allowList()).toThrow(new RegExp(`At least one ${type} to allow must be provided`)); }); + + test('denyList()', () => { + const behavior = clazz.denyList('SESSION_ID', 'secrets'); + + expect(behavior.behavior).toEqual('allExcept'); + expect(items(behavior)).toEqual(['SESSION_ID', 'secrets']); + }); + + test('denyList() throws if list is empty', () => { + expect(() => clazz.denyList()).toThrow(new RegExp(`At least one ${type} to deny must be provided`)); + }); }); describe('HeaderBehavior', () => { @@ -182,4 +193,15 @@ describe('HeaderBehavior', () => { expect(() => { OriginRequestHeaderBehavior.all('X-MyCustomHeader'); }).toThrow(errorMessage); }); }); + + test('denyList()', () => { + const headers = OriginRequestHeaderBehavior.denyList('SESSION_ID', 'secrets'); + + expect(headers.behavior).toEqual('allExcept'); + expect(headers.headers).toEqual(['SESSION_ID', 'secrets']); + }); + + test('denyList() throws if list is empty', () => { + expect(() => OriginRequestHeaderBehavior.denyList()).toThrow(/At least one header to deny must be provided/); + }); });