2

我有一个rootPath我信任的和一个relativePath我不信任的。我想以这样一种方式组合它们,以便我可以确定结果低于rootPath并且用户不能使用..返回起点。我确实希望相对路径允许以下内容:hello\..\world==world

4

3 回答 3

6

System.IO.Path.GetFullPath

扩展:使用 Path.Combine,然后对结果调用 GetFullPath 并检查该结果是否以 rootPath 开头。

它不会保护您免受硬链接的影响,但它应该可以捕获简单的东西,例如双点。

以上代码:

string Resolve(string fileName)
{
    string root = FileRoot();
    string ret = Path.GetFullPath(Path.Combine(root, fileName));
    if (ret.StartsWith(root.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar)) return ret;
    throw new ArgumentException("path resolved to out of accesable directroy");
}
于 2009-04-29T23:31:06.760 回答
2

您可以致电Path.GetFullPath()并检查它是否以您信任的开头rootPath。如果您倾向于偏执,请检查是否rootPath有根。

public Boolean IsPathSafe(String rootPath, String relativePath)
{
  return rootPath.EndsWith(Path.DirectorySeparatorChar.ToString()) &&
    Path.IsPathRooted(rootPath) &&
    Patch.Combine(rootPath, relativePath).GetFullPath().StartsWith(rootPath);
}

有关第一个测试的解释,请参阅 Alex Martelli 对 technophile 回答的评论。

于 2009-04-29T23:33:15.397 回答
-1

您可以做的一件事是计算反斜杠 ( \) 和双点 ( ..) 的数量,并确保双点的数量小于反斜杠的数量。为了超越rootPath文件夹结构中的 s ,您至少需要与双点一样多的反斜杠 - 因此,如果您只允许relativePaths 至少多了一个反斜杠,那么您应该是安全的。

于 2009-04-29T23:26:10.170 回答