Fix arbitrary image file reads in ImageByNameController

GHSL-2021-050: Issue 4 Arbitrary image file read and directory traversal.
This commit is contained in:
Erwin de Haan 2021-03-20 00:46:59 +01:00
parent f61d18612b
commit 239a7156cc

View file

@ -74,7 +74,7 @@ namespace Jellyfin.Api.Controllers
: type; : type;
var path = BaseItem.SupportedImageExtensions var path = BaseItem.SupportedImageExtensions
.Select(i => Path.Combine(_applicationPaths.GeneralPath, name, filename + i)) .Select(i => Path.GetFullPath(Path.Combine(_applicationPaths.GeneralPath, name, filename + i)))
.FirstOrDefault(System.IO.File.Exists); .FirstOrDefault(System.IO.File.Exists);
if (path == null) if (path == null)
@ -82,6 +82,11 @@ namespace Jellyfin.Api.Controllers
return NotFound(); return NotFound();
} }
if (!path.StartsWith(_applicationPaths.GeneralPath))
{
return BadRequest("Invalid image path.");
}
var contentType = MimeTypes.GetMimeType(path); var contentType = MimeTypes.GetMimeType(path);
return File(System.IO.File.OpenRead(path), contentType); return File(System.IO.File.OpenRead(path), contentType);
} }
@ -163,7 +168,8 @@ namespace Jellyfin.Api.Controllers
/// <returns>A <see cref="FileStreamResult"/> containing the image contents on success, or a <see cref="NotFoundResult"/> if the image could not be found.</returns> /// <returns>A <see cref="FileStreamResult"/> containing the image contents on success, or a <see cref="NotFoundResult"/> if the image could not be found.</returns>
private ActionResult GetImageFile(string basePath, string theme, string? name) private ActionResult GetImageFile(string basePath, string theme, string? name)
{ {
var themeFolder = Path.Combine(basePath, theme); var themeFolder = Path.GetFullPath(Path.Combine(basePath, theme));
if (Directory.Exists(themeFolder)) if (Directory.Exists(themeFolder))
{ {
var path = BaseItem.SupportedImageExtensions.Select(i => Path.Combine(themeFolder, name + i)) var path = BaseItem.SupportedImageExtensions.Select(i => Path.Combine(themeFolder, name + i))
@ -171,12 +177,18 @@ namespace Jellyfin.Api.Controllers
if (!string.IsNullOrEmpty(path) && System.IO.File.Exists(path)) if (!string.IsNullOrEmpty(path) && System.IO.File.Exists(path))
{ {
if (!path.StartsWith(basePath))
{
return BadRequest("Invalid image path.");
}
var contentType = MimeTypes.GetMimeType(path); var contentType = MimeTypes.GetMimeType(path);
return PhysicalFile(path, contentType); return PhysicalFile(path, contentType);
} }
} }
var allFolder = Path.Combine(basePath, "all"); var allFolder = Path.GetFullPath(Path.Combine(basePath, "all"));
if (Directory.Exists(allFolder)) if (Directory.Exists(allFolder))
{ {
var path = BaseItem.SupportedImageExtensions.Select(i => Path.Combine(allFolder, name + i)) var path = BaseItem.SupportedImageExtensions.Select(i => Path.Combine(allFolder, name + i))
@ -184,6 +196,11 @@ namespace Jellyfin.Api.Controllers
if (!string.IsNullOrEmpty(path) && System.IO.File.Exists(path)) if (!string.IsNullOrEmpty(path) && System.IO.File.Exists(path))
{ {
if (!path.StartsWith(basePath))
{
return BadRequest("Invalid image path.");
}
var contentType = MimeTypes.GetMimeType(path); var contentType = MimeTypes.GetMimeType(path);
return PhysicalFile(path, contentType); return PhysicalFile(path, contentType);
} }