如何确保写入的所有文件都在给定路径下(阻止目录访问)

edd*_*uld 5 c# directory parent

我们有一个C#应用程序,它将文件写入可配置的位置.文件集(和相对路径)在运行时确定.

我们希望确保它不能在配置的位置之外写入文件.

例如,配置的位置可能是c:\ Stuff\Export,程序在C:\ Stuff \下写入任何内容都是错误的

真的,我认为我们可以通过两种方式实现这一点:1)断言没有相关路径(要写入的文件)指定'父目录'(通常为"../") - System.Path没有指定"父"目录"路径组件虽然(就像它有路径分离,即System.Path.PathSeparator).我觉得在字符串中检查"../"有点笨拙.

2)断言生成的所有最终绝对路径(通过将输出位置与文件相对路径组合)相对于输出位置下方.我不确定如何解决这个问题.

Example usage:
Output directory: c:\Stuff\Export
Output path 1: "foo\bar\important.xls"
Output path 2: "foo\boo\something.csv"
Output path 3: "../../io.sys"

Expected final files
1. c:\Stuff\Export\foo\bar\important.xls
2. c:\Stuff\Export\foo\boo\something.csv
3. Should throw exception
Run Code Online (Sandbox Code Playgroud)

Asb*_*erg 6

如果DirectoryInfo在两条路径上创建实例,其FullName属性应返回完全限定的规范路径。因此,如果您只是对要比较的双方都这样做,则可以这样做:

if (chosenDirectory.FullName != configuredDirectory.FullName)
{
    throw new InvalidOperationException(
        String.Format("Invalid path {0}.", chosenDirectory));
}
Run Code Online (Sandbox Code Playgroud)

由于FullName只是一个字符串,您可以对路径进行常规字符串比较,例如:

if (!chosenDirectory.FullName.StartsWith(configuredDirectory.FullName,
    StringComparison.InvariantCultureIgnoreCase))
{
    throw new InvalidOperationException(
        String.Format("Invalid path {0}.", chosenDirectory));
}
Run Code Online (Sandbox Code Playgroud)

如果您不想在配置的目录中允许子目录,您还可以使用该Parent属性并将其FullName与所选目录进行比较:

if (!chosenDirectory.Parent.FullName.Equals(configuredDirectory.FullName,
    StringComparison.InvariantCultureIgnoreCase))
{
    throw new InvalidOperationException(
        String.Format("Invalid path {0}.", chosenDirectory));
}
Run Code Online (Sandbox Code Playgroud)


Can*_*ide 5

这是一个快速的解决方案:

string chroot = @"C:\root\child";
string requestedPath = @"..\";
string path = Path.GetFullPath(Path.Combine(chroot, requestedPath));
if (!path.StartsWith(chroot, StringComparison.Ordinal))
    throw new Exception("Oops, caught ya!");
Run Code Online (Sandbox Code Playgroud)

编辑:如果你想知道给定的路径是否是一个有效的目录: Directory.Exists(path)