Path Traversal and SSTI

Path Traversal and SSTI

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

Purpose and Scope

This document describes WSHawk's detection mechanisms for Path Traversal and Server-Side Template Injection (SSTI) vulnerabilities in WebSocket communications. These vulnerability classes allow attackers to access unauthorized files or execute arbitrary code on the server by manipulating file paths or template expressions transmitted through WebSocket messages.

Path Traversal and SSTI detection are part of WSHawk's comprehensive vulnerability scanning suite. For information about other injection vulnerabilities, see Injection Vulnerabilities. For XXE and SSRF detection, see XXE and SSRF Detection.


Vulnerability Overview

| Vulnerability Type | Severity | Description | Attack Vector | |-------------------|----------|-------------|---------------| | Path Traversal | HIGH | Unauthorized access to files outside intended directories by manipulating file path parameters | ../../etc/passwd, ..\..\windows\win.ini | | SSTI (Server-Side Template Injection) | CRITICAL | Execution of arbitrary code by injecting template expressions that are evaluated server-side | {{7*7}}, ${__import__('os').system('ls')} |

Both vulnerabilities exploit insufficient input validation when user-controlled data is used in file operations (Path Traversal) or template rendering (SSTI).

Sources: wshawk/main.py:583-663


Detection Architecture

High-Level Detection Flow

graph TB
    subgraph "Payload Sources"
        PTPayloads["WSPayloads.get_path_traversal()<br/>path_traversal.txt<br/>50+ patterns"]
        SSTIPayloads["WSPayloads.get_ssti()<br/>ssti.txt<br/>Template expressions"]
    end
    
    subgraph "Scanner Selection"
        Legacy["Legacy Scanner<br/>WSHawk.__main__"]
        V2["Advanced Scanner<br/>WSHawkV2.scanner_v2"]
    end
    
    subgraph "Message Construction"
        MsgAnalyzer["MessageAnalyzer<br/>detect format"]
        ContextInject["inject_payload_into_message()<br/>smart field injection"]
        BasicInject["Basic Injection<br/>JSON wrapper"]
    end
    
    subgraph "WebSocket Communication"
        Send["ws.send(message)"]
        Recv["ws.recv() with timeout"]
        RateLimit["Rate Limiting<br/>0.05-0.1s delay"]
    end
    
    subgraph "Response Analysis"
        PTIndicators["Path Traversal Indicators<br/>root:, /etc/passwd<br/>boot.ini, [extensions]"]
        SSTIIndicators["SSTI Indicators<br/>Payload reflection<br/>Execution artifacts"]
        Verifier["VulnerabilityVerifier<br/>verify_path_traversal()<br/>confidence scoring"]
    end
    
    subgraph "Results"
        VulnDB[("vulnerabilities list<br/>type, severity<br/>confidence, payload")]
        Report["HTML/JSON/CSV/SARIF<br/>reports with evidence"]
    end
    
    PTPayloads --> Legacy
    PTPayloads --> V2
    SSTIPayloads --> Legacy
    
    Legacy --> BasicInject
    V2 --> MsgAnalyzer
    MsgAnalyzer --> ContextInject
    
    BasicInject --> Send
    ContextInject --> Send
    Send --> Recv
    Recv --> RateLimit
    
    RateLimit --> PTIndicators
    RateLimit --> SSTIIndicators
    PTIndicators --> Verifier
    SSTIIndicators --> Verifier
    
    Verifier --> VulnDB
    VulnDB --> Report
    
    style PTPayloads fill:#f9f9f9
    style SSTIPayloads fill:#f9f9f9
    style Verifier fill:#fff3cd
    style VulnDB fill:#d4edda

Sources: wshawk/main.py:583-663, wshawk/scanner_v2.py:409-448


Path Traversal Detection

Methodology

Path Traversal detection tests whether WebSocket messages containing file path manipulation sequences can access unauthorized files. The scanner injects directory traversal patterns and analyzes responses for file content indicators.

Payload Loading

The WSPayloads class loads path traversal payloads from an external file using lazy loading with caching:

WSPayloads.get_path_traversal() -> List[str]
  ├─ load_payloads('path_traversal.txt')
  ├─ Cache check: _payloads_cache['path_traversal.txt']
  └─ File loading via importlib.resources or filesystem fallback

The payload file contains 50+ path traversal patterns including:

  • Unix-style: ../../etc/passwd, ../../../etc/shadow
  • Windows-style: ..\..\..\windows\win.ini, ..\..\boot.ini
  • URL-encoded: %2e%2e%2f, ..%2F..%2F
  • Double-encoded: %252e%252e%252f
  • Null byte injection: ../../etc/passwd%00

Sources: wshawk/main.py:121-122, wshawk/main.py:70-102

Legacy Scanner Implementation

The legacy scanner (WSHawk class) implements basic path traversal testing:

graph LR
    Start["test_path_traversal()"] --> Connect["await self.connect()"]
    Connect --> LoadPayloads["WSPayloads.get_path_traversal()"]
    LoadPayloads --> Subset["payloads[:payload_count]"]
    
    Subset --> Loop["for payload in payloads"]
    Loop --> Construct["json.dumps({'file': payload, 'action': 'read'})"]
    Construct --> Send["await ws.send(message)"]
    Send --> Wait["await ws.recv(timeout=2.0)"]
    
    Wait --> Check["Check file_indicators in response"]
    Check -->|Match| LogVuln["Logger.vuln()<br/>Append to vulnerabilities"]
    Check -->|No match| Sleep["await asyncio.sleep(0.1)"]
    
    LogVuln --> Sleep
    Sleep --> Loop
    Loop --> Close["await ws.close()"]

Detection Indicators wshawk/main.py:604:

  • 'root:' - Unix /etc/passwd content
  • '/etc/passwd' - Direct file path
  • 'boot.ini' - Windows boot configuration
  • '[extensions]' - Windows INI file section

Vulnerability Record Structure wshawk/main.py:607-614:

{
    'type': 'Path Traversal',
    'severity': 'HIGH',
    'description': 'Path traversal vulnerability detected',
    'payload': payload,
    'recommendation': 'Validate and sanitize file paths'
}

Sources: wshawk/main.py:583-623

Advanced Scanner v2 Implementation

The advanced scanner (WSHawkV2 class) adds automated verification and context-aware injection:

graph TB
    Start["test_path_traversal_v2()"] --> Connect["await self.connect()"]
    Connect --> LoadPayloads["WSPayloads.get_path_traversal()[:50]"]
    
    LoadPayloads --> Loop["for payload in payloads"]
    Loop --> CheckFormat{"learning_complete &&<br/>MessageFormat.JSON?"}
    
    CheckFormat -->|Yes| ContextInject["message_analyzer.<br/>inject_payload_into_message()"]
    CheckFormat -->|No| BasicWrap["json.dumps({'action': 'read_file',<br/>'filename': payload})"]
    
    ContextInject --> SendMulti["for msg in injected_messages"]
    BasicWrap --> SendSingle["await ws.send(msg)"]
    SendMulti --> SendSingle
    
    SendSingle --> Recv["await ws.recv(timeout=2.0)"]
    Recv --> Verify["verifier.verify_path_traversal(<br/>response, payload)"]
    
    Verify --> CheckConf{"confidence !=<br/>ConfidenceLevel.LOW?"}
    CheckConf -->|Yes| LogVuln["Logger.vuln(f'Path Traversal [{confidence.value}]')"]
    CheckConf -->|No| Sleep["await asyncio.sleep(0.05)"]
    
    LogVuln --> AppendVuln["vulnerabilities.append({<br/>type, severity, confidence,<br/>description, payload})"]
    AppendVuln --> Sleep
    Sleep --> Loop

Key Enhancements:

  1. Context-Aware Injection: The MessageAnalyzer detects message format (JSON/XML/protobuf) and injects payloads into all identified fields automatically wshawk/scanner_v2.py:418-419.

  2. Automated Verification: The VulnerabilityVerifier.verify_path_traversal() method provides confidence scoring (LOW/MEDIUM/HIGH/CRITICAL) based on multiple indicators wshawk/scanner_v2.py:426.

  3. Reduced Payload Count: Uses 50 payloads instead of all available for faster scanning wshawk/scanner_v2.py:414.

  4. Faster Rate Limiting: 0.05s delay vs 0.1s in legacy scanner wshawk/scanner_v2.py:444.

Sources: wshawk/scanner_v2.py:409-448

Path Traversal Verification Logic

The VulnerabilityVerifier class implements multi-indicator verification:

graph TB
    Input["verify_path_traversal(<br/>response, payload)"] --> NormalizeResp["response.lower()"]
    
    NormalizeResp --> CheckIndicators["Check indicators:<br/>- 'root:' (passwd file)<br/>- '/etc/passwd'<br/>- 'boot.ini'<br/>- '[extensions]' (INI)"]
    
    CheckIndicators --> MatchCount{"How many<br/>indicators?"}
    
    MatchCount -->|0| ReturnLow["return (False,<br/>ConfidenceLevel.LOW,<br/>'No indicators')"]
    
    MatchCount -->|1| CheckContent{"Strong content<br/>pattern?"}
    CheckContent -->|Yes| ReturnMedium["return (True,<br/>ConfidenceLevel.MEDIUM,<br/>'File content detected')"]
    CheckContent -->|No| ReturnLow
    
    MatchCount -->|2+| ReturnHigh["return (True,<br/>ConfidenceLevel.HIGH,<br/>'Multiple indicators')"]

This verification is used by the v2 scanner to filter out false positives and provide actionable confidence levels.

Sources: wshawk/scanner_v2.py:426, wshawk/vulnerability_verifier.py (referenced)


SSTI Detection

Methodology

Server-Side Template Injection detection tests whether template expressions in WebSocket messages are evaluated server-side. The scanner injects template syntax from common template engines (Jinja2, Twig, Freemarker, etc.) and checks if the expressions are executed rather than sanitized.

Payload Loading

SSTI payloads are loaded from an external file containing template expressions:

WSPayloads.get_ssti() -> List[str]
  ├─ load_payloads('ssti.txt')
  └─ Template expressions for multiple engines

Common SSTI Patterns:

  • Jinja2/Flask: {{7*7}}, {{config.items()}}, {{''.__class__.__mro__[1].__subclasses__()}}
  • Twig: {{7*'7'}}, {{_self.env.registerUndefinedFilterCallback("exec")}}
  • Freemarker: ${7*7}, <#assign ex="freemarker.template.utility.Execute"?new()>
  • Velocity: #set($x=7*7)$x
  • ERB (Ruby): <%= 7*7 %>, <%= system("whoami") %>

Sources: wshawk/main.py:133-134

SSTI Detection Implementation

The legacy scanner implements SSTI testing with reflection-based detection:

graph TB
    Start["test_ssti()"] --> Connect["await self.connect()"]
    Connect --> LoadPayloads["WSPayloads.get_ssti()"]
    LoadPayloads --> Subset["payloads[:payload_count]"]
    
    Subset --> Loop["for payload in payloads"]
    Loop --> Construct["json.dumps({'template': payload,<br/>'action': 'render'})"]
    Construct --> Send["await ws.send(message)"]
    Send --> Wait["await ws.recv(timeout=2.0)"]
    
    Wait --> CheckReflection{"payload in response?"}
    CheckReflection -->|Yes| EvaluateType{"Check execution<br/>artifacts"}
    CheckReflection -->|No| Sleep["await asyncio.sleep(0.1)"]
    
    EvaluateType -->|Executed| LogCritical["Logger.vuln('SSTI detected')<br/>Severity: CRITICAL"]
    EvaluateType -->|Reflected only| LogHigh["Potential SSTI<br/>Severity: HIGH"]
    
    LogCritical --> AppendVuln["vulnerabilities.append({<br/>type: 'Server Side Template Injection'})"]
    LogHigh --> AppendVuln
    AppendVuln --> Sleep
    Sleep --> Loop

Detection Logic wshawk/main.py:645:

if response and payload in response:
    # Payload was reflected - potential SSTI
    # Check if it was executed (e.g., {{7*7}} becomes 49)
    # or just reflected ({{7*7}} appears as-is)

Vulnerability Record wshawk/main.py:647-654:

{
    'type': 'Server Side Template Injection',
    'severity': 'CRITICAL',
    'description': 'SSTI payload reflected/executed',
    'payload': payload,
    'recommendation': 'Use safe template rendering and input validation'
}

Sources: wshawk/main.py:625-663

SSTI vs XSS Distinction

SSTI detection differs from XSS detection in several key ways:

| Aspect | SSTI | XSS | |--------|------|-----| | Execution Context | Server-side template engine | Client-side browser JavaScript | | Severity | CRITICAL (RCE potential) | HIGH (client-side attacks) | | Payload Syntax | {{7*7}}, ${exec()} | <script>alert(1)</script> | | Detection Method | Template expression evaluation | Script tag reflection | | Verification | Response analysis for execution | Browser verification with Playwright |

Note: While both involve payload reflection, SSTI can lead to Remote Code Execution (RCE) on the server, making it more critical. For XSS detection details, see Cross-Site Scripting (XSS) Detection.

Sources: wshawk/main.py:625-663, wshawk/main.py:399-438


Message Injection Strategies

Basic Injection (Legacy Scanner)

The legacy scanner wraps payloads in predetermined JSON structures:

Path Traversal:

message = json.dumps({"file": payload, "action": "read"})
# Example: {"file": "../../etc/passwd", "action": "read"}

SSTI:

message = json.dumps({"template": payload, "action": "render"})
# Example: {"template": "{{7*7}}", "action": "render"}

Sources: wshawk/main.py:600, wshawk/main.py:642

Context-Aware Injection (Scanner v2)

The advanced scanner uses the MessageAnalyzer to automatically inject payloads into all detected fields:

graph LR
    Base["base_message<br/>(sample from learning)"] --> Analyzer["MessageAnalyzer.<br/>detect_format()"]
    Analyzer --> Format{"Format?"}
    
    Format -->|JSON| ExtractFields["extract JSON keys"]
    Format -->|XML| ExtractTags["extract XML elements"]
    Format -->|Text| UseWhole["use entire message"]
    
    ExtractFields --> Inject["inject_payload_into_message()"]
    ExtractTags --> Inject
    UseWhole --> Inject
    
    Inject --> Multiple["List of injected messages<br/>(one per field)"]
    
    Multiple --> Example1["{'username': '../../etc/passwd',<br/>'action': 'search'}"]
    Multiple --> Example2["{'username': 'test',<br/>'query': '../../etc/passwd'}"]
    Multiple --> Example3["{'username': 'test',<br/>'file': '../../etc/passwd'}"]

This approach increases coverage by testing all input vectors automatically without hardcoding field names.

Sources: wshawk/scanner_v2.py:418-419


Integration with Scanning Pipeline

Execution Context

Both Path Traversal and SSTI tests are invoked during comprehensive scans:

Legacy Scanner wshawk/main.py:863-890:

async def run_all_tests(self):
    await self.test_connection()
    await asyncio.gather(
        self.test_origin_bypass(),
        self.test_sql_injection(),
        self.test_xss(),
        self.test_command_injection(),
        # ... other tests ...
        return_exceptions=True
    )

Note: The legacy run_all_tests() does not include test_path_traversal() or test_ssti() by default. These must be called explicitly or added to the test suite.

Advanced Scanner v2 wshawk/scanner_v2.py:593-636:

async def run_heuristic_scan(self):
    await self.learning_phase(ws, duration=5)
    await self.test_sql_injection_v2(ws)
    await self.test_xss_v2(ws)
    await self.test_command_injection_v2(ws)
    await self.test_path_traversal_v2(ws)  # Included in v2
    await self.test_xxe_v2(ws)
    await self.test_nosql_injection_v2(ws)
    await self.test_ssrf_v2(ws)
    # Note: SSTI test not present in v2

Sources: wshawk/main.py:863-890, wshawk/scanner_v2.py:593-636

CLI Integration

Path Traversal and SSTI tests run automatically when using WSHawk CLI commands:

Quick Scan (uses scanner_v2):

wshawk ws://target.com
# Runs test_path_traversal_v2() automatically

Advanced Scan:

wshawk-advanced ws://target.com --full
# Includes all verification features

Interactive Mode:

wshawk-interactive
# Select "Path Traversal" or "SSTI" from menu

Sources: wshawk/main.py:1095-1155, wshawk/advanced_cli.py:12-283


Payload Limiting and Performance

Payload Count Control

Both scanners support limiting the number of payloads tested to balance thoroughness vs speed:

Legacy Scanner:

WSHawk(url, max_payloads=50)
# Tests first 50 payloads from each category
# None = test ALL payloads

Scanner v2:

# Hardcoded limits for performance
path_traversal: 50 payloads
ssti: payload_count from config

Sources: wshawk/main.py:588, wshawk/scanner_v2.py:414

Rate Limiting

Rate limiting prevents overwhelming the target server and avoids detection:

| Scanner | Delay Between Payloads | Implementation | |---------|------------------------|----------------| | Legacy | 0.1s | await asyncio.sleep(0.1) | | Scanner v2 | 0.05s | await asyncio.sleep(0.05) + TokenBucketRateLimiter |

Sources: wshawk/main.py:616, wshawk/scanner_v2.py:444


Reporting and Remediation

Vulnerability Reporting Format

Detected Path Traversal and SSTI vulnerabilities are included in all report formats:

HTML Report - Displays vulnerability cards with:

  • Vulnerability type and severity badge
  • Description with payload details
  • Response snippet (first 200 chars)
  • Remediation recommendation

JSON Export:

{
  "type": "Path Traversal",
  "severity": "HIGH",
  "confidence": "HIGH",
  "description": "Path traversal vulnerability detected",
  "payload": "../../etc/passwd",
  "response_snippet": "root:x:0:0:root:/root:/bin/bash...",
  "recommendation": "Validate and sanitize file paths"
}

SARIF Export - For CI/CD integration with GitHub Security.

Sources: wshawk/main.py:928-1092, wshawk/scanner_v2.py:785-806

Remediation Recommendations

| Vulnerability | Recommendation | Implementation Guidance | |---------------|----------------|-------------------------| | Path Traversal | "Validate and sanitize file paths" | Use whitelisting, canonical path resolution, chroot jails | | SSTI | "Use safe template rendering and input validation" | Disable template execution in user input, use sandboxed template engines |

Sources: wshawk/main.py:612-613, wshawk/main.py:652-653


Dependencies and Requirements

Path Traversal and SSTI detection require:

Core Dependencies:

  • websockets>=12.0 - WebSocket client implementation
  • aiohttp>=3.9.0 - Async HTTP for discovery
  • pyyaml>=6.0.1 - Configuration file parsing

Payload Files Required:

  • wshawk/payloads/path_traversal.txt
  • wshawk/payloads/ssti.txt

Optional Enhancements:

  • playwright>=1.40.0 - Not used for Path Traversal/SSTI but available for XSS verification

Sources: requirements.txt:1-25


Summary

WSHawk provides comprehensive Path Traversal and SSTI detection through:

  1. 50+ Path Traversal payloads testing directory traversal patterns across Unix and Windows platforms
  2. Template injection payloads for multiple server-side template engines (Jinja2, Twig, Freemarker, etc.)
  3. Dual implementation: Legacy scanner with basic detection, v2 scanner with automated verification
  4. Context-aware injection: Automatic payload insertion into all detected message fields
  5. Confidence scoring: Multi-indicator verification with LOW/MEDIUM/HIGH/CRITICAL levels
  6. Rate limiting: Configurable delays to prevent server overload
  7. Multiple report formats: HTML, JSON, CSV, SARIF with detailed evidence

For related vulnerability detection, see Injection Vulnerabilities for SQL/NoSQL/Command injection, and XXE and SSRF Detection for XML and request forgery attacks.