
Critical path traversal to RCE vulnerability in Jellyfin Media Server (CVSS 9.9). Includes proof-of-concept exploit, technical analysis, and detection tools.
A critical path traversal vulnerability in Jellyfin Media Server allows authenticated users with "Upload Subtitles" permission to upload files to arbitrary locations on disk. By exploiting the unvalidated Format field in the subtitle upload endpoint, attackers can write files to sensitive locations, extract sensitive data, escalate privileges, and ultimately execute arbitrary code as root via LD_PRELOAD injection.
| Property | Value |
|---|---|
| CVE ID | CVE-2026-35031 |
| CVSS Score | 9.9 (Critical) |
| CWE | CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal') |
| Affected Product | Jellyfin Media Server |
| Affected Versions | < 10.11.7 |
| Fixed Version | 10.11.7 and later |
| Vulnerability Type | Path Traversal + Arbitrary File Write + RCE |
| Authentication Required | Yes (non-admin user) |
| Privileges Required | "Upload Subtitles" permission |
| Default Port | 8096/TCP |
| GitHub Advisory | GHSA-9p5f-5x8v-x65m |
| Patch Status | Available and released |
| Exploit Public | Yes |
Jellyfin is a free and open-source media server designed to help you manage and stream your personal media collection. It provides functionality similar to commercial media servers but with full source code transparency and community control.
Jellyfin Media Server (Port 8096)
/ | \
/ | \
Web UI REST API Media Streams
(Browser) (Authenticated) (Subtitle Upload)
|
/System/Info/Public (unauthenticated)
/Videos/{itemId}/Subtitles (vulnerable)
/Library/Collections (admin)
Client Devices > Network > Jellyfin Server > Database + Storage
|
/var/lib/jellyfin/
/etc/ld.so.preload (writable via vulnerability)
The vulnerability exists in the subtitle upload endpoint (/Videos/{itemId}/Subtitles) which accepts file uploads and stores them on disk. The critical flaw lies in the insufficient validation of the Format field parameter.
The endpoint processes subtitle uploads without properly validating or sanitizing the Format field:
POST /Videos/{itemId}/Subtitles HTTP/1.1
Content-Type: multipart/form-data
[Binary subtitle data]
Format: /../../../etc/ld.so.preload
Language: en
The Format parameter is intended to specify subtitle format (srt, vtt, ass, etc.) but instead gets treated as part of the file path:
Base Path: /var/lib/jellyfin/subtitles/
User Input: /../../../etc/ld.so.preload
Result: /var/lib/jellyfin/subtitles/../../../etc/ld.so.preload
Resolved: /etc/ld.so.preload (via path traversal)
The vulnerability chains together multiple weaknesses to achieve remote code execution as root:
Step 1: Subtitle Upload with Path Traversal
POST /Videos/{itemId}/Subtitles
Format: /../../../etc/ld.so.preload
|
v
Step 2: Arbitrary File Write
Write attacker-controlled data to /etc/ld.so.preload
|
v
Step 3: File Read via .strm Files
Create .strm files pointing to sensitive paths
Extract database contents and credentials
|
v
Step 4: Database Extraction
Access /jellyfin/jellyfin.db via .strm
Extract admin user hashes
|
v
Step 5: Admin Privilege Escalation
Reset admin password or create new admin account
|
v
Step 6: RCE via LD_PRELOAD Injection
LD_PRELOAD=/path/to/malicious.so java
Arbitrary code execution as root
Input Validation Failure:
Format Field Validation:
Expected: srt | vtt | ass | ssa | sub | subrip
Actual: /../../../etc/ld.so.preload
Result: NO VALIDATION > PATH TRAVERSAL ALLOWED
File Write Operation:
String Concatenation: "/subtitles/" + user_format + ".srt"
|
NO CANONICALIZATION: Path component not resolved before write
NO WHITELIST: Format values not restricted
NO BOUNDS CHECK: ".." sequences not filtered
|
v
Final Path: /etc/ld.so.preload (EXPLOITED)
The LD_PRELOAD technique is a powerful privilege escalation and code execution method on Linux systems:
LD_PRELOAD Injection Flow:
1. Attacker writes malicious .so (shared object) to /etc/ld.so.preload
/etc/ld.so.preload contents:
/path/to/attacker.so
2. Java process starts (Jellyfin runs on Java):
kernel > execve("java", ...) > glibc initialization
|
v
Check /etc/ld.so.preload
|
v
Load attacker.so FIRST
|
v
Execute attacker code
(BEFORE Java main())
3. Code Execution Context:
Process Owner: root (Jellyfin typically runs as root)
Permissions: Full system access
Timing: Before application initialization
Detection: Minimal (malicious code runs early)