# Security Audit Report **Date**: 2026-03-31 **Scope**: Azaion.Detections (full codebase) **Verdict**: FAIL → **REMEDIATED** (Critical/High resolved 2026-04-01) ## Summary | Severity | Count | Resolved | |----------|-------|---------| | Critical | 1 | 1 ✓ | | High | 3 | 3 ✓ | | Medium | 5 | 2 ✓ | | Low | 5 | — | ## OWASP Top 10 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 | ## Findings | # | Severity | Category | Location | Title | Status | |---|----------|----------|----------|-------|--------| | 1 | Critical | A03 Supply Chain | requirements.txt (uvicorn→h11) | HTTP request smuggling via h11 CVE-2025-43859 | **FIXED** — pinned h11==0.16.0 | | 2 | High | A04 Crypto | src/main.py | JWT decoded without signature verification | **FIXED** — PyJWT HMAC verification | | 3 | High | A01 Access Control | src/main.py (all routes) | No authentication required on any endpoint | **FIXED** — require_auth dependency on all protected endpoints | | 4 | High | A03 Supply Chain | requirements.txt (python-multipart) | ReDoS via python-multipart CVE-2026-28356 | **FIXED** — pinned python-multipart>=1.3.1 | | 5 | Medium | A01 Access Control | src/main.py | SSE stream broadcasts cross-user data | **FIXED** — per-job SSE (GET /detect/{media_id}), each client sees only their job | | 6 | Medium | A06 Insecure Design | src/main.py | No rate limiting on inference endpoints | Open — out of scope for this cycle | | 7 | Medium | A02 Misconfig | Dockerfile, Dockerfile.gpu | Containers run as root | **FIXED** — non-root appuser added | | 8 | Medium | A03 Supply Chain | requirements.txt | Unpinned critical dependencies | **FIXED** — all deps pinned | | 9 | Medium | A02 Misconfig | Dockerfile, Dockerfile.gpu | No TLS and no security headers | Open — handled at infra/proxy level | | 10 | Low | A06 Insecure Design | src/main.py | No request body size limit | Open | | 11 | Low | A10 Exceptions | src/main.py | Silent exception swallowing | Open | | 12 | Low | A09 Logging | src/main.py | Security events not logged | Open | | 13 | Low | A01 Access Control | src/main.py | Exception details leaked in responses | Open | | 14 | Low | A07 Auth | src/main.py | Token refresh failure silently ignored | Open (by design for offline mode) | ### Finding Details **F1: HTTP Request Smuggling via h11** (Critical / A03) - Location: `requirements.txt` — unpinned `uvicorn[standard]` pulls `h11-0.14.0` - Description: CVE-2025-43859 (CVSS 9.1). Lenient parsing of chunked-coding line terminators enables HTTP request smuggling. - Impact: Bypass security controls, cache poisoning, session hijacking, data leakage - Remediation: Pin `h11>=0.15.0` in requirements.txt **F2: JWT Decoded Without Signature Verification** (High / A04) - Location: `src/main.py:67-99` (`TokenManager._decode_exp`, `decode_user_id`) - Description: JWT payloads are base64-decoded without cryptographic signature verification. Any client can forge tokens with arbitrary claims. - Impact: Full user impersonation — attacker crafts JWT with target's user ID to access their AI settings, post annotations under their account - Remediation: Use PyJWT with signature verification against the issuer's public key **F3: No Authentication on Endpoints** (High / A01) - Location: `src/main.py` — all route handlers - Description: All endpoints are publicly accessible. Bearer tokens are optional. - Impact: Unauthorized inference triggering, resource exhaustion, unauthorized access to SSE event stream - Remediation: Add FastAPI dependency injection for auth middleware on `/detect`, `/detect/{media_id}`, `/detect/stream` **F4: python-multipart ReDoS** (High / A03) - Location: `requirements.txt` — unpinned `python-multipart` - Description: CVE-2026-28356 (CVSS 7.5). `parse_options_header()` regex causes exponential backtracking on malicious headers. - Impact: Denial of service - Remediation: Pin `python-multipart>=1.3.1` **F5: SSE Stream Cross-User Data Leak** (Medium / A01) - Location: `src/main.py:608-627` - Description: All detection events broadcast to all connected SSE clients without filtering. - Impact: Any client sees all users' detection results (media IDs, coordinates, status) - Remediation: Associate SSE queues with authenticated users; filter events by ownership **F6: No Rate Limiting** (Medium / A06) - Location: `src/main.py:348-469`, `src/main.py:494-605` - Description: No rate limiting on compute-intensive inference endpoints. - Impact: DoS via inference exhaustion (2 worker threads) - Remediation: Add slowapi or similar rate limiting middleware **F7: Docker Containers Run as Root** (Medium / A02) - Location: `Dockerfile:10`, `Dockerfile.gpu:10` - Description: No USER directive; processes run as root inside containers. - Impact: Container escape or compromise gives root filesystem access - Remediation: Add non-root user (`adduser --disabled-password appuser && USER appuser`) **F8: Unpinned Critical Dependencies** (Medium / A03) - Location: `requirements.txt` - Description: `fastapi`, `uvicorn[standard]`, `python-multipart` are unpinned. - Impact: Supply chain attack via compromised PyPI package; inconsistent builds across environments - Remediation: Pin all dependencies to specific versions **F9: No TLS / No Security Headers** (Medium / A02) - Location: `Dockerfile` CMD, `src/main.py` (app setup) - Description: Uvicorn runs without TLS. No security headers middleware. - Impact: Data in transit is unencrypted; missing browser security protections - Remediation: Terminate TLS at reverse proxy or add `--ssl-*` flags; add security headers middleware **F10-F14**: Low severity findings (request size limits, exception handling, logging gaps) documented in `static_analysis.md` and `owasp_review.md`. ## Dependency Vulnerabilities | Package | CVE | Severity | Fix Version | |---------|-----|----------|-------------| | h11 (via uvicorn) | CVE-2025-43859 | Critical | h11>=0.15.0 | | python-multipart | CVE-2026-28356 | High | >=1.3.1 | | opencv-python | — | Low (outdated) | 4.13.0.92 | ## Recommendations ### Immediate (Critical/High) 1. **Pin h11>=0.15.0** to fix HTTP request smuggling vulnerability 2. **Pin python-multipart>=1.3.1** to fix ReDoS vulnerability 3. **Pin all dependencies** to specific versions in requirements.txt 4. **Add JWT signature verification** using PyJWT with the issuer's public key 5. **Add authentication middleware** requiring valid tokens on /detect, /detect/{media_id}, /detect/stream ### Short-term (Medium) 6. **Filter SSE events by user** — associate queues with authenticated sessions 7. **Add rate limiting** on inference endpoints (slowapi or nginx rate limiting) 8. **Run containers as non-root** — add USER directive to Dockerfiles 9. **Add security headers** middleware (X-Content-Type-Options, X-Frame-Options, HSTS) 10. **Configure TLS** at reverse proxy level or add Dockerfile HEALTHCHECK ### Long-term (Low / Hardening) 11. **Add request body size limits** via uvicorn config or middleware 12. **Log security events** — authentication failures, token refresh failures, rate limit hits 13. **Replace silent exception handling** with proper error logging 14. **Set up CI/CD** with dependency scanning, SAST, and secret scanning 15. **Add CORS configuration** if browser clients will access the API directly