Web Management Dashboard

Web Management Dashboard

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

The Web Management Dashboard is a persistent, Flask-based web application that provides centralized management for WSHawk scanning operations. It serves as the primary interface for team-based security assessments, offering SQLite-backed scan history, real-time progress tracking, and RESTful API access.

Scope: This page documents the dashboard's architecture, launch methods, and core components. For detailed authentication implementation, see Authentication and API Keys. For complete REST API endpoint specifications, see REST API Reference. For database schema and scan history management, see Scan History and Persistence.

Purpose and Use Cases

The dashboard addresses three primary operational needs:

  1. Persistent Operations: Unlike CLI-based scans that terminate upon process exit, the dashboard maintains a continuous operational state with scan history stored in ~/.wshawk/scans.db.

  2. Team Collaboration: Multiple operators can launch scans via the web interface or REST API while sharing access to historical results and reports.

  3. Integration Hub: The REST API enables programmatic orchestration from CI/CD pipelines, SOC automation platforms, and custom security tooling.

Sources: README.md:112-136, RELEASE_SUMMARY.md:15-19

System Architecture

The dashboard operates as a distinct Flask application layer that orchestrates scanner instances and manages persistence.

Component Diagram

graph TB
    subgraph "Web_Dashboard_Process"
        Flask["Flask Application<br/>(wshawk --web)"]
        Auth["Authentication Module<br/>SHA-256 + Salt"]
        API["REST API Routes<br/>/api/scans<br/>/api/stats<br/>/login"]
        UI["HTML Template Engine<br/>Jinja2"]
    end
    
    subgraph "Persistence_Layer"
        DB[("scans.db<br/>SQLite + WAL")]
        Reports["Report Files<br/>wshawk_report_*.html"]
        Logs["Traffic Logs<br/>Raw WebSocket Frames"]
    end
    
    subgraph "Scanner_Engine"
        ScannerV2["WSHawkV2<br/>scanner_v2.py"]
    end
    
    subgraph "Configuration"
        ENV["Environment Variables<br/>WSHAWK_WEB_PASSWORD<br/>WSHAWK_API_KEY"]
        YAML["wshawk.yaml<br/>Hierarchical Config"]
    end
    
    Flask --> Auth
    Flask --> API
    Flask --> UI
    
    API --> ScannerV2
    UI --> API
    
    ScannerV2 --> DB
    ScannerV2 --> Reports
    ScannerV2 --> Logs
    
    Auth --> ENV
    Flask --> YAML
    
    DB --> API
    Reports --> UI

Architecture Notes:

  • The Flask application runs as a separate process from CLI-based scans
  • scans.db uses Write-Ahead Logging (WAL) mode for crash recovery
  • Scanner instances are spawned asynchronously via asyncio when triggered through the API
  • Template rendering uses Jinja2 for HTML report viewing within the dashboard

Sources: README.md:112-136, RELEASE_SUMMARY.md:15-19, docs/V3_COMPLETE_GUIDE.md:289-308

Launch Configuration

Command-Line Launch

The dashboard is launched using the --web flag on the primary wshawk entrypoint:

wshawk --web --port 5000 --host 0.0.0.0

Flag Specifications:

| Flag | Default | Description | |------|---------|-------------| | --web | N/A | Activates dashboard mode instead of direct scanning | | --port | 5000 | TCP port for Flask HTTP server | | --host | 127.0.0.1 | Bind address (use 0.0.0.0 for network access) |

Sources: README.md:117-119

Environment-Based Configuration

The dashboard reads authentication credentials and API keys from environment variables:

export WSHAWK_WEB_PASSWORD='production-password-here'
export WSHAWK_API_KEY='api-key-for-programmatic-access'
wshawk --web

If WSHAWK_WEB_PASSWORD is not set, the dashboard operates in open mode (intended only for local development).

Sources: README.md:122-127, docs/V3_COMPLETE_GUIDE.md:300-302

Hierarchical Configuration

The dashboard respects settings in wshawk.yaml for scanner behavior and integration configurations:

web:
  port: 5000
  host: "0.0.0.0"
  
scanner:
  rate_limit: 10
  use_oast: true
  
integrations:
  jira:
    enabled: true
    api_token: "env:JIRA_TOKEN"

Sources: README.md:137-150

Core Components

Database Schema

The scans.db SQLite database maintains three primary tables:

| Table | Purpose | Key Fields | |-------|---------|------------| | scans | Scan metadata and status tracking | scan_id, target_url, start_time, status, vulnerability_count | | vulnerabilities | Detected security issues | vuln_id, scan_id, type, severity, cvss_score, payload, evidence | | traffic_logs | Raw WebSocket message frames | log_id, scan_id, timestamp, direction, raw_data |

The database file is located at ~/.wshawk/scans.db by default and uses WAL mode to ensure zero-loss persistence even if the scanner crashes mid-scan.

Sources: RELEASE_SUMMARY.md:17, docs/V3_COMPLETE_GUIDE.md:293-297

Authentication Layer

Password authentication uses SHA-256 hashing with salt:

  1. User submits password via /login endpoint
  2. Server computes SHA256(password + salt)
  3. Hash compared against stored credential
  4. Session cookie issued on success

API key authentication bypasses password flow:

  • WSHAWK_API_KEY environment variable sets the key
  • Clients pass key via Authorization: Bearer <key> header
  • Used for programmatic access from CI/CD pipelines

Sources: README.md:122-127, RELEASE_SUMMARY.md:18, docs/V3_COMPLETE_GUIDE.md:300-302

Report Management

The dashboard provides in-browser viewing of HTML reports generated by scanner instances:

  • Reports stored as wshawk_report_YYYYMMDD_HHMMSS.html
  • Dashboard serves reports via static file routing
  • Users can view, download, or delete historical reports
  • Each report includes CVSS scores, screenshots (for XSS verification), and remediation guidance

Sources: README.md:132-134

Request Flow

Scan Initiation Flow

sequenceDiagram
    participant Client
    participant Flask
    participant Auth
    participant API
    participant ScannerV2
    participant DB
    
    Client->>Flask: POST /api/scans<br/>{target: "ws://..."}
    Flask->>Auth: Verify Session/API Key
    Auth-->>Flask: Authenticated
    Flask->>API: Route to scan endpoint
    API->>DB: INSERT scan record<br/>(status: "queued")
    DB-->>API: scan_id
    API->>ScannerV2: asyncio.create_task(<br/>scanner.run_heuristic_scan())
    ScannerV2-->>API: Task started
    API-->>Client: 202 Accepted<br/>{scan_id: 123}
    
    Note over ScannerV2,DB: Async scanning process
    ScannerV2->>DB: UPDATE scan<br/>(status: "running")
    ScannerV2->>DB: INSERT vulnerabilities
    ScannerV2->>DB: INSERT traffic_logs
    ScannerV2->>DB: UPDATE scan<br/>(status: "completed")

Flow Description:

  1. Client authenticates via session cookie or API key in Authorization header
  2. API validates authentication and creates database record with status="queued"
  3. Flask spawns async scanner task without blocking request
  4. Scanner updates database atomically as findings are discovered
  5. Client polls GET /api/scans/{id} for status updates

Sources: docs/V3_COMPLETE_GUIDE.md:313-329

Feature Matrix

| Feature | Implementation | Location | |---------|----------------|----------| | Scan History | SQLite persistent storage | ~/.wshawk/scans.db | | Progress Tracking | Real-time status polling via REST API | GET /api/scans/{id} | | Report Viewing | In-browser HTML rendering | /reports/{filename} | | Authentication | SHA-256 password hashing | Environment variable WSHAWK_WEB_PASSWORD | | API Access | Bearer token authentication | Environment variable WSHAWK_API_KEY | | Multi-Scan | Concurrent scan task management | asyncio task queue |

Sources: README.md:130-135

Integration with Scanner Engine

The dashboard does not embed scanner logic. Instead, it orchestrates WSHawkV2 instances:

  1. Scan Trigger: API endpoint creates scanner instance with target URL
  2. Configuration Pass-Through: Scanner inherits settings from wshawk.yaml
  3. Async Execution: Scanner runs in separate asyncio task
  4. Result Storage: Scanner writes directly to scans.db using same schema
  5. Report Generation: Scanner produces HTML report; dashboard serves it

This decoupled architecture ensures that scanner crashes do not affect dashboard availability and multiple scans can run concurrently.

Sources: docs/V3_COMPLETE_GUIDE.md:289-308

Deployment Considerations

Production Deployment

For production use, the dashboard should be:

  1. Reverse Proxied: Place behind Nginx/Apache for TLS termination
  2. Password Protected: Always set WSHAWK_WEB_PASSWORD
  3. Network Isolated: Bind to 127.0.0.1 if only local access needed
  4. Resource Limited: Use Docker resource constraints for multi-tenant environments

Example Docker deployment:

docker run -d \
  --name wshawk-dashboard \
  -p 5000:5000 \
  -v ~/.wshawk:/root/.wshawk \
  -e WSHAWK_WEB_PASSWORD='secure-password' \
  rothackers/wshawk wshawk --web --host 0.0.0.0

Sources: README.md:64-78, docs/V3_COMPLETE_GUIDE.md:354-358

Database Maintenance

The SQLite database grows with scan history. For long-term operations:

  • Backup: Copy ~/.wshawk/scans.db periodically
  • Pruning: Delete old scan records via REST API or direct SQL
  • Vacuum: Run VACUUM to reclaim space after deletions
  • WAL Checkpoint: WAL mode creates -wal and -shm files; checkpointing merges them

Sources: docs/V3_COMPLETE_GUIDE.md:293-297

Comparison with CLI Modes

| Aspect | CLI (wshawk) | Interactive (wshawk-interactive) | Dashboard (wshawk --web) | |--------|----------------|-----------------------------------|----------------------------| | Persistence | None (scan terminates on exit) | None | Permanent (SQLite) | | Multi-User | No | No | Yes (via shared database) | | API Access | No | No | Yes (REST API) | | Authentication | No | No | Yes (SHA-256) | | Use Case | Automation scripts | Learning/training | Team operations, SOC integration |

Sources: README.md:152-160

Related Documentation

Sources: README.md:112-160, RELEASE_SUMMARY.md:1-60, docs/V3_COMPLETE_GUIDE.md:289-330