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

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-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

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