Files
detections/_docs/05_security/static_analysis.md
T
Oleksandr Bezdieniezhnykh be4cab4fcb [AZ-178] Implement streaming video detection endpoint
- Added `/detect/video` endpoint for true streaming video detection, allowing inference to start as upload bytes arrive.
- Introduced `run_detect_video_stream` method in the inference module to handle video processing from a file-like object.
- Updated media hashing to include a new function for computing hashes directly from files with minimal I/O.
- Enhanced documentation to reflect changes in video processing and API behavior.

Made-with: Cursor
2026-04-01 03:11:43 +03:00

4.6 KiB

Static Analysis (SAST)

Date: 2026-03-31 Scope: src/, e2e/, root config files Method: Manual code review with pattern matching

Findings

F1: JWT Tokens Decoded Without Signature Verification (HIGH)

  • Location: src/main.py:67-99 (TokenManager._decode_exp, TokenManager.decode_user_id)
  • Description: JWT payloads are base64-decoded and parsed directly without cryptographic signature verification. Any attacker can forge a JWT with arbitrary claims (user ID, expiration).
  • Impact: An attacker can impersonate any user by crafting a JWT with a target's sub/userId claim, then use that to read their AI settings or post annotations under their account.
  • Remediation: Verify JWT signatures using the issuer's public key or shared secret before trusting claims. Use a library like PyJWT with algorithms and verify=True.

F2: No Authentication Required on Any Endpoint (HIGH)

  • Location: src/main.py:325-627 (all route handlers)
  • Description: All endpoints (/detect, /detect/{media_id}, /detect/stream, /health) are publicly accessible. Bearer tokens are optional — requests without tokens proceed normally with reduced functionality.
  • Impact: Any network-reachable client can trigger AI inference (expensive compute), read the SSE event stream (all detection events for all users), and consume server resources.
  • Remediation: Add authentication middleware requiring valid tokens on /detect, /detect/{media_id}, and /detect/stream. Keep /health public.

F3: SSE Event Stream Broadcasts to All Clients (MEDIUM)

  • Location: src/main.py:608-627 (detect_stream)
  • Description: The /detect/stream SSE endpoint broadcasts all detection events (including mediaId and annotations) to every connected client via a shared _event_queues list. There is no per-user filtering or authentication.
  • Impact: Any connected client receives detection results for all users, leaking media IDs, detection coordinates, and processing status of other users' media.
  • Remediation: Associate each SSE queue with an authenticated user and filter events by user ownership.

F4: No Rate Limiting on Compute-Intensive Endpoints (MEDIUM)

  • Location: src/main.py:348-469 (/detect), src/main.py:494-605 (/detect/{media_id})
  • Description: No rate limiting or throttling on endpoints that trigger AI inference. The ThreadPoolExecutor has only 2 workers, making it easy to exhaust.
  • Impact: An attacker can repeatedly call /detect with valid images to consume all inference capacity, causing denial of service for legitimate users.
  • Remediation: Add rate limiting middleware (e.g., slowapi) on inference endpoints.

F5: Exception Details Leaked in HTTP Responses (LOW)

  • Location: src/main.py:449-450
  • Description: RuntimeError and ValueError messages are passed directly to HTTPException(detail=str(e)). Internal error messages could reveal implementation details.
  • Impact: Information disclosure of internal error messages to external clients.
  • Remediation: Return generic error messages to clients; log detailed errors server-side only.

F6: Silent Exception Swallowing (LOW)

  • Location: src/main.py:63-64 (_refresh), src/main.py:490-491 (_post_annotation_to_service)
  • Description: Multiple except Exception: pass blocks silently ignore errors, including potential security-relevant failures like token refresh failures or annotation posting failures.
  • Impact: Security-relevant events (failed auth refresh, failed API calls) go undetected, making incident investigation difficult.
  • Remediation: Log exceptions at WARNING level instead of silently swallowing.

F7: No Request Body Size Limit (LOW)

  • Location: src/main.py:348-469 (/detect upload endpoint)
  • Description: No explicit limit on uploaded file size. Large uploads could exhaust memory (entire file is read into memory with await file.read()).
  • Impact: Memory exhaustion DoS via oversized uploads.
  • Remediation: Configure uvicorn/nginx --limit-request-body or check Content-Length before reading.

Summary

Severity Count
Critical 0
High 2
Medium 2
Low 3

No Issues Found

  • Injection: No SQL, command injection, XSS, or template injection patterns detected
  • Hardcoded credentials: No secrets, API keys, or passwords in source code
  • Insecure deserialization: No pickle/marshal usage
  • File write safety: Upload paths use content hashes with whitelisted extensions