Przeglądaj źródła

Fix arbitrary image file reads in ImageByNameController

GHSL-2021-050: Issue 4 Arbitrary image file read and directory traversal.
Erwin de Haan 4 lat temu
rodzic
commit
239a7156cc
1 zmienionych plików z 20 dodań i 3 usunięć
  1. 20 3
      Jellyfin.Api/Controllers/ImageByNameController.cs

+ 20 - 3
Jellyfin.Api/Controllers/ImageByNameController.cs

@@ -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);
                 }
                 }