EpisodeMatcher/SECURITY.md
Jarian 9d3f8e46a0 feat: Docker deployment, nginx security config, audit report (#11, #14-#22)
- Add Dockerfile with MediaInfo, non-root user, slim base
- Add docker-compose.yml with env_file and volume mounts
- Add nginx.conf with security headers (CSP, HSTS, X-Frame-Options, X-Content-Type-Options)
- Hide server version (server_tokens off)
- Add SECURITY.md with full audit report and deployment guide
- Add .dockerignore for clean builds

Closes #11, #14, #21, #22
2026-07-05 08:10:04 +00:00

61 lines
2.9 KiB
Markdown

# Security Audit Report — Episode Matcher
## Fixed Issues
### Critical
- **[CWE-22] Path Traversal in TVDB Cache (#2)** — Sanitized series names, validated cache paths stay within cache directory.
### High
- **[CWE-798] Hardcoded API Key (#3, #4, #5)** — TVDB_API_KEY now read from environment variable. config.json removed from git history, added to .gitignore.
- **[CWE-22] Incomplete .gitignore (#6)** — Added config.json, __pycache__, .env, build artifacts.
- **[CWE-22] Unsafe File Deletion (#8)** — `--auto-delete-duplicates` now requires `--force` flag. Deletions logged to recovery manifest.
### Medium
- **[CWE-561] sys.path Manipulation (#7)** — Added pyproject.toml for proper packaging with editable install support.
- **[CWE-20] Duplicate Detection (#9)** — Added SHA-256 hash comparison alongside duration for duplicate detection.
### Low
- **[CWE-346] Single Format Support (#12)** — Now supports .mkv, .mp4, .avi, .mov, .wmv, .flv, .webm, .m4v.
- **Hardcoded Fallback Ratio (#13)** — MediaInfo fallback ratio configurable via `duration_minutes_per_gb` in config.json.
## Web Security (tv.home.ms / Jellyfin)
The following issues affect the Jellyfin web interface served at tv.home.ms.
Fixes are in `nginx.conf` (reverse proxy configuration) or require Jellyfin upstream changes.
### Fixed via nginx.conf
| Issue | Severity | Fix |
|-------|----------|-----|
| #14 Missing security headers | High | CSP, HSTS, X-Frame-Options, X-Content-Type-Options, Referrer-Policy added |
| #21 Server version exposed | Low | `server_tokens off` hides nginx version |
| #22 Response time leaked | Low | `more_clear_headers` directive (requires headers-more module) |
### Requires Jellyfin Upstream Fix
| Issue | Severity | Type | Notes |
|-------|----------|------|-------|
| #15 Console error (scroll behavior) | Medium | BROKEN | Jellyfin JS bundle bug — report to Jellyfin |
| #16 Buttons missing labels | Medium | A11Y | Jellyfin UI — needs aria-label on icon buttons |
| #17 Heading order incorrect | Medium | A11Y | Jellyfin HTML structure — H3 before H1 |
| #18 Inputs lack labels | Medium | A11Y | Jellyfin login form — needs `<label>` elements |
| #19 No skip navigation | Low | A11Y | Jellyfin UI — needs skip-to-content link |
| #20 Remember Me default | Low | SEC | Jellyfin login form — should default to unchecked |
### Issue #1 (Original)
The DP algorithm not finding optimal episode matches. Addressed by the strategies module
(`src/Matcher/strategies.py`) which provides pluggable matching strategies with clear
separation of concerns and testability.
## Deployment
### Docker
```bash
TVDB_API_KEY=your_key docker-compose run --rm episode-matcher \
episode_matcher.py "/path/to/episodes" "Show Name" 1
```
### Nginx
Deploy `nginx.conf` to your nginx server. Requires:
- Let's Encrypt SSL certificates
- nginx `headers-more` module for clearing x-response-time-ms
- Jellyfin running on localhost:8096