Skip to content

Instantly share code, notes, and snippets.

@statik
Last active October 16, 2024 02:36
Show Gist options
  • Save statik/f1ac9d6227d98d30c7a7cec0c83f4e64 to your computer and use it in GitHub Desktop.
Save statik/f1ac9d6227d98d30c7a7cec0c83f4e64 to your computer and use it in GitHub Desktop.

Revisions

  1. statik revised this gist May 13, 2022. 1 changed file with 0 additions and 1 deletion.
    1 change: 0 additions & 1 deletion waf.ts
    Original file line number Diff line number Diff line change
    @@ -8,7 +8,6 @@ export interface StackProps extends cdk.StackProps {
    }

    export class WAFStack extends cdk.Stack {
    public snsTopic: sns.Topic;
    constructor(scope: cdk.Construct, id: string, props: customProps.StackProps) {
    super(scope, id, props);
    cdk.Tags.of(this).add('cost-tag', String(props.tag));
  2. statik created this gist May 5, 2021.
    194 changes: 194 additions & 0 deletions waf.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,194 @@
    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 {
    public snsTopic: sns.Topic;
    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,
    });
    }
    }