# OWASP Top 10 Review **Date**: 2026-03-31 **OWASP Version**: 2025 (8th edition) **Scope**: Full codebase ## Assessment | # | Category | Status | Findings | |---|----------|--------|----------| | A01 | Broken Access Control | FAIL | 3 | | A02 | Security Misconfiguration | FAIL | 2 | | A03 | Software Supply Chain Failures | FAIL | 2 | | A04 | Cryptographic Failures | FAIL | 1 | | A05 | Injection | PASS | — | | A06 | Insecure Design | FAIL | 2 | | A07 | Authentication Failures | FAIL | 1 | | A08 | Software or Data Integrity Failures | PASS | — | | A09 | Logging & Alerting Failures | FAIL | 1 | | A10 | Mishandling of Exceptional Conditions | FAIL | 1 | ## Category Details ### A01: Broken Access Control — FAIL 1. **No authentication required**: All endpoints are publicly accessible. Bearer tokens are optional. Any network-reachable client can trigger inference, access SSE stream, and consume resources. 2. **SSE stream leaks cross-user data**: `/detect/stream` broadcasts all detection events to all connected clients regardless of identity. Horizontal privilege escalation — any user sees every other user's results. 3. **No authorization on media operations**: `/detect/{media_id}` reads any media file that the annotations service returns a path for. No check that the requesting user owns that media. ### A02: Security Misconfiguration — FAIL 1. **Docker containers run as root**: Both `Dockerfile` and `Dockerfile.gpu` do not create or switch to a non-root user. Container compromise gives root filesystem access. 2. **No security headers**: The FastAPI app does not set standard security headers (X-Content-Type-Options, X-Frame-Options, Strict-Transport-Security, Content-Security-Policy). ### A03: Software Supply Chain Failures — FAIL 1. **Unpinned dependencies**: `fastapi`, `uvicorn[standard]`, `python-multipart` are unpinned in `requirements.txt`. A compromised PyPI upload could be silently pulled during build. 2. **Known CVEs in transitive dependencies**: h11 (via uvicorn) has CVE-2025-43859 (CRITICAL — HTTP request smuggling); python-multipart has CVE-2026-28356 (HIGH — ReDoS). ### A04: Cryptographic Failures — FAIL 1. **JWT tokens not cryptographically verified**: `TokenManager._decode_exp()` and `decode_user_id()` decode JWT payloads via base64 without signature verification. Forged tokens are accepted as valid. ### A05: Injection — PASS No SQL, command injection, XSS, LDAP, or template injection patterns found. JSON deserialization uses `json.loads()` which is safe. User input does not reach shell commands or query constructors. ### A06: Insecure Design — FAIL 1. **No rate limiting**: Compute-intensive `/detect` endpoint has no rate limiting. With only 2 ThreadPoolExecutor workers, a small number of requests can exhaust inference capacity. 2. **No input size validation**: Uploaded files are fully read into memory (`await file.read()`) without size checks. Memory exhaustion possible with large payloads. ### A07: Authentication Failures — FAIL 1. **JWT token refresh silently fails**: `TokenManager._refresh()` catches all exceptions and passes silently. Failed refreshes go undetected, potentially allowing expired tokens to be used indefinitely (until the next decode check). ### A08: Software or Data Integrity Failures — PASS No auto-update mechanisms, no CI/CD pipeline in the repo, no unsigned artifact consumption. Model files are loaded from a trusted internal loader service. ### A09: Logging & Alerting Failures — FAIL 1. **Security events not logged**: Authentication failures, token refresh failures, and unauthorized access attempts are silently swallowed (`except Exception: pass`). No audit trail for security-relevant events. ### A10: Mishandling of Exceptional Conditions — FAIL 1. **Silent exception swallowing**: Multiple `except Exception: pass` blocks (token refresh, annotation posting) hide failures. The system "fails open" — errors are ignored and processing continues, potentially in an inconsistent security state.