Web Dashboard¶
The C3PO web dashboard is a Flask application providing real-time device management, camera streams, positioning, firmware deployment, and more.
URL: http://<WEB_HOST>:<WEB_PORT> (default http://localhost:8000)
Authentication¶
Login Page (/login)¶
- Username/password form with CSRF protection
- Credentials set via
WEB_USERNAME/WEB_PASSWORDin.env - Constant-time comparison (
hmac.compare_digest) prevents timing attacks - Session fixation prevention:
session.clear()before login - Rate limited: 5 attempts/minute
Session vs API Auth¶
| Method | Used By | How |
|---|---|---|
| Session | Browser pages | Cookie-based after /login |
| Bearer token | API clients | Authorization: Bearer <MULTILAT_AUTH_TOKEN> |
| Either | API endpoints | Session OR Bearer accepted |
Navigation¶
Top horizontal navbar with active page highlighting (violet underline).
| Page | URL | Description |
|---|---|---|
| Dashboard | /dashboard |
Device list with real-time status |
| Cameras | /cameras |
Live camera gallery + recording |
| MLAT | /mlat |
Multilateration positioning map |
| OTA | /ota |
Firmware build, upload & deploy |
| Honeypot | /honeypot |
Honeypot event analysis (6 tabs) |
| Terminal | /terminal |
Command terminal |
Additional routes:
| URL | Description |
|---|---|
/device/<id> |
Device detail page |
/streams/<file> |
Serve camera JPEG frame |
/recordings/<file> |
Download video recording |
Pages¶
Dashboard¶
URL: /dashboard
The main device management page.
Features:
- Device cards: One card per connected ESP32 with:
- Device ID, IP address, chip type
- Module tags (color-coded:
network,fakeap,recon,ota, etc.) - Connection status (
Connected/Inactive) - Connection duration
- Real-time updates: SSE stream (
/api/devices/stream) or polling fallback (5s) - Click-through: Click a device card →
/device/<id>detail page - Empty state: ASCII art displayed when no devices are connected
Device card example:
┌──────────────────────────────┐
│ abc12345 Connected │
│ IP: 192.168.1.100 │
│ Chip: esp32 │
│ [network] [recon] [ota] │
│ Connected for 2h 15m │
└──────────────────────────────┘
Device Detail¶
URL: /device/<device_id>
Focused view for a single device with detailed information and command history.
Cameras¶
URL: /cameras
Live camera gallery with recording capabilities.
Features:
- Grid layout: Auto-fill grid (400px min cards) for camera thumbnails
- Live refresh: JPEG frames update every 100ms
- New camera detection: Scans
IMAGE_DIRevery 5 seconds - Recording:
- Circular record button per camera (pulsing animation when active)
- Start/stop recording via
/api/recording/start/<cam>and/api/recording/stop/<cam> - Output: MJPEG
.avifiles
- Download: Completed recordings available at
/recordings/<file>
Camera count displayed in page header stats.
MLAT¶
URL: /mlat
Multilateration positioning interface with dual view modes.
Layout:
┌─────────────────────────────┬──────────────┐
│ │ Config │
│ Map / Plan View │ ├ RSSI@1m │
│ │ ├ Path Loss │
│ ● Scanner 1 (-45 dBm) │ └ Smoothing │
│ ● Scanner 2 (-42 dBm) │ │
│ ★ Target (estimated) │ Scanners │
│ │ ├ scanner_1 │
│ │ ├ scanner_2 │
│ │ └ scanner_3 │
├─────────────────────────────┤ │
│ [Map View] [Plan View] │ │
└─────────────────────────────┴──────────────┘
Features:
- Map View: Leaflet.js map with dark theme. GPS coordinates (
lat,lon) - Plan View: HTML5 Canvas with zoom/pan. Local coordinates (
x,yin meters) - View toggle: Switch between map and plan modes
- Scanners: Listed in sidebar with RSSI, estimated distance, last seen
- Target: Estimated position (requires ≥3 scanners)
- Config panel:
RSSI at 1m(default: -40 dBm)Path loss exponent(default: 2.5)Smoothing window(default: 5 readings)
- Clear: Reset all scanner/target data
OTA¶
URL: /ota
Firmware build, upload, and deployment page.
Layout:
┌──────────────────────────────────┬─────────────────┐
│ Build Firmware [idle] │ Uploaded │
│ ├ Device ID: [________] │ Firmware │
│ ├ Hostname: [________] │ │
│ ├ Modules: │ ├ fw-v1.bin │
│ │ ☑ Network ☐ FakeAP │ │ 1.2 MB │
│ │ ☐ Honeypot ☐ Recon │ │ [Use] [Del] │
│ ├ ☑ Allow OTA over HTTP │ │ │
│ └ [Build Firmware] │ └ fw-v2.bin │
│ │ 1.1 MB │
│ Firmware Source │ [Use] [Del] │
│ ├ URL: [______________] │ │
│ │ [Deploy All] │ │
│ └ ── or upload ── │ │
│ [Choose .bin] [Upload] │ │
│ │ │
│ Devices │ │
│ ┌────────┐ ┌────────┐ │ │
│ │abc123 │ │def456 │ │ │
│ │OTA ✓ │ │No OTA │ │ │
│ │[Deploy]│ │[-----] │ │ │
│ └────────┘ └────────┘ │ │
└──────────────────────────────────┴─────────────────┘
Build Firmware Section:
- Device ID input with connected device autocomplete
- Optional hostname
- Module checkboxes: Network, FakeAP, Honeypot, Recon (+ Camera, BLE sub-options)
- OTA HTTP toggle
- Build button → triggers
/api/ota/build/start - Live progress: Status badge, elapsed time, progress hints, expandable build log
- On success: binary auto-appears in firmware sidebar + URL pre-filled
Firmware Source Section:
- HTTPS URL input for direct deploy
- File upload (
.bin) with optional custom name - Deploy All button → push to all OTA-capable connected devices
Device Grid:
- Cards for each connected device
- OTA capability badge (
OTA Enabled/No OTA) - Per-device Deploy button
- Deploy status tracking (idle → deploying → success/error)
LAN IP Modal:
- Auto-detected when accessing from localhost/127.0.0.1
- Prompts for server LAN IP (ESP32 needs a reachable URL)
- Saved in
localStorage
Terminal¶
URL: /terminal
Direct command dispatch interface.
Layout:
┌──────────────────────────────────────────────────┐
│ Terminal │
│ ┌─ Toolbar ──────────────────────────────────┐ │
│ │ Device: [abc12345 ▼] [Clear] [Disconnect] │ │
│ └────────────────────────────────────────────┘ │
│ │
│ ┌─ Output ──────────────────────────────────┐ │
│ │ > system_info │ │
│ │ chip: esp32 │ │
│ │ modules: network,recon,ota │ │
│ │ free_heap: 142560 │ │
│ │ │ │
│ │ > ping 8.8.8.8 │ │
│ │ Reply from 8.8.8.8: time=23ms │ │
│ └────────────────────────────────────────────┘ │
│ │
│ ❯ [________________________________] [Send] │
└──────────────────────────────────────────────────┘
Features:
- Device selector dropdown (connected devices)
- Command input with send button
- Scrollable output pane with syntax highlighting:
.term-cmd— command echo.term-device-label— device identification.term-error— error messages (red).term-success— success messages (green).term-output— standard output
- Clear button to reset output
- Command history
Honeypot¶
URL: /honeypot
Comprehensive honeypot event analysis dashboard (requires hp_dashboard module).
6 Tab Views:
- KPI header: Total events, unique attackers, active sessions, alerts
- Event timeline chart
- Service distribution
- Top attackers
- Paginated event table with severity coloring
- Filter by source IP, event type, severity
- Click for detail panel (slide-out)
- Severity colors: Critical (rose), High (orange), Medium (yellow), Low (green)
- Session list with duration, packet count, protocol
- Session replay modal
- Timeline visualization
- Captured username/password pairs
- Service breakdown (SSH, Telnet, HTTP)
- Frequency analysis
- Cyber kill chain mapping
- Stage progression visualization
- Per-attacker chain tracking
- Technique mapping
- Tactic grouping
- Evidence linking
Sidebar (persistent):
- Live stats
- Top attackers list
- Active alerts
- Quick filters
Severity Color System:
| Severity | Color | CSS Variable |
|---|---|---|
| Critical | Rose #f43f5e |
--sev-crit |
| High | Orange #fb923c |
--sev-high |
| Medium | Yellow #fbbf24 |
--sev-med |
| Low | Green #4ade80 |
--sev-low |
Layer Colors:
| Layer | Color | CSS Variable |
|---|---|---|
| L2 (Data Link) | Indigo #818cf8 |
--layer-l2 |
| L3 (Network) | Orange #f97316 |
--layer-l3 |
| L4 (Transport) | Rose #f43f5e |
--layer-l4 |
| L7 (Application) | Violet #a855f7 |
--layer-l7 |
UI Components¶
Design System¶
The dashboard uses a dark theme with violet accents. All styles are in static/css/main.css.
Color Palette:
| Token | Value | Usage |
|---|---|---|
--bg-primary |
#0a0a0f |
Page background |
--bg-secondary |
#12121a |
Cards, header |
--bg-elevated |
#1a1a25 |
Hover, inputs |
--accent-primary |
#a855f7 |
CTA, active states |
--accent-primary-hover |
#c084fc |
Hover state |
--text-primary |
#e4e4ed |
Main text |
--text-secondary |
#8888a0 |
Labels |
--status-online |
#22d3ee |
Connected (cyan) |
--status-success |
#4ade80 |
Success (green) |
--status-warning |
#fbbf24 |
Warning (yellow) |
--status-error |
#f87171 |
Error (red) |
Typography:
- Body: Inter (400-700)
- Code: JetBrains Mono (400-600)
Card Pattern¶
<div class="card">
<div class="card-header">
<span class="name">Title</span>
<span class="badge badge-connected">Connected</span>
</div>
<div class="card-body">
Content...
</div>
</div>
Button Variants¶
| Class | Style | Usage |
|---|---|---|
.btn-primary |
Violet background | Primary actions |
.btn-secondary |
Dark with border | Secondary actions |
.btn-sm |
Small (6px 12px) | Inline actions |
Status Badges¶
| Class | Color | Usage |
|---|---|---|
.badge-connected |
Green | Device connected |
.badge-inactive |
Yellow | Device inactive |
.badge-live |
Cyan | Camera live |
Real-Time Updates¶
| Page | Mechanism | Interval |
|---|---|---|
| Dashboard | SSE (/api/devices/stream) |
3s |
| Dashboard (fallback) | Polling | 5s |
| Cameras | Image refresh | 100ms |
| Cameras (new detection) | Polling | 5s |
| OTA devices | Polling | 5s |
| OTA firmware list | Polling | 15s |
| OTA build status | Polling | 2s (during build) |
| Terminal | Command polling | On send |
| MLAT | Polling | 2s |
Next
For programmatic access: API Reference →