Thanks for taking the time to report security issues responsibly.
Please do NOT open a public GitHub issue for security bugs. A public report gives attackers a head start before users can upgrade.
Use one of the following private channels:
- GitHub Private Vulnerability Reporting (preferred) - open https://github.com/ZL154/JellyfinSecurity/security/advisories/new and submit the advisory. Only repository maintainers can see it.
- Discord - DM
@zack154on Discord with a description of the issue.
- Affected plugin version(s) (e.g.
2.3.0) - Affected Jellyfin server version(s) (e.g.
10.11.8) - Steps to reproduce (PoC welcome)
- Impact assessment (auth bypass, RCE, info disclosure, DoS, etc.)
- Suggested fix or mitigation if you have one
- Initial acknowledgement
- CVE assignment for confirmed vulnerabilities (via GitHub Security Advisories)
- Credit in the release notes and advisory unless you ask to remain anonymous
The following are generally not treated as vulnerabilities in this plugin:
- Issues that require an attacker to already be a Jellyfin administrator
- Issues caused by misconfigured deployments (e.g. running Jellyfin
without HTTPS in front of it, missing
TrustForwardedFor+TrustedProxyCidrsbehind a reverse proxy) - Self-XSS or theoretical timing attacks against TOTP without a working PoC
- Reports against unsupported plugin versions (see table below)
- Findings from automated scanners with no exploitable PoC
In scope:
- Password compromise - blocked by 2FA / passkey / OIDC requirement
- Brute-force login - blocked by per-IP rate limit + IP ban
- Stolen session cookie replay - bound to device, revocable
- Trusted-browser cookie forgery - HMAC-SHA256 signed, length-checked
- Replay of recovery codes - single-use, marked used on validation
- TOTP code replay across restarts - persisted last-used time-step floor
- TOTP secret swap between users on disk - AES-GCM with userId as AAD
- OIDC token forgery - signature + issuer + audience + nonce validated
- Stolen X-Forwarded-For header - only honoured when peer is a trusted proxy CIDR; real client picked right-to-left
- Impossible travel - notification when consecutive sign-ins exceed cruise-jet speed
- IP allowlist bypass - high-value accounts can be pinned to CIDRs
Out of scope (intentional limitations):
- Endpoint compromise (keylogger reads the user's TOTP code before they type it)
- Server compromise (root on the Jellyfin host)
- Browser-extension compromise stealing the trust cookie
- Side-channel attacks on the underlying OS / crypto primitives
- Native client compromise (a malicious Swiftfin fork that exfiltrates app passwords)
- TOTP secret encryption: AES-GCM with a persistent 32-byte key, userId as AAD (v2 format)
- Trust cookie signing: HMAC-SHA256 with persistent key, length-checked
before
CryptographicOperations.FixedTimeEquals - Recovery code hashing: PBKDF2-HMAC-SHA256, 600k iterations, per-code salt (legacy 100k records remain valid and are consumed on use)
- App password hashing: PBKDF2-SHA256
- API key hashing: SHA-256 (raw key is 256 bits of entropy, no PBKDF2 needed)
- Audit log integrity: per-entry hash chain (
prev_hash || entry) - Constant-time comparison for every secret-bearing path
If you find a deviation from any of the above, that itself is in scope.