Baike.dev
All toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
J

JellyfinSecurity

> 安全
Open source

A Jellyfin plugin that adds native two-factor authentication (TOTP, email OTP) with trusted device tokens, TV device pairing, LAN bypass, and API key bypass. Se

192 stars0 likes0 views
WebsiteGitHub

About

A Jellyfin plugin that adds native two-factor authentication (TOTP, email OTP) with trusted device tokens, TV device pairing, LAN bypass, and API key bypass. Se

██████╗ ███████╗ █████╗
╚════██╗██╔════╝██╔══██╗
 █████╔╝█████╗  ███████║
██╔═══╝ ██╔══╝  ██╔══██║
███████╗██║     ██║  ██║
╚══════╝╚═╝     ╚═╝  ╚═╝

Jellyfin Security

Comprehensive authentication and hardening for Jellyfin: TOTP, passkeys, email OTP, OIDC/SSO sign-in, brute-force IP banning, impossible-travel detection, per-user IP allowlist, device pairing, trusted-browser cookies, and a full audit log - all from one plugin.

Why this exists: for self-hosters who want a complete auth + hardening layer without standing up a separate identity stack. Full IdPs like Authentik (with OIDC or LDAP outposts) and Authelia work great with Jellyfin and offer features this plugin doesn't - they're often the right call for serious deployments. This plugin is for the case where you'd rather get TOTP, passkeys, OIDC sign-in, brute-force protection, impossible-travel detection, IP allowlist, audit logging, and a proper admin UI as a single Jellyfin plugin — no extra containers, no LDAP outpost, no proxy-auth header juggling, native Jellyfin user model end-to-end.

New: step-by-step guides live in the Wiki — Installation, First-Time Setup, OIDC / SSO, Account Protection, Admin Guide, and Troubleshooting.


️ Security posture - what to check before you trust this with your server

You don't have to take my word for it. Every signal below is automated and visible to anyone, including you:

  • CI badge — every push and PR builds and runs the full xUnit test suite (344 tests covering crypto, parsers, authentication flows, translations, and middleware). Green = tests pass.
  • CodeQL badge — GitHub's static security scanner runs the security-extended + security-and-quality C# query packs on every push, PR, and weekly. Green = no security findings.
  • OpenSSF Scorecard — the Linux Foundation's automated security-posture rating (0–10). Scores branch protection, CodeQL, dependency updates, pinned actions, signed releases, security policy, token permissions, and more. Click the badge to see the per-check breakdown.
  • Test suite — 344 xUnit tests covering the security-critical code paths (cookie HMAC, TOTP replay protection, recovery-code PBKDF2, CIDR parser, X-Forwarded-For trust-walk, refuse-LAN-bypass-when-XFF-missing guard, device-token binding, AES-GCM v2 AAD, HIBP k-anonymity hashing, atomic challenge consumption, OIDC redirect_uri proxy-header resolution, OIDC userinfo claim merge, SMTP port 465 socket-option mapping, step-up code verification, step-up action classification, ChallengeStore step-up tokens). Runs on every PR + push.
  • Open security advisories — historical vulnerabilities filed via SECURITY.md, with patch versions, severity, and CVE references.
  • Dependabot PRs — security and version updates for every NuGet dependency. Frequent merges = vulnerabilities don't sit unpatched.
  • Pull request review history — non-trivial changes go through review even when the maintainer is solo, and the diff is public.
  • Release SHA-256 checksums — every release ships with .md5 and .sha256 files alongside the .zip so you can verify the artifact wasn't tampered with after upload.
  • Threat model in SECURITY.md — explicit list of what the plugin defends against and what it intentionally does not. No hand-waving "secure by design" claims.

If any of these go red, file an issue or DM @zack154 on Discord — fixing visible trust signals is treated as a high-priority bug.


What's new in v2.6.0

Jellyfin 12 support, without dropping 10.11. The plugin now ships two builds from one source, .NET 9 for Jellyfin 10.11.x and .NET 10 for Jellyfin 12.x, both in the one catalog entry, so your server installs the build that matches its version automatically. This release also fixes the admin step-up prompt on the settings and OIDC-provider paths, gives the GeoIP diagnostics a real reason instead of a blank "Fail", and folds in five contributor PRs. In-place upgrade from any 2.5.x, no schema migration or config reset.

v2.6.0

  • ** Jellyfin 12 supported, 10.11 unchanged** (#196, #172) — Jellyfin 12 moved to .NET 10, and a 10.11-built plugin cannot load there, which is why every action returned 401 on 12. The plugin now builds twice from one source: a .NET 9 package for 10.11.x and a .NET 10 package for 12.x, both published under the same catalog entry. Jellyfin routes each host to its build, so there is nothing to choose and existing installs update themselves. Verified end to end on real 10.11 and 12 servers.
  • ** The admin step-up prompt appears everywhere it should** (#198/#199, #194/#195; camarigor) — creating, editing and deleting an OIDC provider, the user-2FA toggle, "require password setup" and the audit log are all step-up-gated, but some called the server with a plain fetch, so a required step-up surfaced as a bare "Save failed" and Delete did nothing. They now route through the step-up-aware fetch. The modal also accepts an emailed code or a passkey, not just a typed TOTP, so admins whose factor is email or a passkey are no longer locked out.
  • ** GeoIP diagnostics that explain themselves** (#200, camarigor; refs #51) — a database that would not load used to read as a blank "Fail". The loader now keeps the reason, retries, and falls back to an in-memory open, and the Diagnostics tab prints what it saw for each database (not found at … (directory not visible to the Jellyfin process), rejected (not absolute), and so on).
  • ** In-app OIDC and the setup page on 12** (#191, #193; camarigor) — in-app "Sign in with …" no longer freezes on a blank screen on 12 (the stored credential now carries a resolvable address in the connection mode 12 expects), and 12's changed web routes get a working way back to the setup page from the avatar menu.
  • 500 passing tests. Sigstore-signed and SLSA build-provenance attested.

Full version history is in the Changelog below and on GitHub Releases.


Table of contents

  • How it works
  • Features
  • Screenshots
  • Installation
  • First-time setup
  • Daily use
  • Admin guide
  • SSO / OIDC sign-in (v2.0)
  • Brute-force IP banning (v2.0)
  • Impossible-travel detection (v2.0)
  • Per-user IP allowlist (v2.0)
  • Step-up authentication (v2.5)
  • Encrypted configuration exports (v2.5)
  • Security score & admin overview (v2.5)
  • Internationalization (v2.5)
  • Indefinite device trust (v2.5)
  • Hardened self-service factor changes (v2.5.6)
  • OIDC step-up factor for users (v2.5.7)
  • Hide built-in 2FA / Passkey login buttons (v2.5.7)
  • OIDC private / VPN / LAN endpoints (v2.5.7)
  • Verified-token persistence (v2.5.7)
  • SMTP setup (email OTP)
  • Recovery — locked out
  • Troubleshooting
  • Architecture
  • API endpoints
  • Security model
  • Limitations
  • Changelog
  • Credits
  • Support the project
  • License

⚡ How it works

  1. Each user opts into 2FA via /TwoFactorAuth/Setup — scans a QR code with an authenticator app and saves recovery codes.
  2. On normal login, Jellyfin's SessionStarted event fires. The plugin checks if the user has 2FA enabled.
  3. If yes, the plugin blocks all subsequent API requests from that session until the user completes 2FA via /TwoFactorAuth/Login.
  4. The challenge page names the Jellyfin account being verified. After successful verification, a signed __2fa_trust cookie is set in the browser. For 30 days, that browser doesn't need 2FA again — but new browsers/devices still do.
  5. The block applies regardless of how the user authenticated (Jellyfin web, mobile API, anything that creates a session).

The standard Jellyfin login page gets a small "Sign in with 2FA" button injected so users with 2FA enrolled can route directly to the plugin's login form. The injected controls are Base URL-aware and are restored after Jellyfin's single-page navigation, including the official Android web shell.


Features

Organized by capability. Per-version history lives in the Changelog and on GitHub Releases.

Jellyfin compatibility

  • Runs on Jellyfin 10.11.x and 12.x from one plugin — a .NET 9 build (targetAbi 10.11.0.0) and a .NET 10 build (targetAbi 12.0.0.0) are published under the same catalog entry, and Jellyfin installs the one matching your server automatically. Existing installs auto-update, and upgrading a server from 10.11 to 12 switches builds on the next update.
  • Multi-architecture native support — linux-x64, linux-arm64, and linux-musl-x64 native libraries are bundled, so recovery-code PDFs and native crypto work on x86, Raspberry Pi, Apple-Silicon Linux, and Alpine.
  • Modern authorization headers — the plugin's pages and endpoints accept Jellyfin's current Authorization: MediaBrowser Token, required once 12 disables legacy authorization.

Authentication

  • TOTP (RFC 6238), compatible with Google Authenticator, Authy, 1Password, Microsoft Authenticator, Bitwarden, and others.
  • Passkeys / WebAuthn for Face ID, Touch ID, Windows Hello, security keys, and password managers; credentials request the portable ES256 algorithm so they work across Linux, ARM, Windows, and iOS.
  • 10 single-use recovery codes generated at enrollment, stored as per-code-salted PBKDF2-HMAC-SHA256 hashes (600k iterations), shown once.
  • Email OTP fallback via configurable SMTP — 8-digit codes expire in 5 minutes and are single-use.
  • Per-device trust via a signed HTTP-only cookie (HMAC-SHA256, 30-day expiry, SameSite=Strict).
  • Account-aware challenges show the username being verified before a TOTP, recovery, email, or passkey response is submitted.

SSO / OIDC sign-in

  • Any OIDC identity provider — Google, Microsoft/Entra, Apple, Authelia, Authentik, Keycloak, PocketID, Cloudflare Access, or any OIDC-compliant IdP, with PKCE and full id_token signatur

Issues· 0 open

View all issuesOpen on GitHub

No open issues yet, or sync has not completed.

> Tags

C#authenticationcsharpdotnetfido2

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 18, 2026
Category安全
PricingOpen source

> Related tools

O
OWASP ZAP
开源 Web 应用安全扫描器
O
owasp-wstg-tracker
Simple web app to track OWASP WSTG security testing progress
H
homebridge-mi-gateway-security
XiaoMi Gateway Security plugin for HomeBridge.