-
-
Save marcandjulien/4ddae764ba1a9b0d51c3cb90f7edc556 to your computer and use it in GitHub Desktop.
WAF with CDK examples
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as cdk from "@aws-cdk/core"; | |
import * as wafv2 from "@aws-cdk/aws-wafv2"; | |
// This extends the base cdk stack properties to include a tag name input. | |
export interface StackProps extends cdk.StackProps { | |
tag: string; | |
applicationName?: string; | |
} | |
export class WAFStack extends cdk.Stack { | |
constructor(scope: cdk.Construct, id: string, props: customProps.StackProps) { | |
super(scope, id, props); | |
cdk.Tags.of(this).add('cost-tag', String(props.tag)); | |
const waf = new WAF(this, 'WAFv2'); | |
const devALB = elb.ApplicationLoadBalancer.fromLookup(this, 'devALB', { | |
loadBalancerTags: { | |
// Finds a load balancer matching all tags. | |
'Name': 'foo-dev', | |
}, | |
}); | |
const prodALB = elb.ApplicationLoadBalancer.fromLookup(this, 'prodALB', { | |
loadBalancerTags: { | |
// Finds a load balancer matching all tags. | |
'Name': 'foo-prod', | |
}, | |
}); | |
// Create an association with the dev alb | |
new WebACLAssociation(this, 'DevAssociation',{ | |
resourceArn: devALB.loadBalancerArn, | |
webAclArn: waf.attrArn, | |
}); | |
// Create an association with the prod alb | |
new WebACLAssociation(this, 'ProdAssociation',{ | |
resourceArn: prodALB.loadBalancerArn, | |
webAclArn: waf.attrArn, | |
}); | |
} | |
} | |
interface WafRule { | |
name: string; | |
rule: wafv2.CfnWebACL.RuleProperty; | |
} | |
const awsManagedRules: WafRule[] = [ | |
// AWS IP Reputation list includes known malicious actors/bots and is regularly updated | |
{ | |
name: 'AWS-AWSManagedRulesAmazonIpReputationList', | |
rule: { | |
name: 'AWS-AWSManagedRulesAmazonIpReputationList', | |
priority: 10, | |
statement: { | |
managedRuleGroupStatement: { | |
vendorName: 'AWS', | |
name: 'AWSManagedRulesAmazonIpReputationList', | |
}, | |
}, | |
overrideAction: { | |
none: {}, | |
}, | |
visibilityConfig: { | |
sampledRequestsEnabled: true, | |
cloudWatchMetricsEnabled: true, | |
metricName: 'AWSManagedRulesAmazonIpReputationList', | |
}, | |
}, | |
}, | |
// Common Rule Set aligns with major portions of OWASP Core Rule Set | |
{ | |
name: 'AWS-AWSManagedRulesCommonRuleSet', | |
rule: | |
{ | |
name: 'AWS-AWSManagedRulesCommonRuleSet', | |
priority: 20, | |
statement: { | |
managedRuleGroupStatement: { | |
vendorName: 'AWS', | |
name: 'AWSManagedRulesCommonRuleSet', | |
// Excluding generic RFI body rule for sns notifications | |
// https://docs.aws.amazon.com/waf/latest/developerguide/aws-managed-rule-groups-list.html | |
excludedRules: [ | |
{ name: 'GenericRFI_BODY' }, | |
{ name: 'SizeRestrictions_BODY' }, | |
], | |
}, | |
}, | |
overrideAction: { | |
none: {}, | |
}, | |
visibilityConfig: { | |
sampledRequestsEnabled: true, | |
cloudWatchMetricsEnabled: true, | |
metricName: 'AWS-AWSManagedRulesCommonRuleSet', | |
}, | |
}, | |
}, | |
// Blocks common SQL Injection | |
{ | |
name: 'AWSManagedRulesSQLiRuleSet', | |
rule: { | |
name: 'AWSManagedRulesSQLiRuleSet', | |
priority: 30, | |
visibilityConfig: { | |
sampledRequestsEnabled: true, | |
cloudWatchMetricsEnabled: true, | |
metricName: 'AWSManagedRulesSQLiRuleSet', | |
}, | |
overrideAction: { | |
none: {}, | |
}, | |
statement: { | |
managedRuleGroupStatement: { | |
vendorName: 'AWS', | |
name: 'AWSManagedRulesSQLiRuleSet', | |
excludedRules: [], | |
}, | |
}, | |
}, | |
}, | |
// Blocks common PHP attacks such as using high risk variables and methods in the body or queries | |
{ | |
name: 'AWSManagedRulePHP', | |
rule: { | |
name: 'AWSManagedRulePHP', | |
priority: 40, | |
visibilityConfig: { | |
sampledRequestsEnabled: true, | |
cloudWatchMetricsEnabled: true, | |
metricName: 'AWSManagedRulePHP', | |
}, | |
overrideAction: { | |
none: {}, | |
}, | |
statement: { | |
managedRuleGroupStatement: { | |
vendorName: 'AWS', | |
name: 'AWSManagedRulesPHPRuleSet', | |
excludedRules: [], | |
}, | |
}, | |
}, | |
}, | |
// Blocks attacks targeting LFI(Local File Injection) for linux systems | |
{ | |
name: 'AWSManagedRuleLinux', | |
rule: { | |
name: 'AWSManagedRuleLinux', | |
priority: 50, | |
visibilityConfig: { | |
sampledRequestsEnabled: true, | |
cloudWatchMetricsEnabled: true, | |
metricName: 'AWSManagedRuleLinux', | |
}, | |
overrideAction: { | |
none: {}, | |
}, | |
statement: { | |
managedRuleGroupStatement: { | |
vendorName: 'AWS', | |
name: 'AWSManagedRulesLinuxRuleSet', | |
excludedRules: [], | |
}, | |
}, | |
}, | |
}, | |
]; | |
export class WAF extends wafv2.CfnWebACL { | |
constructor(scope: cdk.Construct, id: string) { | |
super(scope, id,{ | |
defaultAction: { allow: {} }, | |
visibilityConfig: { | |
cloudWatchMetricsEnabled: true, | |
metricName: 'foo-waf', | |
sampledRequestsEnabled: false, | |
}, | |
scope: 'REGIONAL', | |
name: 'foo-prod-waf', | |
rules: awsManagedRules.map(wafRule => wafRule.rule), | |
}); | |
} | |
} | |
export class WebACLAssociation extends wafv2.CfnWebACLAssociation { | |
constructor(scope: cdk.Construct, id: string, props: wafv2.CfnWebACLAssociationProps) { | |
super(scope, id,{ | |
resourceArn: props.resourceArn, | |
webAclArn: props.webAclArn, | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment