From 0f257d82af73b7475ecda7ca51c4dd371cc3975f Mon Sep 17 00:00:00 2001 From: Daniel Van Der Ploeg Date: Wed, 14 Feb 2024 13:19:34 +1030 Subject: [PATCH 1/3] feat: change rate limit bypass to global bypass --- packages/graphql-mesh-server/lib/fargate.ts | 50 +++++++++++-------- .../lib/graphql-mesh-server.ts | 4 +- 2 files changed, 31 insertions(+), 23 deletions(-) diff --git a/packages/graphql-mesh-server/lib/fargate.ts b/packages/graphql-mesh-server/lib/fargate.ts index 17dc9e89..d015a7da 100644 --- a/packages/graphql-mesh-server/lib/fargate.ts +++ b/packages/graphql-mesh-server/lib/fargate.ts @@ -97,9 +97,14 @@ export interface MeshServiceProps { */ rateLimitPriority?: number; /** - * List of IPv4 addresses that can bypass rate limiting. + * The waf allowed ip rule priority. + * Defaults to 2 + */ + allowedIpPriority?: number; + /** + * List of IPv4 addresses that can bypass all WAF block lists. */ - rateLimitBypassList?: string[]; + allowedIps?: string[]; /** * Pass custom cpu scaling steps * Default value: @@ -253,8 +258,8 @@ export class MeshService extends Construct { this.service = fargateService.service; this.loadBalancer = fargateService.loadBalancer; - const rateLimitBypassList = new CfnIPSet(this, "RateLimitBypassList", { - addresses: props.rateLimitBypassList || [], + const allowedIpList = new CfnIPSet(this, "allowList", { + addresses: props.allowedIps || [], ipAddressVersion: "IPV4", scope: "REGIONAL", description: "List of IPs that are whitelisted from rate limiting", @@ -275,9 +280,26 @@ export class MeshService extends Construct { }); const defaultRules: CfnWebACL.RuleProperty[] = [ + { + name: "IPAllowList", + priority: props.allowedIpPriority || 2, + statement: { + ipSetReferenceStatement: { + arn: allowedIpList.attrArn, + }, + }, + visibilityConfig: { + cloudWatchMetricsEnabled: true, + metricName: "IPAllowList", + sampledRequestsEnabled: true, + }, + action: { + allow: {}, + }, + }, { name: "IPBlockList", - priority: 2 || props.blockedIpPriority, + priority: props.blockedIpPriority || 3, statement: { ipSetReferenceStatement: { arn: blockedIpList.attrArn, @@ -294,7 +316,7 @@ export class MeshService extends Construct { }, { name: "IPv6BlockList", - priority: 3 || props.blockedIpPriority, + priority: (props.blockedIpPriority || 3) + 1, statement: { ipSetReferenceStatement: { arn: blockedIpv6List.attrArn, @@ -314,7 +336,7 @@ export class MeshService extends Construct { if (props.rateLimit) { defaultRules.push({ name: "RateLimit", - priority: 10 || props.rateLimitPriority, + priority: props.rateLimitPriority || 10, statement: { rateBasedStatement: { aggregateKeyType: "FORWARDED_IP", @@ -323,20 +345,6 @@ export class MeshService extends Construct { fallbackBehavior: "MATCH", headerName: "X-Forwarded-For", }, - scopeDownStatement: { - notStatement: { - statement: { - ipSetReferenceStatement: { - arn: rateLimitBypassList.attrArn, - ipSetForwardedIpConfig: { - fallbackBehavior: "MATCH", - headerName: "X-Forwarded-For", - position: "FIRST", - }, - }, - }, - }, - }, }, }, visibilityConfig: { diff --git a/packages/graphql-mesh-server/lib/graphql-mesh-server.ts b/packages/graphql-mesh-server/lib/graphql-mesh-server.ts index d49f9fbe..347904e3 100644 --- a/packages/graphql-mesh-server/lib/graphql-mesh-server.ts +++ b/packages/graphql-mesh-server/lib/graphql-mesh-server.ts @@ -122,9 +122,9 @@ export type MeshHostingProps = { */ rateLimitPriority?: number; /** - * List of IPv4 addresses that can bypass rate limiting. + * List of IPv4 addresses that can bypass all WAF block lists. */ - rateLimitBypassList?: string[]; + allowedIps?: string[]; /** * Enable / disable container insights * Defaults to true From e83a938fbc5c5412b19dc3d80a1f63d0000e28e6 Mon Sep 17 00:00:00 2001 From: Daniel Van Der Ploeg Date: Wed, 14 Feb 2024 15:50:28 +1030 Subject: [PATCH 2/3] feat: add block all logic --- packages/graphql-mesh-server/lib/fargate.ts | 151 ++++++++++++------ .../lib/graphql-mesh-server.ts | 5 + 2 files changed, 105 insertions(+), 51 deletions(-) diff --git a/packages/graphql-mesh-server/lib/fargate.ts b/packages/graphql-mesh-server/lib/fargate.ts index d015a7da..a074d4be 100644 --- a/packages/graphql-mesh-server/lib/fargate.ts +++ b/packages/graphql-mesh-server/lib/fargate.ts @@ -78,6 +78,11 @@ export interface MeshServiceProps { * Defaults to 3 */ blockedIpv6Priority?: number; + /** + * If true, block all access to the endpoint. Use in conjunction with allowedIps to block public access + * @default false + */ + blockAll?: boolean; /** * List of AWS Managed rules to add to the WAF */ @@ -279,61 +284,105 @@ export class MeshService extends Construct { description: "List of IPv6s blocked by WAF", }); - const defaultRules: CfnWebACL.RuleProperty[] = [ - { - name: "IPAllowList", - priority: props.allowedIpPriority || 2, - statement: { - ipSetReferenceStatement: { - arn: allowedIpList.attrArn, + const defaultRules: CfnWebACL.RuleProperty[] = props.blockAll + ? [ + { + name: "BlockNonAllowedIps", + priority: props.allowedIpPriority || 2, + statement: { + notStatement: { + statement: { + ipSetReferenceStatement: { + arn: allowedIpList.attrArn, + ipSetForwardedIpConfig: { + fallbackBehavior: "MATCH", + headerName: "X-Forwarded-For", + position: "FIRST" + }, + }, + }, + }, + }, + visibilityConfig: { + cloudWatchMetricsEnabled: true, + metricName: "IPAllowList", + sampledRequestsEnabled: true, + }, + action: { + block: {}, + }, }, - }, - visibilityConfig: { - cloudWatchMetricsEnabled: true, - metricName: "IPAllowList", - sampledRequestsEnabled: true, - }, - action: { - allow: {}, - }, - }, - { - name: "IPBlockList", - priority: props.blockedIpPriority || 3, - statement: { - ipSetReferenceStatement: { - arn: blockedIpList.attrArn, + ] + : [ + { + name: "IPAllowList", + priority: props.allowedIpPriority || 2, + statement: { + ipSetReferenceStatement: { + arn: allowedIpList.attrArn, + ipSetForwardedIpConfig: { + fallbackBehavior: "MATCH", + headerName: "X-Forwarded-For", + position: "FIRST" + }, + }, + }, + visibilityConfig: { + cloudWatchMetricsEnabled: true, + metricName: "IPAllowList", + sampledRequestsEnabled: true, + }, + action: { + allow: {}, + }, }, - }, - visibilityConfig: { - cloudWatchMetricsEnabled: true, - metricName: "IPBlockList", - sampledRequestsEnabled: true, - }, - action: { - block: {}, - }, - }, - { - name: "IPv6BlockList", - priority: (props.blockedIpPriority || 3) + 1, - statement: { - ipSetReferenceStatement: { - arn: blockedIpv6List.attrArn, + { + name: "IPBlockList", + priority: props.blockedIpPriority || 3, + statement: { + ipSetReferenceStatement: { + arn: blockedIpList.attrArn, + ipSetForwardedIpConfig: { + fallbackBehavior: "MATCH", + headerName: "X-Forwarded-For", + position: "FIRST" + }, + }, + }, + visibilityConfig: { + cloudWatchMetricsEnabled: true, + metricName: "IPBlockList", + sampledRequestsEnabled: true, + }, + action: { + block: {}, + }, }, - }, - visibilityConfig: { - cloudWatchMetricsEnabled: true, - metricName: "IPv6BlockList", - sampledRequestsEnabled: true, - }, - action: { - block: {}, - }, - }, - ]; + { + name: "IPv6BlockList", + priority: (props.blockedIpPriority || 3) + 1, + statement: { + ipSetReferenceStatement: { + arn: blockedIpv6List.attrArn, + ipSetForwardedIpConfig: { + fallbackBehavior: "MATCH", + headerName: "X-Forwarded-For", + position: "FIRST" + }, + }, + }, + visibilityConfig: { + cloudWatchMetricsEnabled: true, + metricName: "IPv6BlockList", + sampledRequestsEnabled: true, + }, + action: { + block: {}, + }, + }, + ]; - if (props.rateLimit) { + if (props.rateLimit && !props.blockAll) { defaultRules.push({ name: "RateLimit", priority: props.rateLimitPriority || 10, diff --git a/packages/graphql-mesh-server/lib/graphql-mesh-server.ts b/packages/graphql-mesh-server/lib/graphql-mesh-server.ts index 347904e3..5803d0c3 100644 --- a/packages/graphql-mesh-server/lib/graphql-mesh-server.ts +++ b/packages/graphql-mesh-server/lib/graphql-mesh-server.ts @@ -103,6 +103,11 @@ export type MeshHostingProps = { * Defaults to 3 */ blockedIpv6Priority?: number; + /** + * If true, block all access to the endpoint. Use in conjunction with allowedIps to block public access + * @default false + */ + blockAll?: boolean; /** * List of AWS Managed rules to add to the WAF */ From 92cb3cf05b08ca8dbe5a89f89cd205d10de5e216 Mon Sep 17 00:00:00 2001 From: Daniel Van Der Ploeg Date: Wed, 14 Feb 2024 16:40:13 +1030 Subject: [PATCH 3/3] chore: run prettier --- packages/graphql-mesh-server/lib/fargate.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/graphql-mesh-server/lib/fargate.ts b/packages/graphql-mesh-server/lib/fargate.ts index a074d4be..54805cf3 100644 --- a/packages/graphql-mesh-server/lib/fargate.ts +++ b/packages/graphql-mesh-server/lib/fargate.ts @@ -297,7 +297,7 @@ export class MeshService extends Construct { ipSetForwardedIpConfig: { fallbackBehavior: "MATCH", headerName: "X-Forwarded-For", - position: "FIRST" + position: "FIRST", }, }, }, @@ -323,7 +323,7 @@ export class MeshService extends Construct { ipSetForwardedIpConfig: { fallbackBehavior: "MATCH", headerName: "X-Forwarded-For", - position: "FIRST" + position: "FIRST", }, }, }, @@ -345,7 +345,7 @@ export class MeshService extends Construct { ipSetForwardedIpConfig: { fallbackBehavior: "MATCH", headerName: "X-Forwarded-For", - position: "FIRST" + position: "FIRST", }, }, }, @@ -367,7 +367,7 @@ export class MeshService extends Construct { ipSetForwardedIpConfig: { fallbackBehavior: "MATCH", headerName: "X-Forwarded-For", - position: "FIRST" + position: "FIRST", }, }, },