AWS WAF Advanced Rules: Custom Protection

Build custom AWS WAF rules to protect against sophisticated attacks with regex patterns, rate limiting, and geo-blocking.

AWS WAF (Web Application Firewall) provides essential protection for web applications, but default managed rules may not cover all attack vectors. This guide explores advanced custom rule creation for comprehensive web security.

Understanding WAF Rule Types

AWS WAF supports several rule types for different protection needs:

Rate-Based Rules

Rate-based rules protect against DDoS and brute force attacks:

{
  "Name": "RateLimitRule",
  "Priority": 1,
  "Statement": {
    "RateBasedStatement": {
      "Limit": 2000,
      "AggregateKeyType": "IP",
      "ScopeDownStatement": {
        "ByteMatchStatement": {
          "SearchString": "/api/login",
          "FieldToMatch": { "UriPath": {} },
          "TextTransformations": [{ "Priority": 0, "Type": "LOWERCASE" }],
          "PositionalConstraint": "STARTS_WITH"
        }
      }
    }
  },
  "Action": { "Block": {} },
  "VisibilityConfig": {
    "SampledRequestsEnabled": true,
    "CloudWatchMetricsEnabled": true,
    "MetricName": "RateLimitRule"
  }
}

Regex Pattern Sets

Create pattern sets for complex matching:

import boto3

wafv2 = boto3.client('wafv2')

response = wafv2.create_regex_pattern_set(
    Name='SQLInjectionPatterns',
    Scope='REGIONAL',
    RegularExpressionList=[
        {'RegexString': '(?i)(union.*select|select.*from|insert.*into)'},
        {'RegexString': '(?i)(drop\\s+table|truncate\\s+table)'},
        {'RegexString': "(?i)('.*or.*'.*=|".*or.*".*=)"},
        {'RegexString': '(?i)(exec\\s*\\(|execute\\s*\\()'}
    ]
)

pattern_set_arn = response['Summary']['ARN']

Geo-Blocking Implementation

Block or allow traffic based on geographic location:

GeoMatchRule:
  Name: BlockRestrictedCountries
  Priority: 2
  Statement:
    GeoMatchStatement:
      CountryCodes:
        - KP  # North Korea
        - IR  # Iran
        - RU  # Russia
  Action:
    Block:
      CustomResponse:
        ResponseCode: 403
        CustomResponseBodyKey: geo-blocked
  VisibilityConfig:
    SampledRequestsEnabled: true
    CloudWatchMetricsEnabled: true
    MetricName: GeoBlockRule

IP Reputation Lists

Implement dynamic IP reputation checking:

def update_ip_set_from_threat_feed():
    wafv2 = boto3.client('wafv2')
    
    # Fetch threat intelligence feed
    threat_ips = fetch_threat_intelligence_feed()
    
    # Get current IP set
    ip_set = wafv2.get_ip_set(
        Name='ThreatIntelligenceIPs',
        Scope='REGIONAL',
        Id='existing-ip-set-id'
    )
    
    # Update with new IPs
    wafv2.update_ip_set(
        Name='ThreatIntelligenceIPs',
        Scope='REGIONAL',
        Id='existing-ip-set-id',
        Addresses=threat_ips,
        LockToken=ip_set['LockToken']
    )

Label-Based Rules

Use labels for complex rule chaining:

{
  "Rules": [
    {
      "Name": "LabelSuspiciousRequests",
      "Priority": 1,
      "Statement": {
        "ByteMatchStatement": {
          "SearchString": "../",
          "FieldToMatch": { "UriPath": {} },
          "TextTransformations": [{ "Priority": 0, "Type": "URL_DECODE" }],
          "PositionalConstraint": "CONTAINS"
        }
      },
      "RuleLabels": [{ "Name": "suspicious:path-traversal" }],
      "Action": { "Count": {} }
    },
    {
      "Name": "BlockLabeledRequests",
      "Priority": 2,
      "Statement": {
        "LabelMatchStatement": {
          "Scope": "LABEL",
          "Key": "suspicious:path-traversal"
        }
      },
      "Action": { "Block": {} }
    }
  ]
}

Testing WAF Rules

Test rules before deployment:

# Test with sample requests
aws wafv2 check-capacity \
  --scope REGIONAL \
  --rules file://rules.json

# Analyze rule matches
aws wafv2 get-sampled-requests \
  --web-acl-arn $WEB_ACL_ARN \
  --rule-metric-name RateLimitRule \
  --scope REGIONAL \
  --time-window StartTime=2024-01-01T00:00:00Z,EndTime=2024-01-02T00:00:00Z \
  --max-items 100

Managed Rule Group Customization

Customize managed rule behavior:

ManagedRuleGroupStatement:
  VendorName: AWS
  Name: AWSManagedRulesCommonRuleSet
  ExcludedRules:
    - Name: SizeRestrictions_BODY
    - Name: CrossSiteScripting_BODY
  RuleActionOverrides:
    - Name: EC2MetaDataSSRF_BODY
      ActionToUse:
        Count: {}

Monitoring and Alerting

Set up comprehensive monitoring:

WAFAlarm:
  Type: AWS::CloudWatch::Alarm
  Properties:
    AlarmName: HighBlockRate
    MetricName: BlockedRequests
    Namespace: AWS/WAFV2
    Statistic: Sum
    Period: 300
    EvaluationPeriods: 2
    Threshold: 1000
    ComparisonOperator: GreaterThanThreshold
    Dimensions:
      - Name: WebACL
        Value: !Ref WebACL
      - Name: Region
        Value: !Ref AWS::Region

Working with Warqline

We are a cloud engineering consultancy and an official AWS and Google Cloud partner. If you are running this in production and want a second pair of eyes, we scope work in a free 45-minute technical call: you describe what you are running and what worries you, and we tell you what we would look at first.

Talk to an engineer

Conclusion

Advanced AWS WAF rules provide granular protection against sophisticated attacks. Combine rate limiting, regex patterns, geo-blocking, and IP reputation for defense in depth.