OrchardCMS/OrchardCore · error · FileStoreException
The path ' ' resolves to a physical path outside the file…
Error message
The path '{path}' resolves to a physical path outside the file system store root. What it means
FileSystemStore.GetPhysicalPath validates that combining the store root with the supplied virtual path still resolves inside the store root (a path-traversal guard). If the resolved full path escapes the root, a FileStoreException is thrown. Nearly every read/write/copy/move operation funnels through this method.
Solutions
- Sanitize the input: strip or reject '..' segments, leading slashes, drive letters, and invalid characters before calling the API.
- Use Path.GetFileName / combine the path from trusted components instead of raw user input.
- Ensure the store root (the path given to FileSystemStore) is absolute and canonical so the prefix check compares like with like.
- If this is a security probe, treat it as suspicious input and reject the request rather than retrying.
Example fix
// before
var path = userSuppliedName; // could be "../../evil.txt"
await fileStore.CreateFileFromStreamAsync(path, stream);
// after
var safeName = Path.GetFileName(userSuppliedName.Replace('\\', '/'));
if (string.IsNullOrWhiteSpace(safeName) || safeName.Contains(".."))
{
throw new ArgumentException("Invalid file name.", nameof(userSuppliedName));
}
await fileStore.CreateFileFromStreamAsync(safeName, stream); Defensive patterns
Strategy: validation
Validate before calling
var segments = path.Replace('\\', '/').Split('/', StringSplitOptions.RemoveEmptyEntries);
bool isSafe = segments.Length > 0
&& segments.All(s => s != ".." && s != "." && !Path.IsPathRooted(s) && s.IndexOfAny(Path.GetInvalidFileNameChars()) < 0); Type guard
static bool IsSafeStorePath(string path) =>
!string.IsNullOrWhiteSpace(path)
&& !Path.IsPathRooted(path)
&& !path.Split('/', '\\').Any(s => s == ".."); Try / catch
try
{
await fileStore.GetFileInfoAsync(path);
}
catch (FileStoreException ex) when (ex.Message.Contains("outside the file system store root"))
{
logger.LogWarning("Rejected path-traversal attempt: {Path}", path);
return Results.BadRequest("Invalid path.");
} Prevention
- Never pass raw user input as a store path; reduce it to Path.GetFileName first.
- Reject or decode-and-check URL segments before building store paths.
- Configure FileSystemStore with an absolute canonical root path.
- Treat 'outside the store root' errors as potential security events and log them.
When it happens
Trigger: Passing a path containing '..' segments (e.g. '../../secret.txt'), an absolute path, or a rooted drive path like 'C:/tmp/x.txt' to any IFileStore method (GetFileInfoAsync, CreateFileFromStreamAsync, CopyFileAsync, MoveFileAsync, etc.).
Common situations: User-supplied filenames passed straight into file-store APIs without sanitization; URL-decoded '%2e%2e%2f' segments; comparing paths built with different separators; case where the store root itself is a relative path so the prefix check misfires.
Understand the failure class
Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.
Related errors
- The SMTP pickup directory location
- returned a null .
- Error retrieving file info for
- Error creating directory
- Error deleting file
AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13).
Data as JSON: /api/errors/174f1e0cd77a93c5.
Report an issue: GitHub.
Appendix: source
Thrown at src/OrchardCore/OrchardCore.FileStorage.FileSystem/FileSystemStore.cs:433
/// <summary>
/// Translates a relative path in the virtual file store to a physical path in the underlying file system.
/// </summary>
/// <param name="path">The relative path within the file store.</param>
/// <returns></returns>
/// <remarks>The resulting physical path is verified to be inside designated root file system path.</remarks>
private string GetPhysicalPath(string path)
{
try
{
path = this.NormalizePath(path);
var physicalPath = string.IsNullOrEmpty(path) ? _fileSystemPath : Path.Combine(_fileSystemPath, path);
// Verify that the resulting path is inside the root file system path.
var pathIsAllowed = Path.GetFullPath(physicalPath).StartsWith(_fileSystemPath, StringComparison.OrdinalIgnoreCase);
if (!pathIsAllowed)
{
throw new FileStoreException($"The path '{path}' resolves to a physical path outside the file system store root.");
}
return physicalPath;
}
catch (FileStoreException)
{
throw;
}
catch (Exception ex)
{
throw new FileStoreException($"Cannot resolve physical path with the path '{path}'.", ex);
}
}
}
View on GitHub (pinned to 4306c0717f)