Desktop Application Architecture
Desktop Application Architecture
The following files were used as context for generating this wiki page:
- desktop/index.js
- desktop/preload.js
- desktop/src/renderer.js
- desktop/src/index.html
- desktop/package.json
- wshawk/gui_bridge.py
- wshawk-bridge.spec
- docs/DESKTOP_V3_GUIDE.md
Purpose and Scope
This document provides a complete technical reference for the WSHawk Desktop application architecture. It covers the dual-process sidecar model, inter-process communication protocols, component responsibilities, and the build pipeline that produces platform-specific installers.
For the WebSocket scanner engine internals, see Core Architecture. For individual web pentesting tools, see Desktop Web Pentest Toolkit. For the interceptor and advanced features, see Desktop Advanced Features.
Sources: docs/DESKTOP_V3_GUIDE.md:1-100
Dual-Process Sidecar Model
WSHawk Desktop uses a sidecar architecture where an Electron frontend (JavaScript/HTML/CSS) communicates with a Python backend server over HTTP and Socket.IO. The two processes run independently and communicate via localhost networking.
graph TB
subgraph Electron["Electron App (JavaScript)"]
Main["index.js<br/>(Main Process)"]
Preload["preload.js<br/>(Secure Bridge)"]
Renderer["renderer.js<br/>(UI Logic — 4,641 lines)"]
Main -->|IPC| Preload
Preload -->|contextBridge| Renderer
end
Main -->|"Spawns as child process"| Bridge
Renderer -->|"REST API (fetch)"| Bridge
Renderer <-->|"Socket.IO<br/>(real-time events)"| Bridge
subgraph Backend["Python Backend (Port 8080)"]
Bridge["gui_bridge.py<br/>(FastAPI + Socket.IO)"]
Bridge --> Scanner["scanner_v2.py<br/>(WebSocket Scanner)"]
Bridge --> Mutator["payload_mutator.py<br/>(Mutation Engine)"]
Bridge --> Discovery["ws_discovery.py<br/>(Endpoint Finder)"]
Bridge --> DB["db_manager.py<br/>(SQLite)"]
Bridge --> WebPentest["web_pentest/<br/>(22 HTTP Engines)"]
Bridge --> SmartPayloads["smart_payloads/<br/>(SPE Engine)"]
end
style Electron fill:#1a1a2e,stroke:#6c63ff,color:#fff
style Backend fill:#0f3460,stroke:#e94560,color:#fff
Why a Sidecar?
The sidecar model was chosen over alternatives for several reasons:
| Alternative | Problem | |---|---| | Python GUI (tkinter/Qt) | Poor UI/UX, no modern web technologies, limited animation support | | Electron-only (no Python) | Would require rewriting the scanner, mutation engine, and all 22 web pentest tools in JavaScript | | Embedded Python (python-shell) | Fragile, no real-time streaming, blocks the main thread | | Sidecar (chosen) | Full Python ecosystem for security tools + full web stack for UI. Each process can crash independently |
The tradeoff is binary size (the compiled Python sidecar is ~80-120MB depending on platform) and startup time (~2-3 seconds for sidecar initialization).
Sources: docs/DESKTOP_V3_GUIDE.md:49-100
Component Breakdown
Electron Layer
| Component | File | Lines | Responsibility |
|---|---|---|---|
| Main Process | desktop/index.js | ~230 | Window management, Python sidecar lifecycle, IPC handlers for file dialogs and window controls |
| Preload Script | desktop/preload.js | ~40 | Secure IPC bridge via contextBridge. Whitelisted channels only — no raw ipcRenderer exposure |
| Renderer | desktop/src/renderer.js | 4,641 | All UI logic. Socket.IO client, tool panel interactions, real-time result rendering, theme system |
| HTML Shell | desktop/src/index.html | ~2,200 | Single-page layout containing all views, modals, tool panels, and the sidebar navigation |
| Styles | desktop/src/style.css | ~3,800 | Dark-mode design system with CSS custom properties, glassmorphism effects, and responsive layout |
Python Backend Layer
| Component | File | Lines | Responsibility |
|---|---|---|---|
| GUI Bridge | wshawk/gui_bridge.py | 1,342 | FastAPI server + Socket.IO for real-time communication. Exposes 50+ REST endpoints and 20+ Socket.IO events |
| Scanner Engine | wshawk/scanner_v2.py | ~900 | WebSocket vulnerability scanner with 7 test suites |
| Payload Mutator | wshawk/payload_mutator.py | ~400 | WAF-evasion mutation engine with 8 bypass strategies |
| WS Discovery | wshawk/ws_discovery.py | ~300 | WebSocket endpoint discovery via HTTP probing and JS analysis |
| DB Manager | wshawk/db_manager.py | ~250 | SQLite wrapper for scan history and session persistence |
| Web Pentest | wshawk/web_pentest/ | 22 files | HTTP security tools (crawler, fuzzer, port scanner, etc.) |
| Smart Payloads | wshawk/smart_payloads/ | 3 files | Genetic algorithm payload evolution system |
Sources: docs/DESKTOP_V3_GUIDE.md:82-108
Communication Protocol
The frontend and backend communicate through two channels: REST API for request-response operations and Socket.IO for real-time streaming.
sequenceDiagram
participant UI as Renderer (Electron)
participant Bridge as gui_bridge.py
participant Engine as Scanner / Tool Engine
UI->>Bridge: REST POST /scan/start
Bridge->>Engine: asyncio.create_task()
Bridge-->>UI: {status: "started"}
loop Real-time streaming
Engine-->>Bridge: Result found
Bridge-->>UI: sio.emit('vulnerability_found')
end
Engine-->>Bridge: Scan complete
Bridge-->>UI: sio.emit('scan_complete')
Channel Responsibilities
| Channel | Protocol | Use Cases |
|---|---|---|
| REST API | HTTP fetch() to http://127.0.0.1:8080 | Start scan, send request, get payloads, export report, stop scan |
| Socket.IO | Persistent WebSocket connection | Scan progress, fuzzer results, port discoveries, intercepted frames, vulnerability findings |
| IPC | Electron ipcMain / ipcRenderer | File dialogs (save/open project), window controls (minimize/maximize/close) |
REST API Surface
The gui_bridge.py exposes approximately 50 REST endpoints organized by feature area:
| Category | Example Endpoints | HTTP Methods |
|---|---|---|
| Scanner | /scan/start, /scan/stop, /scan/status | POST, GET |
| Interceptor | /interceptor/action, /interceptor/toggle | POST |
| Request Forge | /forge/send | POST |
| Web Pentest | /web/crawl, /web/fuzz, /web/portscan, /web/dirscan | POST |
| Payloads | /payloads/{category}, /payloads/custom | GET, POST |
| Reports | /web/report, /report/export | POST |
| Config | /system/info, /auth/build | GET, POST |
Socket.IO Events
| Event | Direction | Data |
|---|---|---|
| vulnerability_found | Server → Client | {type, severity, payload, evidence, cvss} |
| scan_progress | Server → Client | {phase, current, total, percentage} |
| intercepted_frame | Server → Client | {id, direction, data, timestamp} |
| fuzzer_result | Server → Client | {payload, status_code, response_size, time} |
| port_found | Server → Client | {port, service, banner, state} |
| scan_complete | Server → Client | {total_vulns, duration, report_path} |
| web_tool_result | Server → Client | {tool, finding_type, data} |
Sources: docs/DESKTOP_V3_GUIDE.md:104-140, wshawk/gui_bridge.py:1-100
Sidecar Lifecycle
Startup Sequence
sequenceDiagram
participant App as app.whenReady()
participant Main as index.js
participant Sidecar as wshawk-bridge
participant Window as BrowserWindow
participant Renderer as renderer.js
App->>Main: checkPythonDependency()
Main->>Main: execSync('python3 --version')
App->>Main: startPythonSidecar()
alt Packaged (production)
Main->>Main: Resolve resources/bin/wshawk-bridge
Main->>Main: chmod +x (macOS/Linux)
Main->>Sidecar: spawn(binary)
else Development
Main->>Sidecar: spawn('python3', ['-m', 'wshawk.gui_bridge'])
end
Sidecar->>Sidecar: FastAPI + Socket.IO init
Sidecar->>Sidecar: uvicorn.run(port=8080)
App->>Main: createWindow()
Main->>Window: loadFile('src/index.html')
Window->>Renderer: DOMContentLoaded
Renderer->>Sidecar: io.connect('http://127.0.0.1:8080')
Sidecar-->>Renderer: Socket.IO 'connect' event
Renderer->>Renderer: connPill = 'Connected'
Platform-Specific Binary Resolution
In production (packaged) mode, index.js resolves the sidecar binary path based on the platform:
| Platform | Binary Path | Notes |
|---|---|---|
| Linux | process.resourcesPath/bin/wshawk-bridge | Permissions fixed via fs.chmodSync(0o755) |
| macOS | process.resourcesPath/bin/wshawk-bridge | DMG packaging strips execute permissions; chmod required |
| Windows | process.resourcesPath/bin/wshawk-bridge.exe | No permission fix needed |
In development mode, the renderer connects to python3 -m wshawk.gui_bridge running from the project root.
Shutdown Sequence
When the user closes the application:
window-all-closedevent fires inindex.jspythonProcess.kill()terminates the sidecar- On macOS, the app stays in the dock (
process.platform !== 'darwin'check) app.quit()terminates the Electron process
Sources: desktop/index.js:31-120, docs/DESKTOP_V3_GUIDE.md:49-100
Security Model
Context Isolation
The Electron app uses strict context isolation to prevent the renderer from accessing Node.js APIs:
// index.js
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
nodeIntegration: false, // No require() in renderer
contextIsolation: true, // Separate JS contexts
}
The preload script exposes only whitelisted IPC channels:
// preload.js
contextBridge.exposeInMainWorld('electronAPI', {
openProject: () => ipcRenderer.invoke('dialog:openProject'),
saveProject: (data) => ipcRenderer.invoke('dialog:saveProject', data),
exportReport: (html) => ipcRenderer.invoke('dialog:exportReport', html),
exportExploit:(data) => ipcRenderer.invoke('dialog:exportExploit', data),
minimize: () => ipcRenderer.send('window:minimize'),
maximize: () => ipcRenderer.send('window:maximize'),
close: () => ipcRenderer.send('window:close'),
});
Network Isolation
The Python sidecar binds exclusively to 127.0.0.1:8080 — it is not accessible from the network. The CORSMiddleware allows * origins only because communication is localhost-only.
Binary Integrity
The sidecar is compiled by PyInstaller into a self-contained binary. All Python dependencies are bundled inside the binary — no system Python installation is required in production mode.
Sources: desktop/index.js:16-21, desktop/preload.js:1-40
Operating Modes
The Desktop application has three progressively expanding modes:
Standard Mode
Available tools:
- WebSocket scanner dashboard
- Request Forge (manual WebSocket frame construction)
- Findings panel (vulnerability cards with severity badges)
- Traffic history (chronological frame log)
- System log (timestamped backend events)
Advanced Mode
Everything in Standard, plus:
- Payload Blaster — High-speed WebSocket fuzzer
- Interceptor — Full-duplex MitM proxy
- Endpoint Map — Automated WebSocket discovery
- Auth Builder — Multi-step authentication sequences
- Mutation Lab — Interactive payload mutation
- Scheduler — Recurring scan automation
- Codec — Encoder/decoder toolkit
- Comparer — Response diff viewer
- Notes — In-app markdown notes
Web Pentest Mode
Everything in Advanced, plus all 22 HTTP security tools organized into six phases. See Desktop Web Pentest Toolkit for complete tool documentation.
Mode Selection: The user toggles between modes via the sidebar. Mode state is persisted in localStorage.
Sources: docs/DESKTOP_V3_GUIDE.md:118-200
Build Pipeline
PyInstaller Compilation
The Python backend is compiled into a standalone binary using PyInstaller:
pyinstaller wshawk-bridge.spec
The .spec file defines:
| Configuration | Value |
|---|---|
| Entry point | wshawk/gui_bridge.py |
| Hidden imports | 80+ modules (uvicorn internals, starlette, socketio, all web_pentest engines) |
| Excluded modules | tkinter, matplotlib, numpy, pandas, scipy, pytest, playwright |
| Output | Single binary (dist/wshawk-bridge or dist/wshawk-bridge.exe) |
| Binary size | ~80-120MB depending on platform |
Electron Packaging
The desktop app is packaged using electron-builder:
cd desktop && npx electron-builder --publish never
| Platform | Output Format | Size |
|---|---|---|
| Linux | .AppImage, .pacman, .deb | ~180-220MB |
| Windows | .exe (NSIS installer) | ~160-200MB |
| macOS | .dmg | ~170-210MB |
CI/CD Pipeline
The GitHub Actions workflow (.github/workflows/build.yml) automates the full build:
graph LR
A["Checkout Code"] --> B["Setup Node 20<br/>+ Python 3.11"]
B --> C["pip install -e .<br/>+ extra deps"]
C --> D["pyinstaller<br/>wshawk-bridge.spec"]
D --> E["Copy binary to<br/>desktop/bin/"]
E --> F["npm install<br/>(Electron deps)"]
F --> G["electron-builder<br/>--publish never"]
G --> H["Upload artifacts"]
H --> I["Create GitHub<br/>Release"]
style A fill:#16213e,stroke:#0f3460,color:#fff
style I fill:#1a1a2e,stroke:#e94560,color:#fff
The build matrix runs on ubuntu-latest, windows-latest, and macos-latest simultaneously with fail-fast: false so all platforms build independently.
extraResources Configuration
The compiled sidecar binary is bundled into the Electron app via package.json:
"extraResources": [
{
"from": "bin",
"to": "bin",
"filter": ["**/*"]
}
]
This copies desktop/bin/wshawk-bridge into resources/bin/wshawk-bridge inside the packaged application. At runtime, index.js resolves this via process.resourcesPath.
Sources: wshawk-bridge.spec:1-100, desktop/package.json:75-86, .github/workflows/build.yml:1-87
State Persistence
Session Save/Load
Full application state can be saved to and loaded from .wshawk project files:
{
"version": "3.0.1",
"timestamp": "2026-02-24T03:00:00Z",
"target": "ws://target.com",
"findings": [...],
"traffic": [...],
"notes": "...",
"auth_sequences": [...],
"scheduled_scans": [...]
}
Save/load uses Electron's native file dialogs via IPC:
- Renderer calls
window.electronAPI.saveProject(state) - Main process shows native save dialog via
dialog.showSaveDialog() - Data is written as JSON to the chosen path
Scan History (SQLite)
The db_manager.py maintains a SQLite database at ~/.wshawk/scans.db with:
- scans table: Target URL, timestamps, vulnerability counts, status
- vulnerabilities table: Individual findings with CVSS scores and payloads
The desktop app provides a History panel with vulnerability regression diffing between scans of the same target.
localStorage Persistence
UI state is persisted in the browser's localStorage:
- Active operating mode (Standard / Advanced / Web Pentest)
- Sidebar collapse state
- Theme preferences
- Active scheduled scans (auto-resume on restart)
Sources: desktop/index.js:98-170, docs/DESKTOP_V3_GUIDE.md:435-465
Related Documentation
- For individual web pentesting tool documentation, see Desktop Web Pentest Toolkit
- For the interceptor, payload blaster, and other advanced features, see Desktop Advanced Features
- For the build and installation process, see Desktop Build Guide
- For the core WebSocket scanner engine, see Core Architecture
- For the Smart Payload Evolution system, see Smart Payload Evolution System
Sources: docs/DESKTOP_V3_GUIDE.md:1-960