CSWSH Test (Cross-Site WebSocket Hijacking)

CSWSH Test (Cross-Site WebSocket Hijacking)

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

Purpose and Scope

This document describes the Cross-Site WebSocket Hijacking (CSWSH) validation test within WSHawk's defensive validation suite. The CSWSH test validates whether WebSocket servers properly implement Origin header validation and CSRF token requirements to prevent cross-site attacks. This module is designed for blue teams to assess the effectiveness of their CSWSH defenses.

For information about other defensive validation tests, see DNS Exfiltration Prevention Test, Bot Detection Validation Test, and WSS Protocol Security Validation. For offensive vulnerability testing, see Offensive Testing.

Sources: wshawk/defensive_validation.py:350-475, docs/DEFENSIVE_VALIDATION.md:64-85


Attack Scenario and Defensive Goal

Attack Scenario

Cross-Site WebSocket Hijacking exploits the lack of same-origin policy enforcement in WebSocket connections:

  1. Attacker hosts a malicious webpage on https://evil-attacker.com
  2. Victim with an active session visits the malicious page
  3. Malicious JavaScript initiates a WebSocket connection to the victim's legitimate application
  4. WebSocket connection inherits victim's session cookies
  5. Attacker performs privileged actions using the victim's authenticated session

Defensive Goal

The CSWSH test validates three critical security controls:

| Security Control | Purpose | |-----------------|---------| | Origin Header Validation | Ensures WebSocket server only accepts connections from trusted origins | | CSRF Token Requirement | Validates that sensitive WebSocket messages require anti-CSRF tokens | | Cross-Site Connection Prevention | Prevents malicious sites from hijacking user sessions |

Sources: wshawk/defensive_validation.py:350-366, docs/DEFENSIVE_VALIDATION.md:64-77


Architecture and Components

Component Overview

CSWSHValidator Architecture and Data Flow

graph TB
    subgraph "Class Inheritance"
        DefensiveValidationModule["DefensiveValidationModule<br/>defensive_validation.py:27-46"]
        CSWSHValidator["CSWSHValidator<br/>defensive_validation.py:350-475"]
        DefensiveValidationModule --> CSWSHValidator
    end
    
    subgraph "Instance Variables"
        target_url["self.target_url: str"]
        oast_domain["self.oast_domain: str"]
        findings["self.findings: List[Dict]"]
    end
    
    subgraph "Core Test Methods"
        test_origin["test_origin_validation()<br/>defensive_validation.py:368-428<br/>Returns: Dict"]
        test_csrf["test_csrf_token_requirement()<br/>defensive_validation.py:430-461<br/>Returns: Dict"]
        run_all["run_all_tests()<br/>defensive_validation.py:463-475<br/>Returns: List[Dict]"]
    end
    
    subgraph "Payload Loading"
        payload_file["payloads/malicious_origins.txt<br/>216+ entries"]
        open_file["open(payload_file, 'r')<br/>defensive_validation.py:383"]
        malicious_origins["malicious_origins: List[str]<br/>defensive_validation.py:384"]
        fallback["Fallback list (3 origins)<br/>defensive_validation.py:387-391"]
    end
    
    subgraph "WebSocket Connection Testing"
        ws_connect["websockets.connect()<br/>defensive_validation.py:397-400"]
        additional_headers["additional_headers={'Origin': origin}<br/>defensive_validation.py:399"]
        vulnerable_origins["vulnerable_origins: List[str]<br/>defensive_validation.py:393"]
    end
    
    subgraph "Finding Management"
        add_finding["add_finding()<br/>defensive_validation.py:35-46"]
        finding_dict["Dict: test, vulnerable, severity,<br/>description, recommendation,<br/>cvss, timestamp"]
        findings_append["self.findings.append(finding_dict)<br/>defensive_validation.py:38-46"]
    end
    
    CSWSHValidator --> target_url
    CSWSHValidator --> oast_domain
    CSWSHValidator --> findings
    
    CSWSHValidator --> test_origin
    CSWSHValidator --> test_csrf
    CSWSHValidator --> run_all
    
    payload_file --> open_file
    open_file --> malicious_origins
    open_file -->|FileNotFoundError| fallback
    fallback --> malicious_origins
    
    test_origin --> malicious_origins
    test_origin --> ws_connect
    ws_connect --> additional_headers
    additional_headers --> vulnerable_origins
    
    test_origin --> add_finding
    test_csrf --> add_finding
    add_finding --> finding_dict
    finding_dict --> findings_append
    findings_append --> findings
    
    run_all --> test_origin
    run_all --> test_csrf

Sources: wshawk/defensive_validation.py:27-46, wshawk/defensive_validation.py:350-475

Class Hierarchy

The CSWSHValidator class inherits from DefensiveValidationModule, providing standardized finding management and reporting capabilities.

classDiagram
    class DefensiveValidationModule {
        +target_url: str
        +oast_domain: str
        +findings: List
        +add_finding(test_name, vulnerable, severity, description, recommendation, cvss)
    }
    
    class CSWSHValidator {
        +test_origin_validation() Dict
        +test_csrf_token_requirement() Dict
        +run_all_tests() List[Dict]
    }
    
    DefensiveValidationModule <|-- CSWSHValidator

Sources: wshawk/defensive_validation.py:27-46, wshawk/defensive_validation.py:350-475


Test Modules

Origin Header Validation Test

The Origin header validation test attempts to establish WebSocket connections using 216+ malicious origins to identify whether the server properly validates the Origin header.

Test Implementation

The test is implemented in test_origin_validation() wshawk/defensive_validation.py:368-428:

Origin Validation Test Flow (defensive_validation.py:368-428)

flowchart TD
    Start["async def test_origin_validation(self) -> Dict:<br/>defensive_validation.py:368"]
    
    LoadPayloads["Load payload file<br/>defensive_validation.py:375-391"]
    
    InitList["vulnerable_origins = []<br/>defensive_validation.py:393"]
    
    ForLoop["for origin in malicious_origins:<br/>defensive_validation.py:395"]
    
    TryBlock["try:<br/>defensive_validation.py:396"]
    
    WSConnect["ws = await websockets.connect(<br/>self.target_url,<br/>additional_headers={'Origin': origin}<br/>)<br/>defensive_validation.py:397-400"]
    
    AppendVuln["vulnerable_origins.append(origin)<br/>defensive_validation.py:402"]
    
    CloseWS["await ws.close()<br/>defensive_validation.py:403"]
    
    ExceptPass["except Exception:<br/>pass<br/>defensive_validation.py:405-406"]
    
    CheckVuln{"if vulnerable_origins:<br/>defensive_validation.py:408"}
    
    AddFindingCrit["self.add_finding(<br/>test_name='CSWSH - Origin Header Validation',<br/>vulnerable=True,<br/>severity='CRITICAL',<br/>cvss=9.1,<br/>...<br/>)<br/>defensive_validation.py:409-418"]
    
    ReturnVuln["return {<br/>'vulnerable': True,<br/>'vulnerable_origins': vulnerable_origins<br/>}<br/>defensive_validation.py:419"]
    
    AddFindingInfo["self.add_finding(<br/>test_name='CSWSH - Origin Header Validation',<br/>vulnerable=False,<br/>severity='INFO',<br/>...<br/>)<br/>defensive_validation.py:421-427"]
    
    ReturnSafe["return {'vulnerable': False}<br/>defensive_validation.py:428"]
    
    Start --> LoadPayloads
    LoadPayloads --> InitList
    InitList --> ForLoop
    
    ForLoop --> TryBlock
    TryBlock --> WSConnect
    WSConnect --> AppendVuln
    AppendVuln --> CloseWS
    CloseWS --> ForLoop
    
    WSConnect -->|Exception| ExceptPass
    ExceptPass --> ForLoop
    
    ForLoop -->|Loop complete| CheckVuln
    
    CheckVuln -->|True| AddFindingCrit
    AddFindingCrit --> ReturnVuln
    
    CheckVuln -->|False| AddFindingInfo
    AddFindingInfo --> ReturnSafe

Sources: wshawk/defensive_validation.py:368-428

Payload Loading Mechanism

The test loads malicious origins from the payload file with a fallback mechanism:

Payload Loading Flow (defensive_validation.py:375-391)

flowchart TD
    Start["Start: test_origin_validation()"]
    
    ImportOS["import os<br/>defensive_validation.py:375"]
    
    GetPath["payload_file = os.path.join(<br/>os.path.dirname(__file__),<br/>'payloads',<br/>'malicious_origins.txt'<br/>)<br/>defensive_validation.py:376-380"]
    
    TryBlock["try:<br/>defensive_validation.py:382"]
    OpenFile["with open(payload_file, 'r') as f:<br/>defensive_validation.py:383"]
    ReadLines["malicious_origins = [<br/>line.strip() for line in f<br/>if line.strip()<br/>]<br/>defensive_validation.py:384"]
    
    ExceptBlock["except FileNotFoundError:<br/>defensive_validation.py:385"]
    FallbackList["malicious_origins = [<br/>'https://evil-attacker.com',<br/>'http://localhost:666',<br/>'null'<br/>]<br/>defensive_validation.py:387-391"]
    
    Continue["Continue with<br/>malicious_origins list"]
    
    Start --> ImportOS
    ImportOS --> GetPath
    GetPath --> TryBlock
    TryBlock --> OpenFile
    OpenFile --> ReadLines
    ReadLines --> Continue
    
    OpenFile -->|FileNotFoundError| ExceptBlock
    ExceptBlock --> FallbackList
    FallbackList --> Continue

Sources: wshawk/defensive_validation.py:375-391

Vulnerability Scoring

| Finding Status | Severity | CVSS Score | Description | |---------------|----------|------------|-------------| | Vulnerable | CRITICAL | 9.1 | Server accepts connections from untrusted origins | | Secure | INFO | 0.0 | Server properly validates Origin header |

Sources: wshawk/defensive_validation.py:409-428


CSRF Token Requirement Test

The CSRF token test validates whether the WebSocket server requires anti-CSRF tokens for sensitive operations.

Test Implementation

The test is implemented in test_csrf_token_requirement() wshawk/defensive_validation.py:430-461:

CSRF Token Test Flow (defensive_validation.py:430-461)

sequenceDiagram
    participant Method as "test_csrf_token_requirement()"
    participant WSLib as "websockets.connect()"
    participant Server as "WebSocket Server"
    participant AddFinding as "self.add_finding()"
    
    Note over Method: defensive_validation.py:430
    
    Method->>Method: try:
    Method->>WSLib: ws = await websockets.connect(self.target_url)
    Note over WSLib: defensive_validation.py:435
    
    WSLib->>Server: WebSocket handshake
    Server-->>WSLib: Connection established
    
    Method->>Method: test_payload = {<br/>"action": "sensitive_action",<br/>"data": "test"<br/>}
    Note over Method: defensive_validation.py:437-440
    
    Method->>Server: await ws.send(str(test_payload))
    Note over Method: defensive_validation.py:442
    
    Server-->>Method: response = await asyncio.wait_for(<br/>ws.recv(), timeout=5.0)
    Note over Method: defensive_validation.py:443
    
    alt 'success' in response.lower()
        Method->>AddFinding: self.add_finding(<br/>test_name="CSRF Token Requirement",<br/>vulnerable=True,<br/>severity="HIGH",<br/>cvss=7.5)
        Note over AddFinding: defensive_validation.py:446-453
        Method-->>Method: return {'vulnerable': True}
        Note over Method: defensive_validation.py:454
    else 'success' not in response
        Method-->>Method: return {'vulnerable': False}
        Note over Method: defensive_validation.py:456
    end
    
    Method->>WSLib: await ws.close()
    Note over Method: defensive_validation.py:458
    
    Method-->>Method: except Exception as e:<br/>return {'error': str(e)}
    Note over Method: defensive_validation.py:460-461

Sources: wshawk/defensive_validation.py:430-461

Payload Structure

The test sends a simple payload to trigger a sensitive action:

test_payload = {
    "action": "sensitive_action",
    "data": "test"
}

If the server processes this request successfully without requiring a CSRF token, it indicates a vulnerability.

Sources: wshawk/defensive_validation.py:437-440

Vulnerability Scoring

| Finding Status | Severity | CVSS Score | Description | |---------------|----------|------------|-------------| | Vulnerable | HIGH | 7.5 | WebSocket accepts sensitive actions without CSRF token | | Secure | N/A | 0.0 | No finding generated (test passes) |

Sources: wshawk/defensive_validation.py:446-454


Test Execution Orchestration

Test Orchestration Method

The run_all_tests() method orchestrates both CSWSH validation tests:

run_all_tests() Implementation (defensive_validation.py:463-475)

flowchart TD
    Start["async def run_all_tests(self) -> List[Dict]:<br/>defensive_validation.py:463"]
    
    InitResults["results = []<br/>defensive_validation.py:465"]
    
    PrintBanner["print('[*] Testing CSWSH Prevention...')<br/>defensive_validation.py:467"]
    
    CallOrigin["result = await self.test_origin_validation()<br/>defensive_validation.py:469"]
    
    AppendOrigin["results.append(result)<br/>defensive_validation.py:470"]
    
    CallCSRF["result = await self.test_csrf_token_requirement()<br/>defensive_validation.py:472"]
    
    AppendCSRF["results.append(result)<br/>defensive_validation.py:473"]
    
    Return["return results<br/>defensive_validation.py:475"]
    
    Start --> InitResults
    InitResults --> PrintBanner
    PrintBanner --> CallOrigin
    CallOrigin --> AppendOrigin
    AppendOrigin --> CallCSRF
    CallCSRF --> AppendCSRF
    AppendCSRF --> Return

Sources: wshawk/defensive_validation.py:463-475

Integration with Defensive Validation Suite

The CSWSH validator is integrated into the main defensive validation suite via run_defensive_validation():

flowchart TD
    RunDefensive["run_defensive_validation(target_url)"]
    
    Banner["Print validation suite banner<br/>Print warnings"]
    AllFindings["all_findings = []"]
    
    DNS["DNSExfiltrationTest"]
    Bot["BotDetectionValidator"]
    CSWSH["CSWSHValidator"]
    WSS["WSSSecurityValidator"]
    
    CSWSHInit["cswsh_test = CSWSHValidator(target_url)"]
    CSWSHRun["await cswsh_test.run_all_tests()"]
    CSWSHExtend["all_findings.extend(cswsh_test.findings)"]
    
    Summary["Print summary:<br/>CRITICAL, HIGH, MEDIUM counts<br/>Print findings details"]
    
    RunDefensive --> Banner
    Banner --> AllFindings
    AllFindings --> DNS
    DNS --> Bot
    Bot --> CSWSH
    
    CSWSH --> CSWSHInit
    CSWSHInit --> CSWSHRun
    CSWSHRun --> CSWSHExtend
    
    CSWSHExtend --> WSS
    WSS --> Summary

Sources: wshawk/defensive_validation.py:478-557, wshawk/defensive_validation.py:514-520


Malicious Origins Payload Collection

Payload File Structure

The malicious_origins.txt file contains 216+ malicious origin headers organized by attack category:

| Category | Example Origins | Count | |----------|----------------|-------| | Generic Malicious | https://evil-attacker.com, https://malicious-site.net | ~20 | | Localhost Abuse | http://localhost:666, http://127.0.0.1:8080 | ~10 | | Internal Networks | http://192.168.1.1, http://10.0.0.1, http://172.16.0.1 | ~5 | | Phishing | https://fake-bank.com, https://paypal-secure-login.net | ~10 | | Attack Techniques | https://csrf-attack.com, https://session-hijack.io | ~15 | | Vulnerability Types | https://xxe-exploit.xml, https://ssrf-target.internal | ~20 | | DDoS/Network Attacks | https://dos-attack.net, http://ddos-botnet.cc | ~30 | | Amplification Attacks | http://dns-amplification.io, http://memcached-amplification.net | ~50 | | Supply Chain | https://npm-typosquat.net, https://pypi-malicious.org | ~20 | | Testing Tools | https://playwright-exploit.net, https://puppeteer-backdoor.io | ~20 | | CI/CD Platforms | https://gitlab-ci-malicious.io, http://github-actions-exploit.net | ~16 |

Sources: wshawk/payloads/malicious_origins.txt:1-217

Payload Distribution

pie
    title Malicious Origins by Category
    "Amplification Attacks" : 50
    "Network/DDoS Attacks" : 30
    "Generic Malicious" : 20
    "Supply Chain Attacks" : 20
    "Testing Tool Exploits" : 20
    "Vulnerability Exploits" : 20
    "CI/CD Platform Exploits" : 16
    "Attack Techniques" : 15
    "Phishing" : 10
    "Localhost Abuse" : 10
    "Internal Networks" : 5

Sources: wshawk/payloads/malicious_origins.txt:1-217


Finding Generation and Reporting

Finding Structure

Each finding generated by the CSWSH validator follows the standard DefensiveValidationModule finding structure:

classDiagram
    class Finding {
        +test: str
        +vulnerable: bool
        +severity: str
        +description: str
        +recommendation: str
        +cvss: float
        +timestamp: float
        +vulnerable_origins: List[str]
    }

Sources: wshawk/defensive_validation.py:35-46

CVSS Scoring Matrix

| Test Name | Vulnerable Status | Severity | CVSS Score | Rationale | |-----------|------------------|----------|------------|-----------| | Origin Header Validation | Vulnerable | CRITICAL | 9.1 | Allows complete session hijacking from any origin | | Origin Header Validation | Secure | INFO | 0.0 | Proper validation prevents CSWSH | | CSRF Token Requirement | Vulnerable | HIGH | 7.5 | Sensitive actions possible without CSRF protection | | CSRF Token Requirement | Secure | N/A | 0.0 | No finding generated |

Sources: wshawk/defensive_validation.py:409-418, wshawk/defensive_validation.py:446-454, docs/DEFENSIVE_VALIDATION.md:82-84

Recommendation Templates

Origin Validation Failure

CRITICAL: Implement Origin header validation immediately. 
Only accept connections from trusted origins.

Sources: wshawk/defensive_validation.py:415-416

CSRF Token Missing

Implement CSRF token validation for WebSocket messages.

Sources: wshawk/defensive_validation.py:451


Usage Examples

Command-Line Interface

Via wshawk-defensive Command

# Test WebSocket server for CSWSH vulnerabilities
wshawk-defensive ws://localhost:8765

# Test secure WebSocket
wshawk-defensive wss://secure-target.com

Sources: docs/DEFENSIVE_VALIDATION.md:142-147, wshawk/defensive_cli.py:1-56

Python API

Direct CSWSHValidator Usage

import asyncio
from wshawk.defensive_validation import CSWSHValidator

async def test_cswsh():
    # Initialize validator
    cswsh_test = CSWSHValidator("ws://localhost:8765")
    
    # Run all CSWSH tests
    results = await cswsh_test.run_all_tests()
    
    # Access findings
    for finding in cswsh_test.findings:
        print(f"[{finding['severity']}] {finding['test']}")
        print(f"  Vulnerable: {finding['vulnerable']}")
        print(f"  CVSS: {finding.get('cvss', 0.0)}")
        print(f"  Description: {finding['description']}")
        print(f"  Recommendation: {finding['recommendation']}")

# Run test
asyncio.run(test_cswsh())

Sources: docs/DEFENSIVE_VALIDATION.md:182-184

Individual Test Execution

import asyncio
from wshawk.defensive_validation import CSWSHValidator

async def test_origin_only():
    cswsh_test = CSWSHValidator("ws://localhost:8765")
    
    # Run only origin validation test
    result = await cswsh_test.test_origin_validation()
    
    if result.get('vulnerable'):
        print(f"Vulnerable origins: {result['vulnerable_origins']}")
    
    print(cswsh_test.findings)

asyncio.run(test_origin_only())

Sources: wshawk/defensive_validation.py:368-428

Integration with Full Defensive Suite

import asyncio
from wshawk.defensive_validation import run_defensive_validation

# Run all defensive tests (includes CSWSH)
async def full_validation():
    findings = await run_defensive_validation("ws://localhost:8765")
    
    # Filter for CSWSH findings
    cswsh_findings = [f for f in findings if 'CSWSH' in f['test'] or 'CSRF' in f['test']]
    
    for finding in cswsh_findings:
        print(f"{finding['test']}: {finding['description']}")

asyncio.run(full_validation())

Sources: docs/DEFENSIVE_VALIDATION.md:151-157, wshawk/defensive_validation.py:478-557


Output Format

Console Output Example

[*] Testing CSWSH Prevention...

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

Findings:
  CRITICAL: 1
  HIGH: 1
  MEDIUM: 0

[CRITICAL] CSWSH - Origin Header Validation
  Description: Server accepts WebSocket connections from untrusted origins: https://evil-attacker.com, http://localhost:666. CSWSH is possible.
  Recommendation: CRITICAL: Implement Origin header validation immediately. Only accept connections from trusted origins.
  CVSS: 9.1

[HIGH] CSRF Token Requirement
  Description: WebSocket accepts sensitive actions without CSRF token.
  Recommendation: Implement CSRF token validation for WebSocket messages.
  CVSS: 7.5

Sources: docs/DEFENSIVE_VALIDATION.md:220-224, wshawk/defensive_validation.py:534-556

Finding Data Structure

Each finding returned in the findings list contains:

{
    'test': 'CSWSH - Origin Header Validation',
    'vulnerable': True,
    'severity': 'CRITICAL',
    'description': 'Server accepts WebSocket connections from untrusted origins: https://evil-attacker.com, http://localhost:666. CSWSH is possible.',
    'recommendation': 'CRITICAL: Implement Origin header validation immediately. Only accept connections from trusted origins.',
    'cvss': 9.1,
    'timestamp': 1234567890.0
}

Sources: docs/DEFENSIVE_VALIDATION.md:242-252, wshawk/defensive_validation.py:35-46


Remediation Guidance

Implementing Origin Header Validation

Python/websockets Example

async def websocket_handler(websocket, path):
    origin = websocket.request_headers.get('Origin')
    
    ALLOWED_ORIGINS = [
        'https://yourdomain.com',
        'https://app.yourdomain.com'
    ]
    
    if origin not in ALLOWED_ORIGINS:
        await websocket.close(1008, "Unauthorized origin")
        return
    
    # Continue with normal handling
    await handle_client(websocket)

Sources: docs/DEFENSIVE_VALIDATION.md:337-352

Node.js/ws Example

wss.on('connection', (ws, req) => {
    const origin = req.headers.origin;
    
    const allowedOrigins = [
        'https://yourdomain.com',
        'https://app.yourdomain.com'
    ];
    
    if (!allowedOrigins.includes(origin)) {
        ws.close(1008, 'Unauthorized origin');
        return;
    }
    
    // Continue with normal handling
    handleClient(ws);
});

Sources: docs/DEFENSIVE_VALIDATION.md:354-372

Implementing CSRF Token Validation

Add token validation to WebSocket message handlers:

  1. Generate unique token during WebSocket handshake
  2. Require token in all sensitive message payloads
  3. Validate token server-side before processing actions
  4. Rotate tokens periodically for enhanced security

Sources: docs/DEFENSIVE_VALIDATION.md:328-352


Integration Points

Entry Points

The CSWSH validator is accessible through multiple entry points:

| Entry Point | File | Purpose | |-------------|------|---------| | CLI Command | wshawk/defensive_cli.py | Direct command-line execution via wshawk-defensive | | Defensive Suite | wshawk/defensive_validation.py:478-557 | Integrated validation with DNS, Bot, and WSS tests | | Direct Import | wshawk/defensive_validation.py:350-475 | Programmatic access to CSWSHValidator class |

Sources: wshawk/defensive_cli.py:1-56, wshawk/defensive_validation.py:478-557

Dependencies

CSWSHValidator Dependency Graph

graph TB
    subgraph "CSWSHValidator Dependencies"
        CSWSH["CSWSHValidator<br/>defensive_validation.py:350"]
    end
    
    subgraph "Python Standard Library"
        Asyncio["asyncio<br/>imported line 20"]
        OS["os<br/>imported line 375"]
        Time["time<br/>imported line 23"]
    end
    
    subgraph "External Libraries"
        Websockets["websockets<br/>imported line 21<br/>used line 397, 435"]
    end
    
    subgraph "Internal Modules"
        BaseModule["DefensiveValidationModule<br/>defensive_validation.py:27-46"]
    end
    
    subgraph "Data Files"
        PayloadFile["wshawk/payloads/malicious_origins.txt<br/>216+ malicious origins<br/>loaded line 376-384"]
    end
    
    subgraph "Methods Using Dependencies"
        TestOrigin["test_origin_validation()<br/>uses: os, websockets, asyncio"]
        TestCSRF["test_csrf_token_requirement()<br/>uses: websockets, asyncio"]
        RunAll["run_all_tests()<br/>uses: asyncio"]
    end
    
    CSWSH --> BaseModule
    CSWSH --> Asyncio
    CSWSH --> Websockets
    CSWSH --> OS
    CSWSH --> Time
    CSWSH --> PayloadFile
    
    CSWSH --> TestOrigin
    CSWSH --> TestCSRF
    CSWSH --> RunAll
    
    TestOrigin --> OS
    TestOrigin --> Websockets
    TestOrigin --> Asyncio
    
    TestCSRF --> Websockets
    TestCSRF --> Asyncio
    
    RunAll --> Asyncio
    
    BaseModule --> Time

Import Statements:

Sources: wshawk/defensive_validation.py:20-25, wshawk/defensive_validation.py:350-475


Limitations and Considerations

Test Limitations

| Limitation | Description | Impact | |------------|-------------|--------| | Origin Header Only | Tests only Origin header validation, not full session security mechanisms | Does not validate session token security | | Single Payload Type | CSRF test uses generic sensitive_action payload | May not match actual application message format | | No Session Context | Tests do not establish authenticated sessions | Cannot verify session-specific protections | | Synchronous Testing | Tests origins sequentially, not in parallel | Slower execution with 216+ origins |

Sources: docs/DEFENSIVE_VALIDATION.md:428-431

Best Practices

  1. Get Authorization: Always obtain explicit written authorization before running tests
  2. Test in Staging: Run validation against staging environments before production
  3. Regular Testing: Schedule periodic validation to ensure defenses remain effective
  4. Document Findings: Track all vulnerabilities and remediation status
  5. Combine Tools: Use CSWSH test alongside other security tools for comprehensive coverage

Sources: docs/DEFENSIVE_VALIDATION.md:416-423, wshawk/defensive_validation.py:1-18


Error Handling

Exception Management

The CSWSH validator implements robust error handling to ensure test suite resilience:

Exception Handling Patterns

flowchart TD
    subgraph "test_origin_validation() Error Handling"
        OriginTry["try:<br/>defensive_validation.py:396"]
        OriginConnect["ws = await websockets.connect(...)<br/>defensive_validation.py:397"]
        OriginSuccess["Success: append to vulnerable_origins<br/>defensive_validation.py:402"]
        OriginExcept["except Exception:<br/>pass<br/>defensive_validation.py:405-406"]
        OriginContinue["Continue to next origin"]
        
        OriginTry --> OriginConnect
        OriginConnect -->|Success| OriginSuccess
        OriginConnect -->|Any Exception| OriginExcept
        OriginExcept --> OriginContinue
    end
    
    subgraph "test_csrf_token_requirement() Error Handling"
        CSRFTry["try:<br/>defensive_validation.py:434"]
        CSRFConnect["ws = await websockets.connect(...)<br/>defensive_validation.py:435"]
        CSRFTest["Test logic execution"]
        CSRFExcept["except Exception as e:<br/>return {'error': str(e)}<br/>defensive_validation.py:460-461"]
        
        CSRFTry --> CSRFConnect
        CSRFConnect --> CSRFTest
        CSRFConnect -->|Exception| CSRFExcept
        CSRFTest -->|Exception| CSRFExcept
    end

Exception Handling Strategy:

| Test Method | Exception Type | Handling Approach | Line Reference | |------------|---------------|-------------------|----------------| | test_origin_validation() | Any Exception during connection | Silent pass, continue to next origin | defensive_validation.py:405-406 | | test_csrf_token_requirement() | Any Exception | Return error dict: {'error': str(e)} | defensive_validation.py:460-461 |

This design ensures:

  • Individual origin test failures don't halt the entire test suite
  • Error information is captured and returned for debugging
  • The defensive validation suite completes even with connectivity issues

Sources: wshawk/defensive_validation.py:396-406, wshawk/defensive_validation.py:434-461


Related Documentation

Sources: docs/DEFENSIVE_VALIDATION.md:1-463