Fuzzing and Bypassing the AWS WAF

Sysdig researchers built an automated WAF fuzzer (Wafer) that used PortSwigger XSS payloads and Selenium-driven interaction to discover that AWS WAF failed to block payloads leveraging the experimental DOM event onbeforetoggle. The team reported the issue to AWS, a fix was deployed, and a PoC demonstrated arbitrary JavaScript execution via a button/popover chain. #AWSWAF #onbeforetoggle #Wafer #Sysdig

Keypoints

  • Sysdig set up a test environment with an EC2-hosted web app behind a load balancer using AWS WAF and managed rule sets (Common, KnownBadInputs, SQLi).
  • Manual testing revealed many tag/attribute permutations but proved infeasible to exhaustively test, prompting development of an automated fuzzer named Wafer.
  • Wafer uses PortSwigger XSS payloads, iterates tags/attributes, generates permutations excluding blocked keywords, and attempts execution verification.
  • Selenium was used to inject hooks (to catch alert/confirm/prompt) and simulate user interactions (click, focus, blur, keyboard events) to trigger client-side execution.
  • Fuzzer implemented obfuscation strategies (splitting tags, inserting spaces/newlines, random Unicode-to-ASCII transforms) to bypass regex-based rules.
  • The fuzzer discovered a bypass using the experimental onbeforetoggle event, enabling a PoC that executed arbitrary JavaScript despite AWS WAF protections; AWS deployed a fix after disclosure.

MITRE Techniques

  • [T1190] Exploit Public-Facing Application – Sending crafted inputs to a web-facing application to trigger code execution: “This payload managed to successfully evade WAF’s defenses while also executing an alert box”
  • [T1203] Exploitation for Client Execution – Causing client-side browsers to execute arbitrary JavaScript via a DOM event: “it relies on the experimental onbeforetoggle event to link a standard HTML button to a popover element, chaining their functionalities to execute arbitrary JavaScript code”
  • [T1595.001] Active Scanning: Vulnerability Scanning – Automated fuzzing and scanning to find unfiltered tags/attributes using Wafer: “we decided to change our methodology and start building our own WAF fuzzer (Wafer)”
  • [T1027] Obfuscated Files or Information – Using obfuscation to bypass regex-based rules, such as splitting tags and injecting Unicode that converts to ASCII: “splitting tags using spaces and newlines, or adding random Unicode characters which are later converted to their ASCII representation”
  • [T1059.007] Command and Scripting Interpreter: JavaScript – Injecting and executing JavaScript in the browser and hooking alert/confirm/prompt for detection: “we created a simple hook to catch every call to alert, confirm, and prompt”

Indicators of Compromise

  • [Domain] blog and PoC source – https://sysdig.com/blog/fuzzing-and-bypassing-the-aws-waf/ (original post), https://github.com/sysdig/wafer (fuzzer repo)
  • [WAF rule sets] AWS WAF configuration references – AWS-AWSManagedRulesCommonRuleSet, AWS-AWSManagedRulesSQLiRuleSet (managed rules present in the tested environment)
  • [DOM event/element] exploit vector – onbeforetoggle (experimental DOM event used to trigger JS execution)
  • [PoC payload snippet] example attack pattern – button with popovertarget and a test element using onbeforetoggle=alert(document.domain) (demonstrated bypass)

We reproduced a typical AWS WAF deployment (EC2 web app behind a load balancer with AWS-managed rule sets: CommonRuleSet, KnownBadInputs, SQLi). Manual tag/attribute testing helped map which inputs triggered WAF blocks, but exhaustive testing proved impractical. To scale coverage, we developed Wafer, a fuzzer seeded with PortSwigger XSS payloads that iterates tags and attributes, learns which tokens are blocked, and generates permutations of allowed tokens to discover unfiltered combinations.

Wafer integrates Selenium to verify execution: it injects a JavaScript hook that sets window.alert_trigger when alert/confirm/prompt are called and injects an event-simulation script that dispatches many events (click, mouseover, focus, blur, keyboard events) to interactively trigger payloads. The fuzzer also applies obfuscation strategies—splitting tags across whitespace/newlines and inserting random Unicode before ASCII normalization—to bypass regex-based rule checks.

Running Wafer found a reliable bypass that used the experimental onbeforetoggle DOM event to link a button (popovertarget) with a popover element containing onbeforetoggle=alert(document.domain), which executed JavaScript despite AWS WAF protections. The PoC demonstrated client-side code execution; Sysdig reported the issue to AWS, a fix was deployed, and the fuzzer and techniques used are documented in the Wafer repository.

Read more: https://sysdig.com/blog/fuzzing-and-bypassing-the-aws-waf/