Browser Validation

Article 4: Playwright-Assisted DOM XSS Evidence Collection

Source File: wshawk/headless_xss_verifier.py
Relevant Class: HeadlessBrowserXSSVerifier

4.1 The False Positive Dilemma

Automated scanners detect Cross-Site Scripting (XSS) by sending a payload like <script>alert(1)</script> and checking if it reflects in the HTTP response.

However, modern frontend frameworks (React, Vue, Angular) often sanitize outputs or bind data safely (e.g., using element.innerText rather than element.innerHTML). In these cases, the payload reflects exactly as sent in the network traffic, but it is inert in the browser DOM. Flagging this as a vulnerability creates massive volumes of false positives.

4.2 Sandboxed DOM Verification

To guarantee XSS execution and eliminate false positives, WSHawk leverages a headless Chromium browser via the asynchronous playwright library.

When the scanner detects a reflected payload in the WebSocket stream, it invokes HeadlessBrowserXSSVerifier.

  1. Context Creation: It spins up an isolated Chromium page in the background.
  2. Beacon Injection: It overrides the native browser alert function to trap execution without halting the automated test:
    window.xssExecuted = false;
    const originalAlert = window.alert;
    window.alert = function(msg) {
        window.xssExecuted = true;
        originalAlert(msg);
    };
  3. DOM Evaluation: It renders the suspected HTML reflection inside the Chromium context. If the payload executes, the overridden alert fires, and the window.xssExecuted beacon evaluates to true.
  4. Mutation Tracking: Beyond simple alerts, the verifier also queries the DOM for injected <script> tags or inline event handlers (onerror, onmouseover) injected by the payload, handling complex DOM-based execution flows.

If the beacon fires or DOM mutation is proven, the vulnerability is flagged as CONFIRMED. If the browser renders the payload harmlessly, the finding is discarded. This methodology results in a 0% false positive rate for DOM XSS detection.