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

73 lines
4.6 KiB
Markdown

# 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