Flare is a desktop application that builds a live digital twin of a local network, correlates discovered services against the NVD CVE database, and lets you run simulated attack scenarios against the model — all without sending any real traffic beyond the initial nmap scan.
┌─────────────────────────────────────────────────────┐
│ Electron shell (frameless window, IPC controls) │
│ ┌───────────────────────────────────────────────┐ │
│ │ React + Vite frontend (port 5173 in dev) │ │
│ │ Zustand state · Cytoscape.js topology graph │ │
│ └───────────────────────┬───────────────────────┘ │
│ │ HTTP 127.0.0.1:8742 │
│ ┌───────────────────────▼───────────────────────┐ │
│ │ FastAPI backend (uvicorn, asyncio) │ │
│ │ SQLAlchemy async · asyncpg · neo4j-driver │ │
│ └──────────┬────────────────────────┬───────────┘ │
└─────────────┼────────────────────────┼──────────────┘
│ │
┌──────────▼──────┐ ┌──────────▼──────┐
│ PostgreSQL 16 │ │ Neo4j 5 │
│ (hosts, ports, │ │ (topology graph │
│ scans, CVEs) │ │ nodes & edges) │
└─────────────────┘ └─────────────────┘
Stack:
- Frontend: React 18, Vite, Zustand, Cytoscape.js
- Desktop shell: Electron 31 (frameless, custom titlebar via IPC)
- Backend: Python 3.11, FastAPI, SQLAlchemy 2 async, asyncpg
- Relational DB: PostgreSQL 16 (via Docker)
- Graph DB: Neo4j 5 Community (via Docker)
- Scanner: python-nmap wrapping nmap
- CVE data: NIST NVD REST API v2
| Requirement | Install |
|---|---|
| Docker + Docker Compose | sudo pacman -S docker docker-compose |
| Node.js ≥ 20 | sudo pacman -S nodejs npm |
| Python 3.11+ with venv | sudo pacman -S python |
| nmap | sudo pacman -S nmap |
Add yourself to the docker group (once, then re-login):
sudo usermod -aG docker $USER
newgrp dockercd flare
docker compose up -dVerify both containers are healthy:
docker compose pscd backend
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txtcd frontend
npm installFrom the project root:
bash scripts/dev.shThis starts three processes concurrently:
- uvicorn backend on
127.0.0.1:8742(with--reload) - Vite dev server on
localhost:5173 - Electron window loading from Vite
Note: nmap requires root for SYN scans and OS fingerprinting (
-sS -O). Running as a normal user falls back to TCP connect scan (-sT) with no OS detection. To get full results:sudo bash scripts/dev.sh
Backend settings are read from backend/.env (optional — defaults work out of the box):
POSTGRES_URL=postgresql+asyncpg://flare:flare@localhost:5432/flare
NEO4J_URI=bolt://localhost:7687
NEO4J_USER=neo4j
NEO4J_PASSWORD=flare-neo4j
BACKEND_PORT=8742
NVD_API_KEY= # optional — raises rate limit from 5 to 50 req/30s
NVD_CACHE_TTL_DAYS=7bash scripts/build.shSteps performed:
- PyInstaller bundles the FastAPI backend into a single binary (
backend/dist/flare-backend) - Vite builds the React frontend into
frontend/dist/ - electron-builder packages everything into a distributable under
dist/
Linux targets: AppImage and .deb
- Nmap-based host discovery over any CIDR, range, or single IP
- Configurable timing profile (T1 Sneaky → T5 Insane) and port range (Top 1000 / Full 1–65535)
- Per-host: IP, MAC, hostname, OS family, OS detail, OS confidence, open ports with service name and version
- Device role inference: gateway, server, workstation
- Root detection: uses SYN scan + OS fingerprint when root, falls back to TCP connect scan otherwise
- Scan can be aborted mid-run; status tracked as
running → completed / aborted - Scan results persisted to PostgreSQL; topology written to Neo4j
- Live graph rendered with Cytoscape.js using breadth-first layout (directed) or circle layout for isolated nodes
- Node colour encodes worst CVE severity: Critical (red) · High (orange) · Medium (amber) · Low/None (blue)
- Node shape encodes role: gateway/router = diamond · switch = rounded rectangle · default = ellipse
- Severity legend and device count badge overlaid on the canvas
- Animated layout with correct viewport fit after animation completes
- Right-panel stays visible while switching hosts (loading state prevents stale data flash)
- Per-host CVE correlation via NIST NVD API v2 (CPE string built from service name + version)
- Results cached in PostgreSQL with 7-day TTL; re-correlation updates in place (preserves foreign keys to avoid cascading data loss across hosts)
- Duplicate CVE deduplication when multiple ports share the same CPE
- Severity filter bar in the CVE panel (All / Critical / High / Medium / Low)
- CVEs sorted by severity rank (Critical first)
- CVE summary in the Device Inspector panel with severity badge counts and quick-nav to the CVE tab
- Neo4j
worst_severityproperty updated after correlation (drives topology node colour)
- Four built-in MITRE ATT&CK-mapped scenarios, all purely in-memory (no real packets):
- Reconnaissance Sweep — T1046: enumerates open ports and banners
- Credential Brute-Force — T1110: identifies exposed SSH, RDP, FTP, Telnet, VNC
- SMB Lateral Movement — T1021.002: checks for CVE-2017-0144, CVE-2020-0796, CVE-2021-44228
- Service Denial-of-Service — T1499: targets high/critical CVEs and exposed HTTP
- Per-step outcome (success / blocked) with technique name and detail
- Aggregated success and blocked counts
- Remediation recommendations generated per scenario
- Frameless Electron window with custom titlebar (IPC minimize/maximize/close)
- Dark theme matching UniFi OS aesthetic (
#0b0d12background,#3b82f6accent) - Three-panel layout: scan config sidebar · topology canvas · device inspector/CVE/simulate right panel
- Startup dialog if nmap is not installed (blocks window open, shows install command)
- Startup error dialog with actionable message if PostgreSQL/Neo4j are unreachable
- Device annotation (free-text notes per host, persisted to DB)
- SVG device-role icons on topology nodes (gateway, server, switch, workstation) embedded as data URLs — works in both Vite dev and Electron
file://production - SVG favicon wired into
index.html
| File | Purpose |
|---|---|
frontend/public/favicon.svg |
Browser/Electron tab icon |
frontend/assets/icon.svg |
App icon source — convert to icon.png (512×512) and icon.ico for the production build |
To convert icon.svg to the required formats (requires Inkscape or ImageMagick):
# PNG for Linux
inkscape frontend/assets/icon.svg -w 512 -h 512 -o frontend/assets/icon.png
# ICO for Windows (requires imagemagick)
convert frontend/assets/icon.png -define icon:auto-resize=256,128,64,48,32,16 frontend/assets/icon.icoflare/
├── backend/
│ ├── app/
│ │ ├── main.py FastAPI app, lifespan, CORS, health endpoint
│ │ ├── config.py Pydantic settings (reads .env)
│ │ ├── database.py PostgreSQL + Neo4j async engine setup
│ │ ├── models/
│ │ │ ├── relational/ SQLAlchemy ORM: Scan, Host, Port, CVECache, HostCVE
│ │ │ └── graph/ Neo4j node/edge dataclasses + Cypher queries
│ │ ├── routers/ FastAPI routers: scan, hosts, cve, simulation
│ │ ├── schemas/ Pydantic request/response models
│ │ └── services/
│ │ ├── scanner.py nmap runner, host/port persistence, topology builder
│ │ ├── twin.py Neo4j read/write helpers
│ │ ├── cve.py NVD API client, cache logic, correlation
│ │ └── simulator.py Attack scenario runners
│ ├── flare-backend.spec PyInstaller spec
│ └── requirements.txt
├── frontend/
│ ├── electron/
│ │ ├── main.js Electron main process, backend lifecycle, IPC
│ │ └── preload.js Context bridge (exposes window controls)
│ └── src/
│ ├── App.jsx Three-panel shell, Titlebar, tab routing
│ ├── store/index.js Zustand store (all async actions)
│ ├── services/api.js Typed fetch wrappers for all 15 API routes
│ └── components/
│ ├── TopologyGraph/ Cytoscape mount, layout, node selection
│ ├── ScanConfig/ Scan form, status card, abort button
│ ├── DeviceInspector/ Host fields, open ports, CVE summary, annotation
│ ├── CVEPanel/ CVE list with severity filter
│ └── AttackSimulator/ Scenario picker, results, remediation
├── docker-compose.yml PostgreSQL 16 + Neo4j 5 Community
└── scripts/
├── dev.sh Start backend + Vite + Electron concurrently
└── build.sh PyInstaller → Vite → electron-builder
| Method | Path | Description |
|---|---|---|
GET |
/health |
Status + nmap availability check |
POST |
/scans |
Start a new scan |
GET |
/scans |
List all scans |
GET |
/scans/{id} |
Get scan status |
POST |
/scans/{id}/abort |
Abort running scan |
GET |
/hosts |
List hosts (optional ?scan_id=) |
GET |
/hosts/{id} |
Host detail with ports |
PATCH |
/hosts/{id}/annotation |
Save note for a host |
GET |
/topology |
Cytoscape-ready nodes + edges from Neo4j |
GET |
/cve/host/{id} |
CVEs linked to a host |
POST |
/cve/correlate/{id} |
Run NVD correlation for a host |
GET |
/cve/dashboard |
Severity totals + top exposed hosts |
DELETE |
/cve/cache/{id} |
Invalidate CVE cache for a host |
GET |
/simulation/scenarios |
List available attack scenarios |
POST |
/simulation/run |
Run a scenario against a target IP |