Defensive Validation

Defensive Validation

The following files were used as context for generating this wiki page:

Purpose and Scope

This document provides an overview of WSHawk's Defensive Validation module, a security control validation framework designed for blue teams. This page covers the module's purpose, architecture, test categories, and usage patterns. For detailed information about specific tests, see:

For offensive vulnerability testing capabilities, see Offensive Testing.


Overview

The Defensive Validation module inverts WSHawk's typical offensive testing model to serve blue team needs. While the core scanner (documented in Scanner Engine) focuses on discovering vulnerabilities, the defensive validation module tests whether security controls are properly configured to prevent those vulnerabilities from being exploited.

Design Philosophy

The module validates four critical security control categories:

| Control Category | Purpose | Risk if Misconfigured | |-----------------|---------|----------------------| | DNS Exfiltration Prevention | Blocks DNS-based data exfiltration | APT-style data theft | | Bot Detection | Detects automated browsers | Credential stuffing, scraping | | CSWSH Prevention | Validates Origin header enforcement | Session hijacking | | WSS Security | Enforces secure WebSocket protocols | MITM attacks |

Each test produces findings with CVSS v3.1 scores ranging from 5.3 (MEDIUM) to 9.8 (CRITICAL), enabling prioritized remediation.

Sources: docs/DEFENSIVE_VALIDATION.md:1-15, README.md:143-183, CHANGELOG.md:14-27


Architecture and System Integration

Position in WSHawk Ecosystem

graph TB
    subgraph "User Interfaces"
        CLI1["wshawk<br/>(Offensive)"]
        CLI2["wshawk-interactive<br/>(Offensive)"]
        CLI3["wshawk-advanced<br/>(Offensive)"]
        CLI4["wshawk-defensive<br/>(Defensive)"]
    end
    
    subgraph "Core Scanning Engine"
        Scanner["WSHawkV2<br/>wshawk/scanner_v2.py"]
        Intel["Intelligence Modules"]
    end
    
    subgraph "Offensive Testing"
        VulnTests["Vulnerability Tests<br/>SQL/XSS/XXE/etc"]
    end
    
    subgraph "Defensive Validation"
        DefMain["run_defensive_validation()<br/>wshawk/defensive_validation.py"]
        DNS["DNSExfiltrationTest"]
        Bot["BotDetectionValidator"]
        CSWSH["CSWSHValidator"]
        WSS["WSSSecurityValidator"]
    end
    
    subgraph "Shared Infrastructure"
        Payloads["Payload Files<br/>payloads/malicious_origins.txt"]
        CVSS["CVSS Scoring"]
        Reports["HTML Reports"]
        Logger["Centralized Logger"]
    end
    
    CLI1 --> Scanner
    CLI2 --> Scanner
    CLI3 --> Scanner
    CLI4 --> DefMain
    
    Scanner --> Intel
    Scanner --> VulnTests
    
    DefMain --> DNS
    DefMain --> Bot
    DefMain --> CSWSH
    DefMain --> WSS
    
    DNS --> Payloads
    CSWSH --> Payloads
    
    VulnTests --> CVSS
    DNS --> CVSS
    Bot --> CVSS
    CSWSH --> CVSS
    WSS --> CVSS
    
    CVSS --> Reports
    DefMain --> Logger

Diagram: Defensive Validation Module Position in WSHawk

The wshawk-defensive CLI command bypasses the offensive scanner engine entirely, invoking run_defensive_validation() directly. This architectural separation ensures defensive tests remain independent from offensive testing logic, while sharing common infrastructure (payload management, CVSS scoring, reporting).

Sources: docs/DEFENSIVE_VALIDATION.md:120-157, README.md:143-148


Module Structure

graph LR
    subgraph "Entry Point"
        CLIEntry["wshawk-defensive CLI<br/>wshawk/__main__.py"]
        APIEntry["run_defensive_validation()<br/>wshawk/defensive_validation.py"]
    end
    
    subgraph "Test Classes"
        DNSClass["DNSExfiltrationTest<br/>- run_all_tests()<br/>- test_xxe_exfiltration()<br/>- test_ssrf_exfiltration()"]
        BotClass["BotDetectionValidator<br/>- run_all_tests()<br/>- test_basic_headless()<br/>- test_evasion_resistance()"]
        CSWSHClass["CSWSHValidator<br/>- run_all_tests()<br/>- test_origin_validation()<br/>- load_malicious_origins()"]
        WSSClass["WSSSecurityValidator<br/>- run_all_tests()<br/>- check_tls_version()<br/>- check_cipher_suites()<br/>- check_certificate()"]
    end
    
    subgraph "Findings Management"
        Findings["findings: List[Dict]<br/>- test: str<br/>- vulnerable: bool<br/>- severity: str<br/>- cvss: float<br/>- description: str<br/>- recommendation: str"]
    end
    
    subgraph "External Dependencies"
        Payloads["payloads/malicious_origins.txt<br/>216+ origins"]
        OAST["OAST Provider<br/>Optional DNS callbacks"]
        Playwright["Playwright<br/>Headless browser"]
        SSL["ssl/socket modules<br/>TLS inspection"]
    end
    
    CLIEntry --> APIEntry
    APIEntry --> DNSClass
    APIEntry --> BotClass
    APIEntry --> CSWSHClass
    APIEntry --> WSSClass
    
    DNSClass --> Findings
    BotClass --> Findings
    CSWSHClass --> Findings
    WSSClass --> Findings
    
    DNSClass --> OAST
    BotClass --> Playwright
    CSWSHClass --> Payloads
    WSSClass --> SSL

Diagram: Defensive Validation Module Internal Structure

Each test class maintains its own findings list and implements a run_all_tests() method that returns results. The run_defensive_validation() function orchestrates execution and aggregates findings.

Sources: docs/DEFENSIVE_VALIDATION.md:159-189


Test Categories

1. DNS Exfiltration Prevention Test

Class: DNSExfiltrationTest

Purpose: Validates that the target network blocks DNS-based data exfiltration attempts through XXE and SSRF vectors.

Attack Scenario: Attackers encode stolen data in DNS queries (e.g., stolen-data.attacker.com), bypassing traditional firewalls. This technique is common in APT attacks and malware C2 communications.

Test Vectors:

  • XXE payload with external entity resolving to DNS callback
  • SSRF payload triggering DNS resolution

CVSS Score: 7.5-8.2 (HIGH) if vulnerable

Detailed information: See DNS Exfiltration Prevention Test

Sources: docs/DEFENSIVE_VALIDATION.md:17-37, CHANGELOG.md:15-16


2. Bot Detection Validation Test

Class: BotDetectionValidator

Purpose: Tests whether anti-bot measures can detect and block headless browsers used in automated attacks.

Attack Scenario: Automated attacks (credential stuffing, scraping, account takeover) rely on headless browsers. Effective bot detection should identify these tools through fingerprinting techniques.

Test Levels:

  1. Basic Detection: Tests if navigator.webdriver and other basic signals are checked
  2. Evasion Resistance: Tests if advanced evasion techniques (e.g., Playwright stealth mode) bypass detection

CVSS Scores:

  • 5.3 (MEDIUM) for basic detection failure
  • 7.8 (HIGH) for evasion resistance failure

Detailed information: See Bot Detection Validation Test

Sources: docs/DEFENSIVE_VALIDATION.md:40-61, CHANGELOG.md:16


3. CSWSH Test (Cross-Site WebSocket Hijacking)

Class: CSWSHValidator

Purpose: Validates that WebSocket connections properly enforce Origin header validation to prevent cross-site attacks.

Attack Scenario: An attacker hosts a malicious page that establishes a WebSocket connection to the victim application, leveraging the victim's authenticated session to perform unauthorized actions.

Test Methodology:

  • Attempts connections with 216+ malicious origins loaded from payloads/malicious_origins.txt
  • Tests include: https://evil-attacker.com, http://localhost:666, null, empty strings, and various obfuscation techniques

CVSS Scores:

  • 9.1 (CRITICAL) for Origin validation failure
  • 7.5 (HIGH) for missing CSRF tokens

Detailed information: See CSWSH Test

Sources: docs/DEFENSIVE_VALIDATION.md:64-85, CHANGELOG.md:17-25, docs/DEFENSIVE_VALIDATION.md:270-273


4. WSS Protocol Security Validation

Class: WSSSecurityValidator

Purpose: Validates TLS/SSL configuration for secure WebSocket (wss://) connections to prevent protocol downgrade attacks and MITM.

Attack Scenarios:

  • Protocol downgrade attacks (POODLE, BEAST)
  • Weak cipher exploitation
  • Man-in-the-Middle via certificate forgery

Validation Checks:

  1. TLS Version: Detects deprecated SSLv2, SSLv3, TLS 1.0, TLS 1.1
  2. Cipher Suites: Identifies weak ciphers (RC4, DES, 3DES, MD5, NULL, EXPORT)
  3. Certificate Validation: Checks expiration, self-signed status, chain integrity
  4. Forward Secrecy: Verifies ECDHE or DHE key exchange
  5. TLS Renegotiation: Tests for insecure renegotiation
  6. Signature Algorithms: Detects weak algorithms (MD5, SHA1)

CVSS Scores:

  • 9.8 (CRITICAL) for deprecated TLS versions
  • 7.5 (HIGH) for weak ciphers or certificate issues
  • 5.3 (MEDIUM) for missing forward secrecy

Detailed information: See WSS Protocol Security Validation

Sources: docs/DEFENSIVE_VALIDATION.md:88-116, CHANGELOG.md:18-23


Usage Patterns

Command Line Interface

The wshawk-defensive command provides the primary CLI interface:

# Basic usage
wshawk-defensive ws://target.com

# Secure WebSocket (enables WSS validation)
wshawk-defensive wss://secure-target.com

The command exits with non-zero status if CRITICAL or HIGH findings are detected, enabling CI/CD integration with failure thresholds.

Sources: docs/DEFENSIVE_VALIDATION.md:139-147, README.md:147-149


Python API

Running All Tests

import asyncio
from wshawk.defensive_validation import run_defensive_validation

# Execute all four test categories
asyncio.run(run_defensive_validation("ws://localhost:8765"))

The run_defensive_validation() function returns a list of findings dictionaries and prints a summary report to stdout.

Sources: docs/DEFENSIVE_VALIDATION.md:149-157


Running Individual Tests

import asyncio
import websockets
from wshawk.defensive_validation import (
    DNSExfiltrationTest,
    BotDetectionValidator,
    CSWSHValidator,
    WSSSecurityValidator
)

async def test_specific_controls():
    # DNS Exfiltration Test (requires open connection)
    async with websockets.connect("ws://localhost:8765") as ws:
        dns_test = DNSExfiltrationTest("ws://localhost:8765")
        await dns_test.run_all_tests(ws)
        print(f"DNS Findings: {dns_test.findings}")
    
    # Bot Detection Test (connection-independent)
    bot_test = BotDetectionValidator("ws://localhost:8765")
    await bot_test.run_all_tests()
    print(f"Bot Findings: {bot_test.findings}")
    
    # CSWSH Test (connection-independent)
    cswsh_test = CSWSHValidator("ws://localhost:8765")
    await cswsh_test.run_all_tests()
    print(f"CSWSH Findings: {cswsh_test.findings}")
    
    # WSS Security Test (wss:// URL required)
    if url.startswith("wss://"):
        wss_test = WSSSecurityValidator("wss://localhost:8765")
        await wss_test.run_all_tests()
        print(f"WSS Findings: {wss_test.findings}")

asyncio.run(test_specific_controls())

Each test class exposes a findings attribute containing the results list.

Sources: docs/DEFENSIVE_VALIDATION.md:160-190


Findings Structure and Reporting

Finding Dictionary Schema

Each test produces findings with the following structure:

{
    'test': str,              # Test name (e.g., "CSWSH - Origin Header Validation")
    'vulnerable': bool,       # True if security control failed
    'severity': str,          # "CRITICAL" | "HIGH" | "MEDIUM" | "LOW" | "INFO"
    'description': str,       # Detailed finding description
    'recommendation': str,    # Remediation guidance
    'cvss': float,           # CVSS v3.1 score (0.0-10.0)
    'timestamp': float       # Unix timestamp
}

Sources: docs/DEFENSIVE_VALIDATION.md:238-252


CVSS Severity Mapping

| Severity | CVSS Range | Interpretation | Action Required | |----------|------------|----------------|-----------------| | CRITICAL | 9.0-10.0 | Immediate exploitation risk | Fix immediately | | HIGH | 7.0-8.9 | Significant security gap | Urgent remediation | | MEDIUM | 4.0-6.9 | Moderate risk | Address soon | | LOW | 0.1-3.9 | Minor concern | Schedule fix | | INFO | 0.0 | Informational only | No action required |

The CVSS scoring follows v3.1 methodology as documented in CVSS Scoring System.

Sources: docs/DEFENSIVE_VALIDATION.md:256-265


Console Output Example

======================================================================
WSHawk Defensive Validation Suite
======================================================================

WARNING: AUTHORIZED TESTING ONLY
These tests validate defensive security controls.
Only use with explicit written authorization.

======================================================================

[*] Testing DNS Exfiltration Prevention...
[*] Validating Bot Detection Effectiveness...
[*] Testing CSWSH Prevention...
[*] Testing WSS Protocol Security...

======================================================================
DEFENSIVE VALIDATION SUMMARY
======================================================================

Findings:
  CRITICAL: 1
  HIGH: 2
  MEDIUM: 1

[CRITICAL] CSWSH - Origin Header Validation
  Description: Server accepts WebSocket connections from untrusted origins
  CVSS: 9.1
  Recommendation: Implement Origin header validation immediately

Sources: docs/DEFENSIVE_VALIDATION.md:194-234


CI/CD Integration Example

# .github/workflows/security-validation.yml
name: Security Validation

on:
  schedule:
    - cron: '0 0 * * 0'  # Weekly
  workflow_dispatch:

jobs:
  defensive-validation:
    runs-on: ubuntu-latest
    steps:
      - name: Install WSHawk
        run: pip install wshawk
      
      - name: Run Defensive Validation
        run: wshawk-defensive wss://staging-server.com
      
      - name: Upload Results
        if: always()
        uses: actions/upload-artifact@v2
        with:
          name: security-validation-results
          path: wshawk_report_*.html

The command returns non-zero exit codes on CRITICAL/HIGH findings, causing the workflow to fail and alert security teams.

Sources: docs/DEFENSIVE_VALIDATION.md:376-411


Payload Management

The CSWSH test uses an external payload file containing 216+ malicious origins:

File: payloads/malicious_origins.txt

Format: One origin per line

https://evil-attacker.com
http://localhost:666
null
data:text/html,<script>alert(1)</script>

The CSWSHValidator.load_malicious_origins() method reads this file at runtime, enabling easy payload updates without code changes.

Sources: docs/DEFENSIVE_VALIDATION.md:268-274, CHANGELOG.md:25-30


Relationship to Offensive Testing

flowchart LR
    subgraph "Offensive Testing (Red Team)"
        OffensiveGoal["Goal: Find vulnerabilities"]
        OffensiveTests["Tests:<br/>SQL Injection<br/>XSS<br/>XXE<br/>SSRF<br/>etc."]
        OffensiveOutcome["Outcome:<br/>Vulnerability reports<br/>Exploit PoCs"]
    end
    
    subgraph "Defensive Validation (Blue Team)"
        DefensiveGoal["Goal: Validate controls"]
        DefensiveTests["Tests:<br/>DNS filtering<br/>Bot detection<br/>Origin validation<br/>TLS security"]
        DefensiveOutcome["Outcome:<br/>Control effectiveness<br/>Configuration gaps"]
    end
    
    subgraph "Shared Infrastructure"
        Payloads["Payload System"]
        CVSS["CVSS Scoring"]
        Reports["HTML Reports"]
    end
    
    OffensiveGoal --> OffensiveTests
    OffensiveTests --> OffensiveOutcome
    
    DefensiveGoal --> DefensiveTests
    DefensiveTests --> DefensiveOutcome
    
    OffensiveTests --> Payloads
    OffensiveTests --> CVSS
    DefensiveTests --> Payloads
    DefensiveTests --> CVSS
    
    CVSS --> Reports

Diagram: Offensive vs Defensive Testing Paradigms

Offensive testing (documented in Offensive Testing) discovers vulnerabilities by exploiting weaknesses. Defensive validation tests whether security controls are properly configured to prevent those same vulnerabilities. Both modes leverage shared infrastructure but serve opposite roles in the security lifecycle.

Sources: README.md:143-183, CHANGELOG.md:29-31


Extension Points

To add new defensive tests:

  1. Create a class inheriting from DefensiveValidationModule base class
  2. Implement run_all_tests() method
  3. Populate self.findings list with finding dictionaries
  4. Register the test in run_defensive_validation() function
  5. Add payload files to payloads/ directory if needed
  6. Update documentation

See Adding Extensions for detailed contribution guidelines.

Sources: docs/DEFENSIVE_VALIDATION.md:433-443