Files
SneakyScan/docs/ROADMAP.md

934 lines
35 KiB
Markdown

# SneakyScanner Roadmap
## Vision & Goals
SneakyScanner is a comprehensive **Flask web application** for infrastructure monitoring and security auditing. The primary interface is the web GUI, with a CLI API client planned for scripting and automation needs.
**Status:** Phase 4 Complete ✅ | Phase 5 Next Up
## Progress Overview
-**Phase 1: Foundation** - Complete (2025-11-13)
- Database schema, SQLAlchemy models, settings system, Flask app structure
-**Phase 2: Flask Web App Core** - Complete (2025-11-14)
- REST API, background jobs, authentication, web UI, testing (100 tests)
-**Phase 3: Dashboard & Scheduling** - Complete (2025-11-14)
- Dashboard, scan history, scheduled scans, trend charts
-**Phase 4: Config Creator** - Complete (2025-11-17)
- CIDR-based config creation, YAML editor, config management UI
- 📋 **Phase 5: Email, Webhooks & Comparisons** - Next Up
- Email notifications, alert rules, scan comparison
- 📋 **Phase 6: CLI as API Client** - Planned
- CLI for scripting and automation via API
- 📋 **Phase 7: Advanced Features** - Future
- CVE integration, timeline view, PDF export, enhanced reports
**Core Features:**
- **Centralized dashboard** for viewing scan history and trends
- **Scheduled scanning** for continuous infrastructure monitoring
- **Email notifications** for critical changes and certificate expirations (coming soon)
- **Historical analysis** with charts, graphs, and comparison reports
- **Config creator** for easy CIDR-based scan configuration
- **RESTful API** for integration and automation
- **Simple deployment** using SQLite3 (single-user, self-hosted)
**Planned:**
- **CLI API client** for scripting and automation workflows (Phase 6)
## Target Users
- **Infrastructure teams** monitoring on-premises networks
- **Security professionals** performing periodic security audits
- **DevOps engineers** tracking infrastructure drift
- **Single users or small teams** (not enterprise multi-tenant)
## Technology Stack
### Backend
- **Flask** 3.x - Lightweight Python web framework
- **SQLAlchemy** 2.x - ORM for database abstraction
- **SQLite3** - Embedded database (easy deployment, sufficient for single-user)
- **APScheduler** 3.x - Background job scheduling for periodic scans
- **Flask-Login** - Simple session-based authentication
- **Flask-CORS** - API access control (optional for CLI API client)
- **Marshmallow** - API serialization/deserialization
### Frontend
- **Jinja2** - Server-side templating (already in use)
- **Bootstrap 5** - Responsive UI framework with dark theme support
- **Chart.js** 4.x - Lightweight charting library for trends
- **DataTables.js** - Interactive sortable/filterable tables (Phase 6)
- **Vanilla JavaScript** - Keep dependencies minimal
### Infrastructure
- **Docker Compose** - Multi-container orchestration (Flask app + Scanner)
- **Gunicorn** - WSGI server for production
- **Nginx** - Reverse proxy (optional, for production deployments)
### Existing Components (Keep)
- **Masscan** - Fast port discovery
- **Nmap** - Service detection
- **Playwright** - Screenshot capture
- **sslyze** - SSL/TLS analysis
## Architecture Overview
```
┌─────────────────────────────────────────────────────────────┐
│ Flask Web Application │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │
│ │ Web UI │ │ REST API │ │ Scheduler │ │
│ │ (Dashboard) │ │ (JSON/CRUD) │ │ (APScheduler) │ │
│ └──────┬───────┘ └──────┬───────┘ └────────┬─────────┘ │
│ │ │ │ │
│ └─────────────────┴────────────────────┘ │
│ │ │
│ ┌────────▼────────┐ │
│ │ SQLAlchemy │ │
│ │ (ORM Layer) │ │
│ └────────┬────────┘ │
│ │ │
│ ┌────────▼────────┐ │
│ │ SQLite3 DB │ │
│ │ (scan history) │ │
│ └─────────────────┘ │
└───────────────────────────┬─────────────────────────────────┘
┌──────────▼──────────┐
│ Scanner Engine │
│ (scanner.py) │
│ ┌────────────────┐ │
│ │ Masscan/Nmap │ │
│ │ Playwright │ │
│ │ sslyze │ │
│ └────────────────┘ │
└─────────────────────┘
┌──────────▼──────────┐
│ CLI API Client │
│ (optional future) │
└─────────────────────┘
```
### Component Interaction
1. **Web UI** - User interacts with dashboard, triggers scans, views history
2. **REST API** - Handles requests from web UI and CLI client
3. **Scheduler (APScheduler)** - Triggers scans based on cron-like schedules
4. **SQLAlchemy ORM** - Abstracts database operations
5. **SQLite3 Database** - Stores scan results, schedules, settings, alerts
6. **Scanner Engine** - Performs actual network scanning (masscan, nmap, etc.)
7. **CLI API Client** - Future: thin client that calls Flask API
## Database Schema Design
### Core Tables
#### `scans`
Stores metadata about each scan execution.
| Column | Type | Description |
|--------|------|-------------|
| `id` | INTEGER PRIMARY KEY | Unique scan ID |
| `timestamp` | DATETIME | Scan start time (UTC) |
| `duration` | FLOAT | Total scan duration (seconds) |
| `status` | VARCHAR(20) | `running`, `completed`, `failed` |
| `config_file` | TEXT | Path to YAML config used |
| `title` | TEXT | Scan title from config |
| `json_path` | TEXT | Path to JSON report |
| `html_path` | TEXT | Path to HTML report |
| `zip_path` | TEXT | Path to ZIP archive |
| `screenshot_dir` | TEXT | Path to screenshot directory |
| `created_at` | DATETIME | Record creation time |
| `triggered_by` | VARCHAR(50) | `manual`, `scheduled`, `api` |
| `schedule_id` | INTEGER | FK to schedules (if triggered by schedule) |
#### `scan_sites`
Logical grouping of IPs by site.
| Column | Type | Description |
|--------|------|-------------|
| `id` | INTEGER PRIMARY KEY | Unique site record ID |
| `scan_id` | INTEGER | FK to scans |
| `site_name` | VARCHAR(255) | Site name from config |
#### `scan_ips`
IP addresses scanned in each scan.
| Column | Type | Description |
|--------|------|-------------|
| `id` | INTEGER PRIMARY KEY | Unique IP record ID |
| `scan_id` | INTEGER | FK to scans |
| `site_id` | INTEGER | FK to scan_sites |
| `ip_address` | VARCHAR(45) | IPv4 or IPv6 address |
| `ping_expected` | BOOLEAN | Expected ping response |
| `ping_actual` | BOOLEAN | Actual ping response |
#### `scan_ports`
Discovered TCP/UDP ports.
| Column | Type | Description |
|--------|------|-------------|
| `id` | INTEGER PRIMARY KEY | Unique port record ID |
| `scan_id` | INTEGER | FK to scans |
| `ip_id` | INTEGER | FK to scan_ips |
| `port` | INTEGER | Port number (1-65535) |
| `protocol` | VARCHAR(10) | `tcp` or `udp` |
| `expected` | BOOLEAN | Was this port expected? |
| `state` | VARCHAR(20) | `open`, `closed`, `filtered` |
#### `scan_services`
Detected services on open ports.
| Column | Type | Description |
|--------|------|-------------|
| `id` | INTEGER PRIMARY KEY | Unique service record ID |
| `scan_id` | INTEGER | FK to scans |
| `port_id` | INTEGER | FK to scan_ports |
| `service_name` | VARCHAR(100) | Service name (e.g., `ssh`, `http`) |
| `product` | VARCHAR(255) | Product name (e.g., `OpenSSH`) |
| `version` | VARCHAR(100) | Version string |
| `extrainfo` | TEXT | Additional nmap info |
| `ostype` | VARCHAR(100) | OS type if detected |
| `http_protocol` | VARCHAR(10) | `http` or `https` (if web service) |
| `screenshot_path` | TEXT | Relative path to screenshot |
#### `scan_certificates`
SSL/TLS certificates discovered on HTTPS services.
| Column | Type | Description |
|--------|------|-------------|
| `id` | INTEGER PRIMARY KEY | Unique certificate record ID |
| `scan_id` | INTEGER | FK to scans |
| `service_id` | INTEGER | FK to scan_services |
| `subject` | TEXT | Certificate subject (CN) |
| `issuer` | TEXT | Certificate issuer |
| `serial_number` | TEXT | Serial number |
| `not_valid_before` | DATETIME | Validity start date |
| `not_valid_after` | DATETIME | Validity end date |
| `days_until_expiry` | INTEGER | Days until expiration |
| `sans` | TEXT | JSON array of SANs |
| `is_self_signed` | BOOLEAN | Self-signed certificate flag |
#### `scan_tls_versions`
TLS version support and cipher suites.
| Column | Type | Description |
|--------|------|-------------|
| `id` | INTEGER PRIMARY KEY | Unique TLS version record ID |
| `scan_id` | INTEGER | FK to scans |
| `certificate_id` | INTEGER | FK to scan_certificates |
| `tls_version` | VARCHAR(20) | `TLS 1.0`, `TLS 1.1`, `TLS 1.2`, `TLS 1.3` |
| `supported` | BOOLEAN | Is this version supported? |
| `cipher_suites` | TEXT | JSON array of cipher suites |
### Scheduling & Notifications Tables
#### `schedules`
Scheduled scan configurations.
| Column | Type | Description |
|--------|------|-------------|
| `id` | INTEGER PRIMARY KEY | Unique schedule ID |
| `name` | VARCHAR(255) | Schedule name (e.g., "Daily prod scan") |
| `config_file` | TEXT | Path to YAML config |
| `cron_expression` | VARCHAR(100) | Cron-like schedule (e.g., `0 2 * * *`) |
| `enabled` | BOOLEAN | Is schedule active? |
| `last_run` | DATETIME | Last execution time |
| `next_run` | DATETIME | Next scheduled execution |
| `created_at` | DATETIME | Schedule creation time |
| `updated_at` | DATETIME | Last modification time |
#### `alerts`
Alert history and notifications sent.
| Column | Type | Description |
|--------|------|-------------|
| `id` | INTEGER PRIMARY KEY | Unique alert ID |
| `scan_id` | INTEGER | FK to scans |
| `alert_type` | VARCHAR(50) | `new_port`, `cert_expiry`, `service_change`, `ping_failed` |
| `severity` | VARCHAR(20) | `info`, `warning`, `critical` |
| `message` | TEXT | Human-readable alert message |
| `ip_address` | VARCHAR(45) | Related IP (optional) |
| `port` | INTEGER | Related port (optional) |
| `email_sent` | BOOLEAN | Was email notification sent? |
| `email_sent_at` | DATETIME | Email send timestamp |
| `created_at` | DATETIME | Alert creation time |
#### `alert_rules`
User-defined alert rules.
| Column | Type | Description |
|--------|------|-------------|
| `id` | INTEGER PRIMARY KEY | Unique rule ID |
| `rule_type` | VARCHAR(50) | `unexpected_port`, `cert_expiry`, `service_down`, etc. |
| `enabled` | BOOLEAN | Is rule active? |
| `threshold` | INTEGER | Threshold value (e.g., days for cert expiry) |
| `email_enabled` | BOOLEAN | Send email for this rule? |
| `created_at` | DATETIME | Rule creation time |
### Settings Table
#### `settings`
Application configuration key-value store.
| Column | Type | Description |
|--------|------|-------------|
| `id` | INTEGER PRIMARY KEY | Unique setting ID |
| `key` | VARCHAR(255) UNIQUE | Setting key (e.g., `smtp_server`) |
| `value` | TEXT | Setting value (JSON for complex values) |
| `updated_at` | DATETIME | Last modification time |
**Example Settings:**
- `smtp_server` - SMTP server hostname
- `smtp_port` - SMTP port (587, 465, 25)
- `smtp_username` - SMTP username
- `smtp_password` - SMTP password (encrypted)
- `smtp_from_email` - From email address
- `smtp_to_emails` - JSON array of recipient emails
- `app_password` - Single-user password hash (bcrypt)
- `retention_days` - How long to keep old scans (0 = forever)
## API Design
### REST API Endpoints
All API endpoints return JSON and follow RESTful conventions.
#### Scans
| Method | Endpoint | Description | Request Body | Response |
|--------|----------|-------------|--------------|----------|
| `GET` | `/api/scans` | List all scans (paginated) | - | `{ "scans": [...], "total": N, "page": 1 }` |
| `GET` | `/api/scans/{id}` | Get scan details | - | `{ "scan": {...} }` |
| `POST` | `/api/scans` | Trigger new scan | `{ "config_file": "path" }` | `{ "scan_id": N, "status": "running" }` |
| `DELETE` | `/api/scans/{id}` | Delete scan and files | - | `{ "status": "deleted" }` |
| `GET` | `/api/scans/{id}/status` | Get scan status | - | `{ "status": "running", "progress": "45%" }` |
| `GET` | `/api/scans/{id1}/compare/{id2}` | Compare two scans | - | `{ "diff": {...} }` |
#### Schedules
| Method | Endpoint | Description | Request Body | Response |
|--------|----------|-------------|--------------|----------|
| `GET` | `/api/schedules` | List all schedules | - | `{ "schedules": [...] }` |
| `GET` | `/api/schedules/{id}` | Get schedule details | - | `{ "schedule": {...} }` |
| `POST` | `/api/schedules` | Create new schedule | `{ "name": "...", "config_file": "...", "cron_expression": "..." }` | `{ "schedule_id": N }` |
| `PUT` | `/api/schedules/{id}` | Update schedule | `{ "enabled": true, "cron_expression": "..." }` | `{ "status": "updated" }` |
| `DELETE` | `/api/schedules/{id}` | Delete schedule | - | `{ "status": "deleted" }` |
| `POST` | `/api/schedules/{id}/trigger` | Manually trigger scheduled scan | - | `{ "scan_id": N }` |
#### Alerts
| Method | Endpoint | Description | Request Body | Response |
|--------|----------|-------------|--------------|----------|
| `GET` | `/api/alerts` | List recent alerts | - | `{ "alerts": [...] }` |
| `GET` | `/api/alerts/rules` | List alert rules | - | `{ "rules": [...] }` |
| `POST` | `/api/alerts/rules` | Create alert rule | `{ "rule_type": "...", "threshold": N }` | `{ "rule_id": N }` |
| `PUT` | `/api/alerts/rules/{id}` | Update alert rule | `{ "enabled": false }` | `{ "status": "updated" }` |
| `DELETE` | `/api/alerts/rules/{id}` | Delete alert rule | - | `{ "status": "deleted" }` |
#### Settings
| Method | Endpoint | Description | Request Body | Response |
|--------|----------|-------------|--------------|----------|
| `GET` | `/api/settings` | Get all settings (sanitized) | - | `{ "settings": {...} }` |
| `PUT` | `/api/settings` | Update settings | `{ "smtp_server": "...", ... }` | `{ "status": "updated" }` |
| `POST` | `/api/settings/test-email` | Test email configuration | - | `{ "status": "sent" }` |
#### Statistics & Trends
| Method | Endpoint | Description | Request Body | Response |
|--------|----------|-------------|--------------|----------|
| `GET` | `/api/stats/summary` | Dashboard summary stats | - | `{ "total_scans": N, "last_scan": "...", ... }` |
| `GET` | `/api/stats/trends` | Trend data for charts | `?days=30&metric=port_count` | `{ "data": [...] }` |
| `GET` | `/api/stats/certificates` | Certificate expiry overview | - | `{ "expiring_soon": [...], "expired": [...] }` |
### Authentication
**Phase 2-3:** Simple session-based authentication (single-user)
- Login endpoint: `POST /api/auth/login` (username/password)
- Logout endpoint: `POST /api/auth/logout`
- Session cookies with Flask-Login
- Password stored as bcrypt hash in settings table
**Phase 5:** API token authentication for CLI client
- Generate API token: `POST /api/auth/token`
- Revoke token: `DELETE /api/auth/token`
- CLI sends token in `Authorization: Bearer <token>` header
## Phased Roadmap
### Phase 1: Foundation ✅ COMPLETE
**Completed:** 2025-11-13
**Deliverables:**
- SQLite database with 11 tables (scans, sites, IPs, ports, services, certificates, TLS versions, schedules, alerts, alert_rules, settings)
- SQLAlchemy ORM models with relationships
- Alembic migration system
- Settings system with encryption (bcrypt for passwords, Fernet for sensitive data)
- Flask app structure with API blueprints
- Docker Compose deployment configuration
- Validation script for verification
---
### Phase 2: Flask Web App Core ✅ COMPLETE
**Completed:** 2025-11-14
**Deliverables:**
- REST API with 8 endpoints (scans: trigger, list, get, status, delete; settings: get, update, test-email)
- Background job queue using APScheduler (up to 3 concurrent scans)
- Session-based authentication with Flask-Login
- Database integration for scan results (full normalized schema population)
- Web UI templates (dashboard, scan list/detail, login, error pages)
- Error handling with content negotiation (JSON/HTML) and request IDs
- Logging system with rotating file handlers
- Production Docker Compose deployment
- Comprehensive test suite (100 tests, all passing)
- Documentation (API_REFERENCE.md, DEPLOYMENT.md)
---
### Phase 3: Dashboard & Scheduling ✅ COMPLETE
**Completed:** 2025-11-14
**Deliverables:**
- Dashboard with summary stats (total scans, IPs, ports, services)
- Recent scans table with clickable details
- Scan detail page with full results display
- Historical trend charts using Chart.js (port counts over time)
- Scheduled scan management UI (create, edit, delete, enable/disable)
- Schedule execution with APScheduler and cron expressions
- Manual scan trigger from web UI
- Navigation menu (Dashboard, Scans, Schedules, Configs, Settings)
- Download buttons for scan reports (JSON, HTML, ZIP)
---
### Phase 4: Config Creator ✅ COMPLETE
**Completed:** 2025-11-17
**Deliverables:**
- CIDR-based config creation UI (simplified workflow for quick config generation)
- YAML editor with CodeMirror (syntax highlighting, line numbers)
- Config management UI (list, view, edit, download, delete)
- Direct YAML upload for advanced users
- REST API for config operations (7 endpoints: list, get, create, update, delete, upload, download)
- Schedule dependency protection (prevents deleting configs used by schedules)
- Comprehensive testing (25+ unit and integration tests)
---
### Phase 5: Email, Webhooks & Comparisons
**Status:** Next Up
**Priority:** MEDIUM
**Goals:**
- Implement email notification system for infrastructure misconfigurations
- Implement webhook notification system for real-time alerting
- Create scan comparison reports to detect drift
- Add alert rule configuration for unexpected exposure detection
**Core Use Case:**
Monitor infrastructure for misconfigurations that expose unexpected ports/services to the world. When a scan detects an open port that wasn't defined in the YAML config's `expected_ports` list, trigger immediate notifications via email and/or webhooks.
**Planned Features:**
#### 1. Alert Rule Engine
**Purpose:** Automatically detect and classify infrastructure anomalies after each scan.
**Alert Types:**
- `unexpected_port` - Port open but not in config's `expected_ports` list
- `unexpected_service` - Service detected that doesn't match expected service name
- `cert_expiry` - SSL/TLS certificate expiring soon (configurable threshold)
- `ping_failed` - Expected host not responding to ping
- `service_down` - Previously detected service no longer responding
- `service_change` - Service version/product changed between scans
- `weak_tls` - TLS 1.0/1.1 detected or weak cipher suites
- `new_host` - New IP address responding in CIDR range
- `host_disappeared` - Previously seen IP no longer responding
**Alert Severity Levels:**
- `critical` - Unexpected internet-facing service (ports 80/443/22/3389/etc.)
- `warning` - Minor configuration drift or upcoming cert expiry
- `info` - Informational alerts (new host discovered, service version change)
**Alert Rule Configuration:**
```yaml
# Example alert rule configuration (stored in DB)
alert_rules:
- id: 1
rule_type: unexpected_port
enabled: true
severity: critical
email_enabled: true
webhook_enabled: true
filter_conditions:
ports: [22, 80, 443, 3389, 3306, 5432, 27017] # High-risk ports
- id: 2
rule_type: cert_expiry
enabled: true
severity: warning
threshold: 30 # Days before expiry
email_enabled: true
webhook_enabled: false
```
**Implementation:**
- Evaluate alert rules after each scan completes
- Compare current scan results to expected configuration
- Generate alerts and store in `alerts` table
- Trigger notifications based on rule configuration
- Alert deduplication (don't spam for same issue)
#### 2. Email Notifications
**Purpose:** Send detailed email alerts when infrastructure misconfigurations are detected.
**SMTP Configuration (via Settings API):**
```json
{
"smtp_server": "smtp.gmail.com",
"smtp_port": 587,
"smtp_use_tls": true,
"smtp_username": "alerts@example.com",
"smtp_password": "encrypted_password",
"smtp_from_email": "SneakyScanner <alerts@example.com>",
"smtp_to_emails": ["admin@example.com", "security@example.com"],
"email_alerts_enabled": true
}
```
**Email Template (Jinja2 HTML):**
```html
Subject: [SneakyScanner Alert] Unexpected Port Detected - {{ ip_address }}:{{ port }}
Body:
===============================================
SneakyScanner Security Alert
===============================================
Alert Type: {{ alert_type }}
Severity: {{ severity }}
Scan ID: {{ scan_id }}
Timestamp: {{ timestamp }}
Issue Detected:
{{ message }}
Details:
- IP Address: {{ ip_address }}
- Port: {{ port }}/{{ protocol }}
- Service: {{ service_name }} ({{ product }} {{ version }})
- Expected: No (not in expected_ports list)
Recommended Actions:
1. Verify if this service should be exposed
2. Check firewall rules for {{ ip_address }}
3. Review service configuration
4. Update scan config if this is intentional
View Full Scan Results:
{{ web_url }}/scans/{{ scan_id }}
===============================================
```
**Email Features:**
- HTML email with styled alert box (Bootstrap-based)
- Plain-text fallback for compatibility
- Alert summary with actionable recommendations
- Direct link to scan detail page
- Configurable recipients (multiple emails)
- Test email functionality in Settings UI
- Email delivery tracking (email_sent, email_sent_at in alerts table)
- Rate limiting to prevent email flood
**Email API Endpoints:**
- `POST /api/settings/email` - Configure SMTP settings
- `POST /api/settings/email/test` - Send test email
- `GET /api/alerts?email_sent=true` - Get alerts with email status
#### 3. Webhook Notifications
**Purpose:** Real-time HTTP POST notifications for integration with external systems (Slack, PagerDuty, custom dashboards, SIEM tools).
**Webhook Configuration (via Settings API):**
```json
{
"webhook_enabled": true,
"webhook_urls": [
{
"id": 1,
"name": "Slack Security Channel",
"url": "https://hooks.slack.com/services/XXX/YYY/ZZZ",
"enabled": true,
"auth_type": "none",
"custom_headers": {},
"alert_types": ["unexpected_port", "unexpected_service", "weak_tls"],
"severity_filter": ["critical", "warning"]
},
{
"id": 2,
"name": "PagerDuty",
"url": "https://events.pagerduty.com/v2/enqueue",
"enabled": true,
"auth_type": "bearer",
"auth_token": "encrypted_token",
"custom_headers": {
"Content-Type": "application/json"
},
"alert_types": ["unexpected_port"],
"severity_filter": ["critical"]
}
]
}
```
**Webhook Payload Format (JSON):**
```json
{
"event_type": "scan_alert",
"alert_id": 42,
"alert_type": "unexpected_port",
"severity": "critical",
"timestamp": "2025-11-17T14:23:45Z",
"scan": {
"scan_id": 123,
"title": "Production Network Scan",
"timestamp": "2025-11-17T14:15:00Z",
"config_file": "prod_config.yaml",
"triggered_by": "scheduled"
},
"alert_details": {
"message": "Unexpected port 3306 (MySQL) exposed on 192.168.1.100",
"ip_address": "192.168.1.100",
"port": 3306,
"protocol": "tcp",
"state": "open",
"service": {
"name": "mysql",
"product": "MySQL",
"version": "8.0.32"
},
"expected": false,
"site_name": "Production Servers"
},
"recommended_actions": [
"Verify if MySQL should be exposed externally",
"Check firewall rules for 192.168.1.100",
"Review MySQL bind-address configuration"
],
"web_url": "https://sneakyscanner.local/scans/123"
}
```
**Webhook Features:**
- Multiple webhook URLs with independent configuration
- Per-webhook filtering by alert type and severity
- Custom headers support (for API keys, auth tokens)
- Authentication methods:
- `none` - No authentication
- `bearer` - Bearer token in Authorization header
- `basic` - Basic authentication
- `custom` - Custom header-based auth
- Retry logic with exponential backoff (3 attempts)
- Webhook delivery tracking (webhook_sent, webhook_sent_at, webhook_response_code)
- Test webhook functionality in Settings UI
- Timeout configuration (default 10 seconds)
- Webhook delivery history and logs
**Webhook API Endpoints:**
- `POST /api/webhooks` - Create webhook configuration
- `GET /api/webhooks` - List all webhooks
- `PUT /api/webhooks/{id}` - Update webhook configuration
- `DELETE /api/webhooks/{id}` - Delete webhook
- `POST /api/webhooks/{id}/test` - Send test webhook
- `GET /api/webhooks/{id}/history` - Get delivery history
**Slack Integration Example:**
Transform webhook payload to Slack message format:
```json
{
"text": "SneakyScanner Alert: Unexpected Port Detected",
"attachments": [
{
"color": "danger",
"fields": [
{"title": "IP Address", "value": "192.168.1.100", "short": true},
{"title": "Port", "value": "3306/tcp", "short": true},
{"title": "Service", "value": "MySQL 8.0.32", "short": true},
{"title": "Severity", "value": "CRITICAL", "short": true}
],
"footer": "SneakyScanner",
"ts": 1700234625
}
]
}
```
#### 4. Alert Management UI
**Purpose:** Web interface for configuring alert rules, viewing alert history, and managing notifications.
**Pages:**
- `/alerts` - Alert history with filtering and search
- `/alerts/rules` - Alert rule configuration
- `/settings/email` - Email notification settings
- `/settings/webhooks` - Webhook configuration
**Alert History Features:**
- Filter by alert type, severity, date range, IP address
- Search by message content
- Bulk acknowledge/dismiss alerts
- Export alerts to CSV
- Alert detail modal with full context
**Alert Rule UI Features:**
- Enable/disable rules individually
- Configure severity levels
- Set thresholds (e.g., cert expiry days)
- Toggle email/webhook per rule
- Test rules against recent scans
#### 5. Scan Comparison
**Purpose:** Detect infrastructure drift by comparing two scans and highlighting changes.
**Comparison API:**
- `GET /api/scans/{id1}/compare/{id2}` - Compare two scans
**Comparison Response:**
```json
{
"scan1": {"id": 100, "timestamp": "2025-11-10T10:00:00Z"},
"scan2": {"id": 123, "timestamp": "2025-11-17T14:15:00Z"},
"summary": {
"new_ports": 2,
"removed_ports": 0,
"service_changes": 1,
"cert_changes": 0,
"new_hosts": 1,
"removed_hosts": 0
},
"differences": {
"new_ports": [
{"ip": "192.168.1.100", "port": 3306, "service": "mysql"}
],
"removed_ports": [],
"service_changes": [
{
"ip": "192.168.1.50",
"port": 22,
"old": "OpenSSH 8.2",
"new": "OpenSSH 8.9"
}
],
"new_hosts": [
{"ip": "192.168.1.200", "site": "Production Servers"}
]
}
}
```
**Comparison UI Features:**
- Side-by-side comparison view
- Color-coded differences (green=new, red=removed, yellow=changed)
- Filter by change type
- Export comparison report to PDF/HTML
- "Compare with previous scan" button on scan detail page
---
**Phase 5 Implementation Plan:**
1. **Week 1: Alert Rule Engine**
- Implement alert evaluation logic after scan completion
- Create `alerts` table population
- Add alert rule CRUD API
- Unit tests for alert detection
2. **Week 2: Email Notifications**
- SMTP integration with Flask-Mail
- Jinja2 email templates (HTML + plain text)
- Settings API for email configuration
- Test email functionality
- Email delivery tracking
3. **Week 3: Webhook System**
- Webhook configuration API
- HTTP POST delivery with retry logic
- Webhook template system for different platforms
- Test webhook functionality
- Delivery tracking and logging
4. **Week 4: Alert UI & Scan Comparison**
- Alert history page with filtering
- Alert rule management UI
- Email/webhook settings pages
- Scan comparison API and UI
- Integration testing
**Success Criteria:**
- Alert triggered within 30 seconds of scan completion
- Email delivered successfully to configured recipients
- Webhook POST delivered with retry on failure
- Scan comparison highlights all infrastructure changes
- Zero false positives for expected ports/services
- Alert deduplication prevents notification spam
---
### Phase 6: CLI as API Client
**Status:** Planned
**Priority:** MEDIUM
**Goals:**
- Create CLI API client for scripting and automation
- Maintain standalone mode for testing
- API token authentication
**Planned Features:**
1. **API Client Mode:**
- `--api-mode` flag to enable API client mode
- `--api-url` and `--api-token` arguments
- Trigger scans via API, poll for status, download results
- Scans stored centrally in database
- Standalone mode still available for testing
2. **API Token System:**
- Token generation UI in settings page
- Secure token storage (hashed in database)
- Token authentication middleware
- Token expiration and revocation
3. **Benefits:**
- Centralized scan history accessible via web dashboard
- No need to mount volumes for output
- Scheduled scans managed through web UI
- Scriptable automation while leveraging web features
---
### Phase 7: Advanced Features
**Status:** Future/Deferred
**Priority:** LOW
**Planned Features:**
1. **Enhanced Reports:**
- Sortable/filterable tables (DataTables.js)
- Inline screenshot thumbnails with lightbox
- PDF export (WeasyPrint)
2. **Vulnerability Detection:**
- CVE database integration (NVD API)
- Service version matching to known CVEs
- CVSS severity scores
- Alert rules for critical CVEs
3. **Timeline View:**
- Visual scan history timeline
- Filter by site/IP
- Event annotations
4. **Advanced Charts:**
- Port activity heatmap
- Service version tracking
- Certificate expiration forecast
5. **Integrations:**
- Slack notifications
- Webhook support
- Prometheus metrics export
- CSV export/import
---
## Current Architecture
**Primary Interface:** Web GUI (Phases 1-4 Complete)
- Full-featured Flask web application
- Dashboard, scan management, scheduling, config creator
- REST API for all operations
- Single-user deployment with SQLite
**Coming Soon:** CLI API Client (Phase 6 Planned)
- Thin client for scripting and automation
- Calls Flask API for scan operations
- Results stored centrally in database
- Access to all web features via command line
**Core Scanning Engine:**
- Masscan for port discovery
- Nmap for service detection
- Playwright for screenshots
- sslyze for SSL/TLS analysis
**Deployment:**
- Docker Compose for easy deployment
- SQLite database (single-user, embedded)
- Gunicorn WSGI server
- Optional Nginx reverse proxy
## Development Workflow
### Iteration Cycle
1. **Plan** - Define features for phase
2. **Implement** - Code backend + frontend
3. **Test** - Unit tests + manual testing
4. **Deploy** - Update Docker Compose
5. **Document** - Update README.md, ROADMAP.md
6. **Review** - Get user feedback
7. **Iterate** - Adjust priorities based on feedback
### Git Workflow
- **main branch** - Stable releases
- **develop branch** - Active development
- **feature branches** - Individual features (`feature/dashboard`, `feature/scheduler`)
- **Pull requests** - Review before merge
### Testing Strategy
- **Unit tests** - pytest for models, API endpoints
- **Integration tests** - Full scan → DB → API workflow
- **Manual testing** - UI/UX testing in browser
- **Performance tests** - Large scans, database queries
### Documentation
- **README.md** - User-facing documentation (updated each phase)
- **ROADMAP.md** - This file (updated as priorities shift)
- **CLAUDE.md** - Developer documentation (architecture, code references)
- **API.md** - API documentation (OpenAPI/Swagger in Phase 4)
## Resources & References
### Documentation
- [Flask Documentation](https://flask.palletsprojects.com/)
- [SQLAlchemy ORM](https://docs.sqlalchemy.org/)
- [APScheduler](https://apscheduler.readthedocs.io/)
- [Chart.js](https://www.chartjs.org/docs/)
- [Bootstrap 5](https://getbootstrap.com/docs/5.3/)
### Tutorials
- [Flask Mega-Tutorial](https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-i-hello-world)
- [SQLAlchemy Tutorial](https://docs.sqlalchemy.org/en/20/tutorial/)
- [APScheduler with Flask](https://github.com/viniciuschiele/flask-apscheduler)
### Similar Projects (Inspiration)
- [OpenVAS](https://www.openvas.org/) - Vulnerability scanner with web UI
- [Nessus](https://www.tenable.com/products/nessus) - Commercial scanner (inspiration for UI/UX)
- [OWASP ZAP](https://www.zaproxy.org/) - Web app scanner (comparison reports, alerts)
## Changelog
| Date | Version | Changes |
|------|---------|---------|
| 2025-11-14 | 1.0 | Initial roadmap created based on user requirements |
| 2025-11-13 | 1.1 | **Phase 1 COMPLETE** - Database schema, SQLAlchemy models, Flask app structure, settings system with encryption, Alembic migrations, API blueprints, Docker support, validation script |
| 2025-11-14 | 1.2 | **Phase 2 COMPLETE** - REST API (5 scan endpoints, 3 settings endpoints), background jobs (APScheduler), authentication (Flask-Login), web UI (dashboard, scans, login, errors), error handling (content negotiation, request IDs, logging), 100 tests passing, comprehensive documentation (API_REFERENCE.md, DEPLOYMENT.md, PHASE2_COMPLETE.md) |
| 2025-11-17 | 1.3 | **Bug Fix** - Fixed Chart.js infinite canvas growth issue in scan detail page (duplicate initialization, missing chart.destroy(), missing fixed-height container) |
| 2025-11-17 | 1.4 | **Phase 4 COMPLETE** - Config Creator with CIDR-based creation, YAML editor (CodeMirror), config management UI (list/edit/delete), REST API (7 endpoints), Docker volume permissions fix, comprehensive testing and documentation |
| 2025-11-17 | 1.5 | **Roadmap Compression** - Condensed completed phases (1-4) into concise summaries, updated project scope to emphasize web GUI frontend with CLI as API client coming soon (Phase 6), reorganized phases for clarity |
---
**Last Updated:** 2025-11-17
**Next Review:** Before Phase 5 kickoff (Email & Comparisons)