docs: add comprehensive threat model

STRIDE analysis covering:
- System architecture and trust boundaries
- Attack surface analysis (10 entry points)
- Threat actors (anonymous, authenticated, operator, sophisticated)
- 20+ threats with mitigations across STRIDE categories
- Security controls matrix
- MIME polyglot attack mitigations
- Cryptographic controls
- Residual risks and known limitations
- Incident response guidance
This commit is contained in:
Username
2025-12-26 17:10:41 +01:00
parent dc2da67fb3
commit 98694ba1cc
2 changed files with 288 additions and 1 deletions

View File

@@ -203,7 +203,7 @@ Not tested (no signature defined):
```
[ ] Add remaining MIME test results to security assessment
[ ] Document rate limiting behavior under attack
[ ] Create threat model diagram
[x] Create threat model diagram (documentation/threat-model.md)
[x] Add security headers audit to CI pipeline
```

View File

@@ -0,0 +1,287 @@
# FlaskPaste Threat Model
Security architecture, attack surfaces, and mitigations for FlaskPaste.
---
## System Architecture
```
INTERNET
|
+-----------+-----------+
| HAProxy/nginx |
| (TLS termination) |
+-----------+-----------+
|
+-----------+-----------+
| FlaskPaste |
| (Flask + Gunicorn) |
+-----------+-----------+
|
+-----------+-----------+
| SQLite DB |
| (paste storage) |
+-----------------------+
```
### Trust Boundaries
```
+----------------------------------------------------------------+
| UNTRUSTED ZONE |
| - Anonymous users |
| - Public internet |
+----------------------------------------------------------------+
|
[TLS + PoW Challenge]
|
+----------------------------------------------------------------+
| SEMI-TRUSTED ZONE |
| - HAProxy/nginx reverse proxy |
| - Rate limiting enforcement |
+----------------------------------------------------------------+
|
[X-Proxy-Secret validation]
|
+----------------------------------------------------------------+
| TRUSTED ZONE |
| - Flask application |
| - SQLite database |
| - PKI CA (if enabled) |
+----------------------------------------------------------------+
```
---
## Attack Surface Analysis
### Entry Points
| Entry Point | Protocol | Auth | Rate Limited | Description |
|-------------|----------|------|--------------|-------------|
| POST / | HTTPS | Optional | Yes | Create paste |
| GET /{id} | HTTPS | Optional | Yes | View paste metadata |
| GET /{id}/raw | HTTPS | Optional | Yes | View raw content |
| HEAD /{id} | HTTPS | None | Yes | Check existence |
| DELETE /{id} | HTTPS | Required | Yes | Delete paste |
| GET /challenge | HTTPS | None | Yes | Get PoW challenge |
| POST /pki/* | HTTPS | Required | Yes | PKI operations |
| GET /metrics | HTTPS | None | No | Prometheus metrics |
| GET /health | HTTPS | None | No | Health check |
### Data Flows
```
User Input Flow:
+--------+ +-------+ +---------+ +--------+
| Client | --> | Proxy | --> | Flask | --> | SQLite |
+--------+ +-------+ +---------+ +--------+
| | |
| [Rate Limit] [Validation]
| | |
+-- PoW -------+ [MIME detect]
+-- Password --+--------[PBKDF2 hash]
+-- Content ---+--------[Size check]
+-- mTLS cert -+--------[SHA1 verify]
```
---
## Threat Actors
### Anonymous Attacker
- **Motivation:** Abuse, DoS, content injection
- **Capabilities:** Automated tools, botnets
- **Mitigations:** PoW, rate limiting, anti-flood
### Authenticated Attacker
- **Motivation:** Data exfiltration, privilege escalation
- **Capabilities:** Valid credentials, API access
- **Mitigations:** Ownership checks, audit logging
### Malicious Operator
- **Motivation:** Credential theft, data access
- **Capabilities:** Proxy access, log access
- **Mitigations:** X-Proxy-Secret, no plaintext passwords
### Sophisticated Attacker
- **Motivation:** Zero-day exploitation, APT
- **Capabilities:** Reverse engineering, timing attacks
- **Mitigations:** Constant-time operations, defense in depth
---
## Threat Categories (STRIDE)
### Spoofing
| Threat | Vector | Mitigation | Status |
|--------|--------|------------|--------|
| Client identity spoofing | Forge X-SSL-Client-SHA1 | X-Proxy-Secret validation | MITIGATED |
| IP address spoofing | Forge X-Forwarded-For | Proxy secret required | MITIGATED |
| Paste ownership claim | Guess owner cert SHA1 | 40-char hex, DB lookup | MITIGATED |
### Tampering
| Threat | Vector | Mitigation | Status |
|--------|--------|------------|--------|
| Content modification | MITM attack | TLS 1.3 required | MITIGATED |
| Paste content tampering | Direct DB access | File permissions, no shell access | MITIGATED |
| PoW token replay | Reuse solved challenge | Token expiration (60s) | MITIGATED |
### Repudiation
| Threat | Vector | Mitigation | Status |
|--------|--------|------------|--------|
| Deny paste creation | No audit trail | Audit logging with X-Request-ID | MITIGATED |
| Deny deletion | Claim not deleted | Audit log with operator ID | MITIGATED |
### Information Disclosure
| Threat | Vector | Mitigation | Status |
|--------|--------|------------|--------|
| Paste enumeration | Sequential IDs | Random hex IDs (64-bit entropy) | MITIGATED |
| Password-protected content | Brute force | PBKDF2 600k iterations, rate limit | MITIGATED |
| Timing oracle on passwords | Response time variance | Constant-time comparison | MITIGATED |
| Burn-after-read race | HEAD then GET | HEAD triggers deletion | MITIGATED |
| Metrics exposure | /metrics endpoint | Public by design (no PII) | ACCEPTED |
### Denial of Service
| Threat | Vector | Mitigation | Status |
|--------|--------|------------|--------|
| Request flooding | High volume requests | Rate limiting (per-IP) | MITIGATED |
| Content spam | Large pastes | Size limits (100KB anon, 10MB auth) | MITIGATED |
| Memory exhaustion | Unbounded dicts | MAX_ENTRIES caps (10000) | MITIGATED |
| CPU exhaustion | Complex operations | PoW offloads to client | MITIGATED |
| Anti-flood bypass | Distributed attack | Dynamic PoW (16-28 bits) | MITIGATED |
| Content hash bypass | Unique content | Dedup window + PoW | MITIGATED |
### Elevation of Privilege
| Threat | Vector | Mitigation | Status |
|--------|--------|------------|--------|
| Delete others' pastes | Guess owner ID | Ownership verification | MITIGATED |
| Bypass size limits | Forge auth header | X-Proxy-Secret required | MITIGATED |
| PKI CA compromise | Unauthorized cert issue | Client cert required | MITIGATED |
| SQL injection | Malformed input | Parameterized queries | MITIGATED |
| SSTI | Template injection | No user content in templates | MITIGATED |
| Command injection | Shell escape | No shell execution | MITIGATED |
---
## Security Controls Matrix
```
+---------------------+------------------------------------------+
| Layer | Controls |
+---------------------+------------------------------------------+
| Network | TLS 1.3, mTLS (optional), X-Proxy-Secret |
| Transport | Security headers, CSP, X-Frame-Options |
| Application | Input validation, MIME detection, PoW |
| Session | Stateless, no cookies, no CSRF needed |
| Data | PBKDF2 passwords, random IDs, expiry |
| Audit | Request ID tracking, structured logging |
| Operations | Rate limiting, anti-flood, size limits |
+---------------------+------------------------------------------+
```
---
## MIME Detection Security
Content is detected by magic bytes, not user-supplied Content-Type:
```
User uploads "image.png" with PHP payload
|
v
[Magic byte detection] --> Not PNG magic --> text/plain
|
[X-Content-Type-Options: nosniff] --> Browser won't sniff
|
[CSP: default-src 'none'] --> No script execution
```
### Polyglot Attack Mitigations
| Attack | Detection | Result |
|--------|-----------|--------|
| PNG + HTML | PNG magic detected | image/png |
| GIF + JS | GIF magic detected | image/gif |
| PDF + ZIP | PDF magic detected | application/pdf |
| SVG + script | No XML magic | text/plain |
| JPEG + PHP | JPEG magic detected | image/jpeg |
---
## Cryptographic Controls
| Purpose | Algorithm | Parameters |
|---------|-----------|------------|
| Password hashing | PBKDF2-SHA256 | 600,000 iterations |
| Paste ID generation | secrets.token_hex | 32 chars (128 bits) |
| PoW challenge | SHA-256 | Variable difficulty (16-28 bits) |
| HMAC verification | hmac.compare_digest | Constant-time |
| PKI certificates | RSA-2048 / ECDSA P-256 | SHA-256 signing |
---
## Residual Risks
### Accepted Risks
| Risk | Justification | Monitoring |
|------|---------------|------------|
| Metrics exposed | No PII, needed for monitoring | Access logs |
| Anonymous paste creation | Core functionality | Rate limiting |
| Content storage | User-provided, may be malicious | MIME detection |
### Known Limitations
| Limitation | Impact | Workaround |
|------------|--------|------------|
| TAR detection | ustar at offset 257 | Falls back to text/plain |
| Java .class files | 0xCAFEBABE = Mach-O | Falls back to Mach-O |
| Large file DoS | Memory during upload | Gunicorn body limit |
---
## Audit Compliance
| Control | Evidence | Frequency |
|---------|----------|-----------|
| Input validation | Unit tests | Every commit (CI) |
| Rate limiting | Integration tests | Every commit (CI) |
| Security headers | headers_audit.py | Every commit (CI) |
| Injection prevention | Fuzz tests | Every commit (CI) |
| Timing attacks | Timing tests | Weekly |
| Penetration testing | pentest_session.py | Monthly |
---
## Incident Response
### Detection Points
- `/metrics` - Request rates, error rates, PoW difficulty
- Audit logs - Unusual patterns, failed auth attempts
- Anti-flood - Difficulty increase indicates attack
### Response Actions
| Trigger | Automatic Response | Manual Response |
|---------|-------------------|-----------------|
| High request rate | PoW difficulty increase | Review logs, block IPs |
| Failed auth spike | Rate limit enforcement | Investigate, rotate certs |
| Large paste flood | Size limit rejection | Block IP range |
| Enumeration attempt | 400 responses | Add to blocklist |
---
## Version History
| Date | Change |
|------|--------|
| 2025-12-26 | Initial threat model |