Advanced Verification: Playwright and OAST

Advanced Verification: Playwright and OAST

Relevant source files

Purpose and Scope

This document explains WSHawk's two advanced verification mechanisms that move beyond simple pattern matching to confirm actual exploitability: Playwright browser-based verification for XSS and Out-of-Band Application Security Testing (OAST) for blind vulnerabilities. These verification layers reduce false positives and provide proof-of-concept evidence for detected vulnerabilities.

For information about the vulnerability detection modules that trigger these verification mechanisms, see Vulnerability Detection Modules. For session security testing, see Session Hijacking Tests.


Why Advanced Verification is Required

Traditional vulnerability scanners rely on pattern matching: if a payload is reflected in a response, the scanner flags it as vulnerable. This approach produces high false positive rates because:

  • XSS: Reflection does not prove execution. The payload may be encoded, escaped, or placed in a non-executable context.
  • XXE/SSRF: Blind vulnerabilities produce no visible response. Pattern matching cannot detect out-of-band data exfiltration or internal network access.
  • Context awareness: A payload like <script>alert(1)</script> may be reflected but sanitized to &lt;script&gt;alert(1)&lt;/script&gt;.

WSHawk implements two verification layers to address these limitations:

| Verification Method | Purpose | Vulnerability Types | Evidence Type | | --- | --- | --- | --- | | Playwright Browser | Confirm script execution in real browser | XSS | Screenshot + console logs | | OAST (Out-of-Band) | Detect blind vulnerabilities via callbacks | XXE, SSRF | DNS/HTTP callback logs |

Sources: README.md L14-L16

CHANGELOG.md L63-L65


Playwright Browser-Based XSS Verification

Overview

The HeadlessBrowserXSSVerifier class uses Playwright to load responses in a real Chromium browser and verify that injected JavaScript actually executes. This provides definitive proof of exploitability.

Verification Process:

Sources: scanner_v2.py L215-L293


Integration with Scanner

The scanner conditionally enables browser verification based on the use_headless_browser flag:

Configuration in WSHawkV2:

Verification trigger during XSS testing:

Sources: scanner_v2.py L250-L266


Verification Workflow in Code

Sources: scanner_v2.py L215-L293

scanner_v2.py L52-L54


Browser Verification Evidence

When browser verification succeeds, the vulnerability entry includes additional evidence fields:

Sources: scanner_v2.py L273-L283


Resource Cleanup

The scanner ensures proper cleanup of browser resources after testing completes:

Sources: scanner_v2.py L619-L624


OAST for Blind Vulnerabilities

Overview

The OASTProvider class enables detection of blind vulnerabilities (XXE, SSRF) that do not produce visible responses. OAST works by injecting payloads that trigger DNS or HTTP callbacks to a controlled server, proving the vulnerability exists even when no error messages appear.

OAST Architecture:

Sources: scanner_v2.py L402-L456

scanner_v2.py L56-L58


OAST Integration in Scanner

The scanner conditionally enables OAST based on the use_oast flag:

Configuration in WSHawkV2:

OAST initialization during XXE testing:

Sources: scanner_v2.py L410-L417


Payload Generation with OAST

When OAST is enabled, the scanner generates payloads containing unique callback identifiers:

Example OAST XXE payload:

Sources: scanner_v2.py L422-L426


Supported Vulnerability Types

| Vulnerability | OAST Usage | Callback Trigger | | --- | --- | --- | | XXE | External entity loads OAST URL | DNS lookup or HTTP request to parse entity | | SSRF | Injected URL points to OAST server | Target makes HTTP request to attacker-controlled domain | | Command Injection | Payload executes curl to OAST domain | OS command triggers HTTP request | | DNS Exfiltration | DNS query to OAST subdomain | Application performs DNS lookup |

Sources: scanner_v2.py L402-L456

README.md L25


OAST Provider Configuration

The OASTProvider supports two modes:

  1. Local OAST Server (default): Runs SimpleOASTServer on localhost
  2. Interactsh Integration: Uses external Interactsh service for public testing

Initialization:

Modes comparison:

| Mode | Pros | Cons | Use Case | | --- | --- | --- | --- | | use_interactsh=False | No external dependencies, offline testing | Requires firewall rules for callbacks | Internal networks, local testing | | use_interactsh=True | Public DNS/HTTP callbacks work anywhere | Requires internet, shares data with external service | Cloud targets, remote testing |

Sources: scanner_v2.py L412


OAST Resource Cleanup

Like browser verification, OAST resources are properly cleaned up:

Sources: scanner_v2.py L626-L631


Configuration and Usage

Enabling/Disabling Verification Mechanisms

Via Python API:

Via CLI (wshawk-advanced):

Sources: README.md L85-L92

README.md L199-L207


Prerequisites

For Playwright verification:

For OAST:

No additional installation required. The SimpleOASTServer is included in WSHawk. For external testing with Interactsh, ensure network egress is allowed.

Sources: README.md L42-L44


Implementation Architecture

Class Relationships

Sources: scanner_v2.py L28-L75

scanner_v2.py L52-L58


Confidence Level Escalation

Advanced verification mechanisms can escalate confidence levels:

| Initial Detection | Verification Method | Final Confidence | Condition | | --- | --- | --- | --- | | ConfidenceLevel.HIGH | Playwright | ConfidenceLevel.CRITICAL | JavaScript executed in browser | | ConfidenceLevel.MEDIUM | Playwright | ConfidenceLevel.HIGH | Partial execution detected | | Pattern match | OAST | ConfidenceLevel.HIGH | Callback received within timeout | | No pattern match | OAST | ConfidenceLevel.CRITICAL | Blind vulnerability confirmed via callback |

Code implementation:

Sources: scanner_v2.py L261-L264


Performance and Resource Considerations

Browser Verification Overhead

  • Browser launch time: ~2-3 seconds per test suite (browser is reused across tests)
  • Per-payload verification: ~500ms (page load + JavaScript execution wait)
  • Memory usage: ~100-150MB for Chromium instance

Optimization strategy:

The scanner initializes the browser once and reuses it for all XSS tests:

Sources: scanner_v2.py L253-L255


OAST Server Resource Usage

  • DNS server: UDP port binding (minimal overhead)
  • HTTP server: Single async HTTP server (< 10MB memory)
  • Callback storage: In-memory dictionary (negligible for normal scans)

Network considerations:

OAST requires the target application to have network egress to the OAST server. Firewall rules must allow:

  • DNS queries to OAST domain
  • HTTP/HTTPS requests to OAST server

Sources: scanner_v2.py L410-L417


Verification Workflow Summary

Sources: scanner_v2.py L215-L293

scanner_v2.py L402-L456


Summary

WSHawk's advanced verification mechanisms provide definitive proof of exploitability:

  • Playwright verification confirms XSS payloads execute in real browsers, eliminating false positives from sanitized or encoded reflections
  • OAST integration detects blind vulnerabilities (XXE, SSRF) that produce no visible responses, using out-of-band DNS/HTTP callbacks
  • Both mechanisms integrate seamlessly with the scanner's confidence scoring system, escalating to CRITICAL when verification succeeds
  • Resource management ensures proper cleanup of browser instances and OAST servers after testing

These verification layers distinguish WSHawk from pattern-matching scanners, providing security teams with high-confidence findings backed by concrete evidence.

Sources: scanner_v2.py L28-L681

README.md L14-L16

CHANGELOG.md L63-L65