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:
-
Context-Aware Injection: The
MessageAnalyzerdetects message format (JSON/XML/protobuf) and injects payloads into all identified fields automatically wshawk/scanner_v2.py:418-419. -
Automated Verification: The
VulnerabilityVerifier.verify_path_traversal()method provides confidence scoring (LOW/MEDIUM/HIGH/CRITICAL) based on multiple indicators wshawk/scanner_v2.py:426. -
Reduced Payload Count: Uses 50 payloads instead of all available for faster scanning wshawk/scanner_v2.py:414.
-
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 implementationaiohttp>=3.9.0- Async HTTP for discoverypyyaml>=6.0.1- Configuration file parsing
Payload Files Required:
wshawk/payloads/path_traversal.txtwshawk/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:
- 50+ Path Traversal payloads testing directory traversal patterns across Unix and Windows platforms
- Template injection payloads for multiple server-side template engines (Jinja2, Twig, Freemarker, etc.)
- Dual implementation: Legacy scanner with basic detection, v2 scanner with automated verification
- Context-aware injection: Automatic payload insertion into all detected message fields
- Confidence scoring: Multi-indicator verification with LOW/MEDIUM/HIGH/CRITICAL levels
- Rate limiting: Configurable delays to prevent server overload
- 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.