mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-04-06 18:32:08 +01:00
Fix GHSA-j2hf-x4q5-47j3 with improved sanitization
Co-Authored-By: Shadowghost <Ghost_of_Stone@web.de>
This commit is contained in:
committed by
Bond_009
parent
c008f28d31
commit
8cecf53057
@@ -1171,11 +1171,18 @@ namespace MediaBrowser.Controller.Entities
|
||||
info.Video3DFormat = video.Video3DFormat;
|
||||
info.Timestamp = video.Timestamp;
|
||||
|
||||
if (video.IsShortcut)
|
||||
if (video.IsShortcut && !string.IsNullOrEmpty(video.ShortcutPath))
|
||||
{
|
||||
info.IsRemote = true;
|
||||
info.Path = video.ShortcutPath;
|
||||
info.Protocol = MediaSourceManager.GetPathProtocol(info.Path);
|
||||
var shortcutProtocol = MediaSourceManager.GetPathProtocol(video.ShortcutPath);
|
||||
|
||||
// Only allow remote shortcut paths — local file paths in .strm files
|
||||
// could be used to read arbitrary files from the server.
|
||||
if (shortcutProtocol != MediaProtocol.File)
|
||||
{
|
||||
info.IsRemote = true;
|
||||
info.Path = video.ShortcutPath;
|
||||
info.Protocol = shortcutProtocol;
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(info.Container))
|
||||
|
||||
@@ -262,9 +262,28 @@ namespace MediaBrowser.Providers.MediaInfo
|
||||
|
||||
private void FetchShortcutInfo(BaseItem item)
|
||||
{
|
||||
item.ShortcutPath = File.ReadAllLines(item.Path)
|
||||
var shortcutPath = File.ReadAllLines(item.Path)
|
||||
.Select(NormalizeStrmLine)
|
||||
.FirstOrDefault(i => !string.IsNullOrWhiteSpace(i) && !i.StartsWith('#'));
|
||||
|
||||
if (string.IsNullOrWhiteSpace(shortcutPath))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Only allow remote URLs in .strm files to prevent local file access
|
||||
if (Uri.TryCreate(shortcutPath, UriKind.Absolute, out var uri)
|
||||
&& (string.Equals(uri.Scheme, "http", StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(uri.Scheme, "https", StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(uri.Scheme, "rtsp", StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(uri.Scheme, "rtp", StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
item.ShortcutPath = shortcutPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogWarning("Ignoring invalid or non-remote .strm path in {File}: {Path}", item.Path, shortcutPath);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -7,6 +7,7 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Emby.Naming.Common;
|
||||
using Jellyfin.Extensions;
|
||||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
@@ -32,6 +33,7 @@ namespace MediaBrowser.Providers.Subtitles
|
||||
private readonly ILibraryMonitor _monitor;
|
||||
private readonly IMediaSourceManager _mediaSourceManager;
|
||||
private readonly ILocalizationManager _localization;
|
||||
private readonly HashSet<string> _allowedSubtitleFormats;
|
||||
|
||||
private readonly ISubtitleProvider[] _subtitleProviders;
|
||||
|
||||
@@ -41,7 +43,8 @@ namespace MediaBrowser.Providers.Subtitles
|
||||
ILibraryMonitor monitor,
|
||||
IMediaSourceManager mediaSourceManager,
|
||||
ILocalizationManager localizationManager,
|
||||
IEnumerable<ISubtitleProvider> subtitleProviders)
|
||||
IEnumerable<ISubtitleProvider> subtitleProviders,
|
||||
NamingOptions namingOptions)
|
||||
{
|
||||
_logger = logger;
|
||||
_fileSystem = fileSystem;
|
||||
@@ -51,6 +54,9 @@ namespace MediaBrowser.Providers.Subtitles
|
||||
_subtitleProviders = subtitleProviders
|
||||
.OrderBy(i => i is IHasOrder hasOrder ? hasOrder.Order : 0)
|
||||
.ToArray();
|
||||
_allowedSubtitleFormats = new HashSet<string>(
|
||||
namingOptions.SubtitleFileExtensions.Select(e => e.TrimStart('.')),
|
||||
StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -171,6 +177,12 @@ namespace MediaBrowser.Providers.Subtitles
|
||||
/// <inheritdoc />
|
||||
public Task UploadSubtitle(Video video, SubtitleResponse response)
|
||||
{
|
||||
var format = response.Format;
|
||||
if (string.IsNullOrEmpty(format) || !_allowedSubtitleFormats.Contains(format))
|
||||
{
|
||||
throw new ArgumentException($"Unsupported subtitle format: '{format}'");
|
||||
}
|
||||
|
||||
var libraryOptions = BaseItem.LibraryManager.GetLibraryOptions(video);
|
||||
return TrySaveSubtitle(video, libraryOptions, response);
|
||||
}
|
||||
@@ -230,7 +242,7 @@ namespace MediaBrowser.Providers.Subtitles
|
||||
|
||||
foreach (var savePath in savePaths)
|
||||
{
|
||||
var path = savePath + "." + extension;
|
||||
var path = Path.GetFullPath(savePath + "." + extension);
|
||||
try
|
||||
{
|
||||
if (path.StartsWith(video.ContainingFolderPath, StringComparison.Ordinal)
|
||||
@@ -241,7 +253,7 @@ namespace MediaBrowser.Providers.Subtitles
|
||||
|
||||
while (fileExists)
|
||||
{
|
||||
path = string.Format(CultureInfo.InvariantCulture, "{0}.{1}.{2}", savePath, counter, extension);
|
||||
path = Path.GetFullPath(string.Format(CultureInfo.InvariantCulture, "{0}.{1}.{2}", savePath, counter, extension));
|
||||
fileExists = File.Exists(path);
|
||||
counter++;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user