AWS WAF Disassociation


Description

Detects when AWS WAF is disassociated from protected resources such as Application Load Balancers, API Gateway, CloudFront, or AppSync. Removing WAF protection exposes applications to SQL injection, XSS, DDoS attacks, and OWASP Top 10 vulnerabilities. Attackers often disable WAF before launching attacks, or this may indicate misconfiguration or unauthorized changes.

Query · python

def rule(event):
    return event.get("eventName") == "DisassociateWebACL"


def title(event):
    return (
        f"AWS Account ID [{event.get('recipientAccountId')}] "
        f"disassociated WebACL [{event.deep_get('requestParameters', 'resourceArn')}]"
    )


def alert_context(event):
    return {
        "awsRegion": event.get("awsRegion"),
        "eventName": event.get("eventName"),
        "recipientAccountId": event.get("recipientAccountId"),
        "requestID": event.get("requestID"),
        "actor_user": event.udm("actor_user"),
        "requestParameters": event.deep_get("requestParameters", "resourceArn"),
        "userIdentity": event.deep_get("userIdentity", "principalId"),
    }

Analyst notes

  1. Query ALB access logs, CloudFront logs, or API Gateway logs for requestParameters.resourceArn in the timeframe between this DisassociateWebACL event and WAF re-association to identify attack traffic that reached the unprotected resource
  2. Search for SQL injection patterns, XSS payloads, or unusual request volumes in the application logs that may indicate exploitation while WAF protection was removed
  3. Review CloudTrail for other security-related API calls by userIdentity.arn in the 6 hours around this event to identify if other defensive controls were modified or disabled
Raw source AWS WAF Disassociation · Panther Python
Esc
Published by panther-labs/panther-analysis ↗, licensed under Apache 2.0 ↗. Reproduced here unmodified.
AnalysisType: rule
Description: >
  Detects when AWS WAF is disassociated from protected resources such as Application Load Balancers, API Gateway, CloudFront, or AppSync. Removing WAF protection exposes applications to SQL injection, XSS, DDoS attacks, and OWASP Top 10 vulnerabilities. Attackers often disable WAF before launching attacks, or this may indicate misconfiguration or unauthorized changes.
DisplayName: "AWS WAF Disassociation"
Enabled: true
Filename: aws_waf_disassociation.py
Reference: https://docs.aws.amazon.com/waf/latest/APIReference/API_DisassociateWebACL.html
Runbook: |
  1. Query ALB access logs, CloudFront logs, or API Gateway logs for requestParameters.resourceArn in the timeframe between this DisassociateWebACL event and WAF re-association to identify attack traffic that reached the unprotected resource
  2. Search for SQL injection patterns, XSS payloads, or unusual request volumes in the application logs that may indicate exploitation while WAF protection was removed
  3. Review CloudTrail for other security-related API calls by userIdentity.arn in the 6 hours around this event to identify if other defensive controls were modified or disabled
Severity: Critical
Tags:
  - AWS
  - Web Application Firewall
  - Defense Evasion
  - Impair Defenses
  - Network Security
Reports:
  MITRE ATT&CK:
    - TA0005:T1562.004
Tests:
  - ExpectedResult: true
    Log:
      apiVersion: "2019-04-23"
      awsRegion: us-west-2
      eventCategory: Management
      eventID: 94678efc-2176-462c-b0c9-a612881a39ed
      eventName: DisassociateWebACL
      eventSource: wafv2.amazonaws.com
      eventTime: "2022-09-29 23:04:35"
      eventType: AwsApiCall
      eventVersion: "1.08"
      managementEvent: true
      p_any_aws_account_ids:
        - "012345678910"
      p_any_aws_arns:
        - arn:aws:elasticloadbalancing:us-west-2:012345678910:loadbalancer/app/web/84dc5457e450dba5
        - arn:aws:iam::012345678910:role/DevAdministrator
        - arn:aws:sts::012345678910:assumed-role/DevAdministrator/example_user
      p_any_domain_names:
        - AWS Internal
      p_any_trace_ids:
        - ASIARLIVEKVNJNSTUSF6
      p_event_time: "2022-09-29 23:04:35"
      p_log_type: AWS.CloudTrail
      p_parse_time: "2022-09-29 23:08:26.172"
      p_row_id: 5ad3a83ca88f938cbff8fdd913d1ce1d
      p_source_id: 125a8146-e3ea-454b-aed7-9e08e735b670
      p_source_label: Panther Identity Org CloudTrail
      readOnly: false
      recipientAccountId: "012345678910"
      requestID: e4d47992-90f1-47f0-bff7-de18a8277005
      requestParameters:
        resourceArn: arn:aws:elasticloadbalancing:us-west-2:012345678910:loadbalancer/app/web/84dc5457e450dba5
      sessionCredentialFromConsole: true
      sourceIPAddress: AWS Internal
      userAgent: AWS Internal
      userIdentity:
        accessKeyId: ASIARLIVEKVNJNSTUSF6
        accountId: "012345678910"
        arn: arn:aws:sts::012345678910:assumed-role/DevAdministrator/example_user
        principalId: AROARLIVEKVNIRVGDLJWJ:example_user
        sessionContext:
          attributes:
            creationDate: "2022-09-29T22:51:13Z"
            mfaAuthenticated: "true"
          sessionIssuer:
            accountId: "012345678910"
            arn: arn:aws:iam::012345678910:role/DevAdministrator
            principalId: AROARLIVEKVNIRVGDLJWJ
            type: Role
            userName: DevAdministrator
          webIdFederationData: {}
        type: AssumedRole
    Name: WAF-Disassociate
  - ExpectedResult: false
    Log:
      apiVersion: "2019-04-23"
      awsRegion: us-west-2
      eventCategory: Management
      eventID: 94678efc-2176-462c-b0c9-a612881a39ed
      eventName: ListWebACLs
      eventSource: wafv2.amazonaws.com
      eventTime: "2022-09-29 23:04:35"
      eventType: AwsApiCall
      eventVersion: "1.08"
      managementEvent: true
      p_any_aws_account_ids:
        - "012345678910"
      p_any_aws_arns:
        - arn:aws:elasticloadbalancing:us-west-2:012345678910:loadbalancer/app/web/84dc5457e450dba5
        - arn:aws:iam::012345678910:role/DevAdministrator
        - arn:aws:sts::012345678910:assumed-role/DevAdministrator/example_user
      p_any_domain_names:
        - AWS Internal
      p_any_trace_ids:
        - ASIARLIVEKVNJNSTUSF6
      p_event_time: "2022-09-29 23:04:35"
      p_log_type: AWS.CloudTrail
      p_parse_time: "2022-09-29 23:08:26.172"
      p_row_id: 5ad3a83ca88f938cbff8fdd913d1ce1d
      p_source_id: 125a8146-e3ea-454b-aed7-9e08e735b670
      p_source_label: Panther Identity Org CloudTrail
      readOnly: false
      recipientAccountId: "012345678910"
      requestID: e4d47992-90f1-47f0-bff7-de18a8277005
      requestParameters:
        resourceArn: arn:aws:elasticloadbalancing:us-west-2:012345678910:loadbalancer/app/web/84dc5457e450dba5
      sessionCredentialFromConsole: true
      sourceIPAddress: AWS Internal
      userAgent: AWS Internal
      userIdentity:
        accessKeyId: ASIARLIVEKVNJNSTUSF6
        accountId: "012345678910"
        arn: arn:aws:sts::012345678910:assumed-role/DevAdministrator/example_user
        principalId: AROARLIVEKVNIRVGDLJWJ:example_user
        sessionContext:
          attributes:
            creationDate: "2022-09-29T22:51:13Z"
            mfaAuthenticated: "true"
          sessionIssuer:
            accountId: "012345678910"
            arn: arn:aws:iam::012345678910:role/DevAdministrator
            principalId: AROARLIVEKVNIRVGDLJWJ
            type: Role
            userName: DevAdministrator
          webIdFederationData: {}
        type: AssumedRole
    Name: WAF - List WebACLs
DedupPeriodMinutes: 60
LogTypes:
  - AWS.CloudTrail
RuleID: "AWS.WAF.Disassociation"
Threshold: 1


# ------ paired body: aws_waf_disassociation.py ------

def rule(event):
    return event.get("eventName") == "DisassociateWebACL"


def title(event):
    return (
        f"AWS Account ID [{event.get('recipientAccountId')}] "
        f"disassociated WebACL [{event.deep_get('requestParameters', 'resourceArn')}]"
    )


def alert_context(event):
    return {
        "awsRegion": event.get("awsRegion"),
        "eventName": event.get("eventName"),
        "recipientAccountId": event.get("recipientAccountId"),
        "requestID": event.get("requestID"),
        "actor_user": event.udm("actor_user"),
        "requestParameters": event.deep_get("requestParameters", "resourceArn"),
        "userIdentity": event.deep_get("userIdentity", "principalId"),
    }

Detection rules belong to the projects that publish them and remain under their own licenses. This site indexes and links to them; it claims no rights in them.