- 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
2.9 KiB
2.9 KiB
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-duplicatesnow requires--forceflag. 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_gbin 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
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-moremodule for clearing x-response-time-ms - Jellyfin running on localhost:8096