diff options
| author | Cody Robibero <cody@robibe.ro> | 2026-08-30 14:40:16 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-08-30 14:40:16 -0400 |
| commit | 9fe5a53e47526ae84b246ec3ae8f861056b52eca (patch) | |
| tree | dd1319a5d805659eafa1a00a0aadcc394d950253 /MediaBrowser.Controller/IO | |
| parent | 2996f726c19d65eb3fed0fbc42710278d1be3ec3 (diff) | |
| parent | 0c560b22ce73323329645b836c9910abc257ce4e (diff) | |
Merge commit from fork
Secure library paths
Diffstat (limited to 'MediaBrowser.Controller/IO')
| -rw-r--r-- | MediaBrowser.Controller/IO/FileSystemHelper.cs | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/MediaBrowser.Controller/IO/FileSystemHelper.cs b/MediaBrowser.Controller/IO/FileSystemHelper.cs index 44b7fadf5e..f636258191 100644 --- a/MediaBrowser.Controller/IO/FileSystemHelper.cs +++ b/MediaBrowser.Controller/IO/FileSystemHelper.cs @@ -166,4 +166,35 @@ public static class FileSystemHelper return ResolveLinkTarget(fileInfo.FullName, returnFinalTarget); } + + /// <summary> + /// Combines a caller supplied name with a parent directory, making sure the name cannot escape that directory. + /// </summary> + /// <param name="parentPath">The directory the name has to resolve inside of.</param> + /// <param name="name">The name of the child.</param> + /// <returns> + /// The full path of the child, or <c>null</c> if <paramref name="name"/> is not the name of a direct child + /// of <paramref name="parentPath"/>. + /// </returns> + public static string? GetChildPath(string parentPath, string name) + { + if (string.IsNullOrWhiteSpace(name) || name.Contains('\0', StringComparison.Ordinal)) + { + return null; + } + + // Rejects directory separators, and on Windows also volume separators, as those make the name more than a single segment. + if (!string.Equals(Path.GetFileName(name), name, StringComparison.Ordinal)) + { + return null; + } + + var fullPath = Path.GetFullPath(Path.Combine(parentPath, name)); + var fullParentPath = Path.TrimEndingDirectorySeparator(Path.GetFullPath(parentPath)); + + // Catches the remaining relative names, "." and "..", which are valid single segments. + return string.Equals(Path.GetDirectoryName(fullPath), fullParentPath, StringComparison.Ordinal) + ? fullPath + : null; + } } |
