Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
284 changes: 284 additions & 0 deletions docs/secure-deployment-guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,284 @@
# SecuScan Secure Deployment Guide & Operator Threat Model

This document outlines the security architecture, trust boundaries, threat modeling, and secure deployment hardening procedures for operators deploying SecuScan in local, LAN, or containerized production environments.

As a high-powered pentesting and vulnerability scanning toolkit, SecuScan executes network operations, runs system commands, and stores highly sensitive credentials (API keys, target scopes, and vulnerability records). Standard security controls must be strictly maintained by the system operator.

---

## 1. Security Architecture & Trust Boundaries

SecuScan is designed with a **local-first** security philosophy. Out of the box, the backend acts as a single-user system running on loopback (`127.0.0.1:8000`) with no built-in multi-tenant authentication or isolation. When deploying, the operator must understand three core trust boundaries:

```mermaid
graph TD
subgraph "External Boundary"
T[External Network / Targets]
end
subgraph "Host Isolation Boundary"
subgraph "Sandbox Layer"
P1[Docker Plugin 1]
P2[Docker Plugin 2]
end
B[SecuScan Backend API]
V[(SQLite DB / Vault)]
end
subgraph "Operator Boundary"
O[Local Operator / UI Dashboard]
Proxy[Reverse Proxy / Auth Gateway]
end

O -->|Local Loopback Only / Authenticated Proxy| B
Proxy -->|Handles SSL/Auth| B
B -->|Decrypts Secrets| V
B -->|Launches & Isolates| P1
B -->|Launches & Isolates| P2
P1 -->|Probes / Scans| T
```

### The Three Trust Boundaries:

1. **Operator to Backend Boundary**: The API exposes execution points that can run terminal commands via plugins. Access to this boundary must be restricted to authorized operators only. Placing the backend directly on a public IP without authentication is an immediate, critical vulnerability.
2. **Backend to Sandbox Boundary**: The backend triggers third-party plugins. Because plugins evaluate system scopes and templates, they must be isolated (either via Docker containers or strict system permission policies) to prevent host compromise.
3. **Sandbox to Network Boundary**: Scanners send packets to external targets. The outbound network flows must be governed by active guardrails (Safe Mode) to prevent self-scanning or unauthorized scanning of critical environments.

---

## 2. Operator Threat Model (STRIDE-based)

The following threat modeling table details operational risks, target boundaries, and respective mitigations:

| Threat Category | Specific Threat | Target Boundary | Impact | Mitigation / Configuration |
| :--- | :--- | :--- | :--- | :--- |
| **Spoofing (S)** | Unauthorized user accesses the API or hijacks an active operator session. | Operator to Backend | Attackers can launch unauthorized scans, edit secret values, or read audit logs. | Bind backend to `127.0.0.1:8000` only. In multi-user LANs, place behind an authenticating reverse proxy (Authelia/OAuth2) and enable `SECUSCAN_TRUSTED_PROXIES` for client rate limiting. |
| **Tampering (T)** | Compromised plugin or directory path traversal alters scanner output or inputs. | Backend to Sandbox | Malicious report generation, file injection, or database manipulation. | Enable plugin signature verification (`SECUSCAN_ENFORCE_PLUGIN_SIGNATURES=true`). Ensure `is_safe_path` validation is strictly enforced on path targets to prevent directory traversal. |
| **Repudiation (R)** | Operator performs intrusive scans or downloads secret vault keys without log generation. | Operator to Backend | Inability to track internal misuse, compromise, or unauthorized target scanning. | Backend automatically writes critical events (e.g. `report_downloaded`, `secret_stored`) to the SQLite database audit log (`audit_log`). Retain and ship these logs off-host securely. |
| **Information Disclosure (I)** | plaintext credential vault key leaks through public git repositories, environment dumps, or logs. | Host Isolation Boundary | Attackers can decrypt all stored third-party API keys, tokens, and sweep target credentials. | deriving a cryptographically strong 32-byte key from `SECUSCAN_VAULT_KEY`. Never use the default fallback in production. Ensure logs are sanitized and block raw target leaks in errors. |
| **Denial of Service (D)** | Intrusive scanning sweeps overwhelm target infrastructure or exhaust local host memory/CPU. | Sandbox to Network | Local system crashes due to high task concurrency, or scanner targets collapse, triggering legal action. | Configure `SECUSCAN_MAX_CONCURRENT_TASKS=3`. Apply `EndpointRateLimiter` dependencies to mutation (`task_start`, `vault`) and catalog endpoints to prevent abuse. Limit sandbox resource usage. |
| **Elevation of Privilege (E)** | Compromised plugin subverts shell templating, executing arbitrary commands as root on the host machine. | Backend to Sandbox | Full host compromise, data loss, and lateral movement in the hosting subnet. | Set `SECUSCAN_DOCKER_ENABLED=true` to force plugin sandboxing. Restrict container resources (`SECUSCAN_SANDBOX_CPU_QUOTA=0.5` and `SECUSCAN_SANDBOX_MEMORY_MB=512`) and run Docker in rootless mode. |

---

## 3. Local-Only Design vs. Network Exposure

By default, SecuScan is a **local single-operator utility**.

### Local-Only Topology (Recommended)
The backend binds to `127.0.0.1:8000`. The frontend communicates with it purely on loopback. Firewalls block port 8000 from all external interfaces.

### Remote / Team Server Topology
If you must host SecuScan on a central server for a security team:
1. **DO NOT** expose `8000` to the internet or shared subnets directly.
2. **DO NOT** configure the backend to bind to `0.0.0.0` without an upstream authenticating proxy.
3. **DO** set up a reverse proxy (Nginx, Traefik, Apache) to terminate TLS and handle robust authentication (e.g., Basic Authentication, Authelia, or Keycloak).

---

## 4. Credential Vault & Key Management

SecuScan stores sensitive data—such as third-party API keys and secrets—encrypted inside its SQLite database using AES-256 in CBC mode (Fernet) via the Python `cryptography` library.

### Key Derivation Mechanics
1. During startup, the system reads the environment variable `SECUSCAN_VAULT_KEY`.
2. It derives a deterministic 32-byte key using SHA-256:
```python
seed = settings.vault_key or settings.plugin_signature_key or "secuscan-dev-key"
digest = hashlib.sha256(seed.encode("utf-8")).digest()
key = base64.urlsafe_b64encode(digest)
```

### How to Generate a Secure Vault Key
Never rely on the default fallback seed (`"secuscan-dev-key"`). Generate a strong, unique high-entropy key before starting the service:

**Option A: Using OpenSSL (Terminal)**
```bash
openssl rand -base64 32
# Output example: wL/f2Fm09r3j6K0A9XpLh6eU7rD5xN2yQ4j1k9v8c0o=
```

**Option B: Using Python**
```python
python3 -c "import secrets; print(secrets.token_urlsafe(32))"
```

Export this key to the environment before running the backend:
```bash
export SECUSCAN_VAULT_KEY="your-high-entropy-generated-token"
```

### Key Rotation Procedure
If you need to rotate your vault key:
1. Stop the SecuScan service.
2. Export the *old* key as `SECUSCAN_OLD_VAULT_KEY` and the *new* key as `SECUSCAN_VAULT_KEY`.
3. Execute the migration command to decrypt and re-encrypt the database entries (or manually recreate the secrets).
4. Remove the old key from the environment.

---

## 5. Plugin Sandboxing & Execution Isolation

Plugins are powerful, dynamic, and potentially dangerous because they execute system processes. Operators have three core safety controls:

### A. Docker Execution Sandbox (Highly Recommended)
By default, plugins run on the host's native OS, which carries risk if a plugin is compromised. To isolate them inside Docker containers, set:
```bash
export SECUSCAN_DOCKER_ENABLED=true
```
This forces the backend to run all scan tasks inside lightweight Docker containers, isolating the filesystem and subverting host privilege escalation. Ensure you also tune the quotas to prevent resource exhaustion:
* `SECUSCAN_SANDBOX_CPU_QUOTA=0.5` (Limits containers to half a CPU core)
* `SECUSCAN_SANDBOX_MEMORY_MB=512` (Limits containers to 512 MB RAM)
* `SECUSCAN_SANDBOX_TIMEOUT=600` (Forces standard tasks to abort after 10 minutes)

### B. Plugin Signature Verification
Compromised plugins can introduce remote code execution (RCE). To only allow plugins cryptographically signed by trusted authors, enable:
```bash
export SECUSCAN_ENFORCE_PLUGIN_SIGNATURES=true
export SECUSCAN_PLUGIN_SIGNATURE_KEY="your-public-verification-key"
```

---

## 6. Network Exposure Guardrails (Safe Mode)

SecuScan includes built-in network guardrails designed to prevent accidental target scanning or scanning of restricted infrastructure:

```bash
export SECUSCAN_SAFE_MODE_DEFAULT=true
```

When `Safe Mode` is enabled:
1. **Public IPs are Blocked**: Targets resolving to public IP addresses (e.g. `8.8.8.8`, `1.1.1.1`) are immediately rejected.
2. **Allowed Subnets**: Scans are strictly restricted to private networks (RFC 1918) defined in the configuration, typically matching local lab or intranet subnets:
```bash
SECUSCAN_ALLOWED_NETWORKS="127.0.0.1, 192.168.*.*, 10.*.*.*, 172.16.*.*"
```
3. **Blocked TLDs**: Domain targets ending in critical Top Level Domains (such as `.gov` or `.mil`) are automatically blocked at the validator layer before packets are sent.
4. **Loopback Scan Controls**: If you want to restrict scans of the local host itself, you can disable loopback scans:
```bash
export SECUSCAN_ALLOW_LOOPBACK_SCANS=false
```

---

## 7. Actionable Deployment Profiles

### Profile A: Local Desktop (Single User)
Best for standalone security researchers, running on a single laptop/workstation.

* **Setup**: Binds purely to loopback. Docker sandboxing is enabled for plugin isolation.
* **Environment File (`.env`)**:
```bash
SECUSCAN_BIND_ADDRESS="127.0.0.1"
SECUSCAN_BIND_PORT=8000
SECUSCAN_DEBUG=false
SECUSCAN_VAULT_KEY="generate-a-strong-32-byte-key"
SECUSCAN_DOCKER_ENABLED=true
SECUSCAN_ALLOW_LOOPBACK_SCANS=true
SECUSCAN_SAFE_MODE_DEFAULT=true
```

---

### Profile B: Team LAN Server (Shared Subnet)
Best for internal security teams working within a local LAN.

* **Setup**: Binds to local interface, behind an Nginx reverse proxy running Basic Authentication to prevent unauthorized access.
* **Nginx Configuration Template (`/etc/nginx/sites-available/secuscan`)**:
```nginx
server {
listen 443 ssl http2;
server_name secuscan.local;

# TLS configuration
ssl_certificate /etc/ssl/certs/secuscan.crt;
ssl_certificate_key /etc/ssl/private/secuscan.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;

# Basic Auth block for team authentication
auth_basic "SecuScan Restricted Access";
auth_basic_user_file /etc/nginx/.htpasswd;

location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

# SSE streaming settings (critical for scan log streams)
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_cache off;
proxy_buffering off;
chunked_transfer_encoding on;
proxy_read_timeout 86400s;
}
}
```
* **Environment File (`.env`)**:
```bash
SECUSCAN_BIND_ADDRESS="127.0.0.1"
SECUSCAN_BIND_PORT=8000
SECUSCAN_TRUSTED_PROXIES="127.0.0.1" # Allows rate limiting to trace real IP behind proxy
SECUSCAN_VAULT_KEY="generate-a-strong-32-byte-key"
SECUSCAN_DOCKER_ENABLED=true
SECUSCAN_ALLOW_LOOPBACK_SCANS=false # Prevent team members from scanning the host server
SECUSCAN_SAFE_MODE_DEFAULT=true
```

---

### Profile C: Production Containerized (Docker Compose)
Best for scalable, clean container deployment.

* **Setup**: Deploy backend and frontend containers with locked down read-only volumes and rate limits.
* **Deployment Configuration (`docker-compose.yml`)**:
```yaml
version: '3.8'

services:
backend:
image: secuscan-backend:latest
build:
context: ./backend
dockerfile: Dockerfile
environment:
- SECUSCAN_BIND_ADDRESS=0.0.0.0
- SECUSCAN_BIND_PORT=8000
- SECUSCAN_VAULT_KEY=your_generated_secret_here
- SECUSCAN_DOCKER_ENABLED=true
- SECUSCAN_SAFE_MODE_DEFAULT=true
- SECUSCAN_ALLOW_LOOPBACK_SCANS=false
- SECUSCAN_TRUSTED_PROXIES=10.0.0.0/8,172.16.0.0/12,192.168.0.0/16
volumes:
- /var/run/docker.sock:/var/run/docker.sock # Required if launching nested plugins
- secuscan-data:/app/data
ports:
- "127.0.0.1:8000:8000" # Expose ONLY to loopback on host
restart: unless-stopped
networks:
- secuscan-net

volumes:
secuscan-data:

networks:
secuscan-net:
driver: bridge
```

---

## 8. Operator Hardening Checklist

Before deploying SecuScan in a shared or active scanner environment, run through this pre-flight checklist:

- [ ] **Symmetric Encryption Key Derived**: Ensure `SECUSCAN_VAULT_KEY` is set to a unique, high-entropy 32-byte token (Generated via OpenSSL or Secrets library).
- [ ] **Bind Address Locked Down**: Confirm the service binds to loopback (`127.0.0.1`) rather than `0.0.0.0` unless placed directly behind a firewalled proxy.
- [ ] **SSL/TLS Active**: If exposed to a LAN, confirm the reverse proxy terminates connection with modern TLS configurations (TLS 1.2 or 1.3 only).
- [ ] **Authentication Enabled**: Confirm Nginx basic auth or an authentication wrapper (Authelia, Keycloak) prevents unauthorized entry to port 8000/443.
- [ ] **Docker Socket Isolated**: If `SECUSCAN_DOCKER_ENABLED` is true, run Docker in rootless mode on the host to avoid container escape risks.
- [ ] **Limits Enforced**: Ensure endpoint rate limiters are active to prevent scan/auth abuse under high concurrency.
- [ ] **Target Scope Defined**: Confirm `SECUSCAN_SAFE_MODE_DEFAULT` is active for untrusted operator environments to protect external networks.
- [ ] **Audit Logging Preserved**: Set SQLite database permissions such that only the backend process can write to `secuscan.db` and audit logs are regularly monitored.
Loading