restructure of dirs, huge docs update
This commit is contained in:
483
docs/ROADMAP.md
483
docs/ROADMAP.md
@@ -1,5 +1,9 @@
|
||||
# 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
|
||||
@@ -11,37 +15,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 & Comparisons** - Next Up
|
||||
- 📋 **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
|
||||
|
||||
## Recent Bug Fixes
|
||||
|
||||
### 2025-11-17: Chart.js Infinite Canvas Growth Fix
|
||||
**Issue:** Scan detail page (`scan_detail.html`) was experiencing infinite scrolling and page lock-up due to Chart.js canvas growing infinitely (height reaching 22302px+).
|
||||
|
||||
**Root Causes:**
|
||||
1. Duplicate initialization - `loadScan()` was being called twice on page load
|
||||
2. Multiple Chart.js instances created on the same canvas without destroying previous ones
|
||||
3. Canvas element without fixed-height container caused infinite resize loop with `responsive: true` and `maintainAspectRatio: false`
|
||||
|
||||
**Fixes Applied:**
|
||||
1. **Consolidated initialization** (`scan_detail.html:172-175`) - Moved `findPreviousScan()` and `loadHistoricalChart()` into `DOMContentLoaded` event listener, removed duplicate call
|
||||
2. **Chart instance tracking** (`scan_detail.html:169`) - Added `let historyChart = null;` to store chart reference
|
||||
3. **Destroy old charts** (`scan_detail.html:501-504`) - Added `historyChart.destroy()` before creating new chart instance
|
||||
4. **Fixed-height container** (`scan_detail.html:136-138`) - Wrapped canvas in `<div style="position: relative; height: 300px;">` to prevent infinite resize loop
|
||||
|
||||
**Files Modified:**
|
||||
- `web/templates/scan_detail.html`
|
||||
|
||||
**Status:** ✅ Fixed and tested
|
||||
|
||||
## 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.
|
||||
|
||||
**Core Features:**
|
||||
- **Centralized dashboard** for viewing scan history and trends
|
||||
@@ -439,33 +420,360 @@ All API endpoints return JSON and follow RESTful conventions.
|
||||
|
||||
---
|
||||
|
||||
### Phase 5: Email & Comparisons
|
||||
### Phase 5: Email, Webhooks & Comparisons
|
||||
**Status:** Next Up
|
||||
**Priority:** MEDIUM
|
||||
|
||||
**Goals:**
|
||||
- Implement email notification system
|
||||
- Create scan comparison reports
|
||||
- Add alert rule configuration
|
||||
- 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. **Email Notifications:**
|
||||
- SMTP integration with configurable settings
|
||||
- Alert email templates (Jinja2 HTML)
|
||||
|
||||
#### 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 triggers for critical events
|
||||
- Email delivery tracking
|
||||
|
||||
2. **Alert Rule Engine:**
|
||||
- Alert types: unexpected ports, cert expiry, service changes, host down, weak TLS
|
||||
- Alert rule creation and management UI
|
||||
- Automatic evaluation after each scan
|
||||
- Alert history with severity filtering
|
||||
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
|
||||
|
||||
3. **Scan Comparison:**
|
||||
- Compare two scans API endpoint
|
||||
- Diff detection (new/removed ports, service changes, cert changes)
|
||||
- Visual comparison UI with highlighting
|
||||
- "Compare" button on scan list
|
||||
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
|
||||
|
||||
---
|
||||
|
||||
@@ -560,34 +868,6 @@ All API endpoints return JSON and follow RESTful conventions.
|
||||
- Gunicorn WSGI server
|
||||
- Optional Nginx reverse proxy
|
||||
|
||||
## Prioritized Feature List
|
||||
|
||||
### Completed ✅ (Phases 1-4)
|
||||
1. **Database foundation** (SQLite3 + SQLAlchemy)
|
||||
2. **Flask web app core** (REST API, authentication)
|
||||
3. **Dashboard with scan history** (list, detail, delete)
|
||||
4. **Trend charts** (Chart.js - port counts over time)
|
||||
5. **Scheduled scans** (APScheduler + cron expressions)
|
||||
6. **Config creator** (CIDR-based, YAML editor)
|
||||
|
||||
### Next Up (Phase 5)
|
||||
7. **Email notifications** (SMTP integration)
|
||||
8. **Alert rules** (cert expiry, unexpected ports, etc.)
|
||||
9. **Scan comparison reports** (diff view)
|
||||
|
||||
### Planned (Phase 6-7)
|
||||
10. **CLI as API client** (token auth, scripting)
|
||||
11. **Sortable/filterable tables** (DataTables.js)
|
||||
12. **PDF export** (WeasyPrint)
|
||||
13. **Vulnerability detection** (CVE integration)
|
||||
14. **Timeline view** (visual scan history)
|
||||
|
||||
### Future/Deferred
|
||||
15. **Multi-user support** (if requirements change)
|
||||
16. **Slack/webhook integrations**
|
||||
17. **Prometheus metrics**
|
||||
18. **Advanced charts** (heatmaps, forecasts)
|
||||
|
||||
## Development Workflow
|
||||
|
||||
### Iteration Cycle
|
||||
@@ -617,69 +897,6 @@ All API endpoints return JSON and follow RESTful conventions.
|
||||
- **CLAUDE.md** - Developer documentation (architecture, code references)
|
||||
- **API.md** - API documentation (OpenAPI/Swagger in Phase 4)
|
||||
|
||||
## Success Metrics
|
||||
|
||||
### Phase 1 Success ✅ ACHIEVED
|
||||
- [x] Database creates successfully with all 11 tables
|
||||
- [x] Settings can be stored/retrieved with encryption
|
||||
- [x] Flask app starts without errors
|
||||
- [x] API blueprints load correctly
|
||||
- [x] All Python modules have valid syntax
|
||||
- [x] Docker deployment configured
|
||||
|
||||
### Phase 2 Success ✅ ACHIEVED
|
||||
- [x] Database stores scan results correctly
|
||||
- [x] REST API functional with all endpoints
|
||||
- [x] Background scans execute asynchronously
|
||||
- [x] Authentication protects all routes
|
||||
- [x] Web UI is intuitive and responsive
|
||||
- [x] 100 tests passing with comprehensive coverage
|
||||
- [x] Docker deployment production-ready
|
||||
|
||||
### Phase 3 Success ✅ ACHIEVED
|
||||
- [x] Dashboard displays scans and trends with charts
|
||||
- [x] Scheduled scans execute automatically
|
||||
- [x] Historical trend charts show scan history
|
||||
- [x] Real-time progress updates for running scans
|
||||
|
||||
### Phase 4 Success ✅ ACHIEVED
|
||||
- [x] Users can create configs from CIDR ranges via web UI
|
||||
- [x] YAML editor with syntax highlighting works correctly
|
||||
- [x] Config management UI provides list/view/edit/download/delete operations
|
||||
- [x] Direct YAML upload works for advanced users
|
||||
- [x] Configs immediately usable in scan triggers and schedules
|
||||
- [x] Delete protection prevents removal of configs used by schedules
|
||||
- [x] All tests passing (25+ unit and integration tests)
|
||||
|
||||
### Phase 5 Success (Email & Comparisons)
|
||||
- [ ] Email notifications sent for critical alerts
|
||||
- [ ] Comparison reports show meaningful diffs
|
||||
- [ ] Settings UI allows SMTP configuration without editing files
|
||||
|
||||
### Phase 6 Success (CLI as API Client)
|
||||
- [ ] CLI can trigger scans via API
|
||||
- [ ] API tokens work for authentication
|
||||
- [ ] Standalone CLI mode still functional
|
||||
|
||||
### Phase 7 Success (Advanced Features)
|
||||
- [ ] CVE integration provides actionable vulnerability data
|
||||
- [ ] Timeline view helps track infrastructure changes
|
||||
- [ ] PDF exports are shareable and professional
|
||||
|
||||
## Open Questions
|
||||
|
||||
### Technical Decisions
|
||||
- **Flask vs. FastAPI?** - Sticking with Flask for simplicity, but FastAPI offers async and auto-docs
|
||||
- **APScheduler vs. Celery?** - APScheduler for simplicity (no Redis/RabbitMQ needed), but Celery scales better
|
||||
- **Bootstrap vs. Tailwind?** - Bootstrap for speed (pre-built components), Tailwind for customization
|
||||
- **Chart.js vs. Plotly?** - Chart.js for lightweight, Plotly for interactive (decide in Phase 3)
|
||||
|
||||
### Product Questions
|
||||
- **Should we support multiple configs per schedule?** - Start with 1:1, add later if needed
|
||||
- **How many scans to keep in DB?** - Add retention setting (default: keep all)
|
||||
- **Support for multi-tenancy?** - Not in scope (single-user), but database schema allows future expansion
|
||||
- **Mobile app?** - Out of scope, but responsive web UI covers basics
|
||||
|
||||
## Resources & References
|
||||
|
||||
### Documentation
|
||||
|
||||
Reference in New Issue
Block a user