# 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.
