v0.3.29
Security
Phases 2 + 3 of the security hardening pass. New docs/security.md documents the threat model and a hardening checklist.
Fixed
- Passwords now hashed with bcrypt (cost 12). Legacy SHA-256 hashes from older installs are transparently upgraded on first successful login.
- Secret comparisons (API key, password hash, session signature) all use
hmac.compare_digest— no more timing oracles. - Session signing fails closed when
session_secretis empty; the old code fell back to a literal"default-secret"constant that made every un-configured install's sessions forgeable. Startup now auto-generatessession_secreton any DB that's missing it, not only on fresh installs. - Login rate-limited to 8 attempts/minute/IP.
post_conversion_scriptsetting refuses to save a non-empty value whenauth_enabled=false. Changing this setting runs arbitrary commands after every encode — now it requires the password-auth gate, not just an API key.- SSRF protection on user-configured outbound URLs (Plex, Sonarr, Radarr, Discord webhook, generic webhook). Link-local (
169.254.0.0/16— covers AWS / Azure / GCP / Alibaba metadata endpoints), IPv6 link-local, and IPv6 site-local ranges are rejected at save time. - Session cookies set
Secureflag when the request arrived over HTTPS (detected via scheme +X-Forwarded-Proto). - Settings export now strips every secret row (
api_key,session_secret,auth_password_hash, integration API keys, SMTP password, path-tokened URLs). Previously a leaked export file handed over every stored credential. /api/settings/browserefuses to list the filesystem root or any system directory (/etc,/root,/proc,/sys,/boot,/dev). The old picker could be used as an unauthenticated filesystem enumerator before v0.3.28's auth middleware fixes; now it's locked regardless of auth state.- LIKE search patterns escape
%and_metacharacters withESCAPE '\\'. Stops user-supplied search strings from enumerating scan_results via wildcard patterns. - Symlink guards on rename / backup write destinations. Refuses to follow a pre-existing symlink at the target path — closes the window where an attacker with write access to the backup folder could redirect the rename.
- TMDB API key passed as
params={...}rather than interpolated into the URL string — httpx exception messages no longer carry the raw key. - python-multipart bumped to 0.0.18 (CVE-2024-53981 DoS).
.env/.env.*added to.dockerignoreso local secrets never leak into image layers.
Added
- Baseline security headers on every response:
X-Content-Type-Options: nosniff,X-Frame-Options: DENY,Content-Security-Policy: frame-ancestors 'none',Referrer-Policy: strict-origin-when-cross-origin. backend/ssrf_guard.py— reusable URL validator; can also block RFC 1918 private ranges whenblock_private=Truefor cloud deployments.docs/security.md— threat model, list of in-app defences, hardening checklist for production deployments.
Remaining (tracked for the next release)
- Per-node worker tokens. Anyone who holds the shared
api_keycan currently impersonate any registered worker by sending itsnode_idin a heartbeat. The fix (issue per-node tokens at registration, bind them tonode_idon every subsequent call) is a bigger change that touches worker-mode and is deferred to keep this release scoped.
Docker images
Pinned to this release:
docker pull ghcr.io/i-ial9000/shrinkerr:0.3.29 # portable (amd64 + arm64, CPU)
docker pull ghcr.io/i-ial9000/shrinkerr:0.3.29-nvenc # x86_64 + NVIDIA GPU (NVENC)
docker pull ghcr.io/i-ial9000/shrinkerr:0.3.29-edge # as above but ffmpeg master
docker pull ghcr.io/i-ial9000/shrinkerr:0.3.29-edge-nvencFloating tags (:latest, :edge, :nvenc, :edge-nvenc) track the most recent release of each lineage.