【问题标题】:Validate to prevent a path string to go up to parent folder验证以防止路径字符串上升到父文件夹
【发布时间】:2019-04-08 23:40:27
【问题描述】:

我的业务逻辑正在接受文件夹路径字符串来读取文件夹/文件。但是,由于安全性要求,用户只能访问该文件夹。例如:

他们的文件夹是:C:\foo\user\bar,他们可以通过https://www.example.com/download?path=data/.a.b..txt访问C:\foo\user\bar\data\.a.b..txt

但是,我想阻止用户输入可能使他们进入文件夹并查看其他数据的内容。这是我当前的代码:

        var result = this.ResultFolder; // The user folder (\user\bar as in the example)

        if (!string.IsNullOrEmpty(path))
        {
            path = path.Replace("/", @"\");

            if (path.StartsWith(@"\"))
            {
                path = path.Substring(1);
            }

            if (path.StartsWith('\\') || path.Contains("..\\"))
            {
                throw new InvalidDataException("Forbidden Path.");
            }

            result = Path.Combine(result, path);
        }

基本上,我是做什么的:

  • 将所有 / 替换为 \,这样我只需要担心一个分隔符。

  • 请求允许路径以 \ 开头,它算什么。

  • 1234563错误的情况,因为它是有效的文件/文件夹名称)

它是正确和安全的吗?有什么框架方法可以帮助解决这个问题吗?

【问题讨论】:

  • 您仍然会得到“a\b..\c.txt”的假阴性。您是否需要担心符号链接或硬链接?
  • 考虑使用Path.GetFullPath(string path),然后比较结果的根文件夹以确保它与您期望的根目录相符。它处理绝对路径、相对路径、其中包含“..”的路径,并提供一个完整路径到任何结果。
  • 为什么不直接从父文件夹中删除用户权限?
  • @ChrisDunaway 我已经考虑过这一点,但由于我们开发人员不会部署它们,这是一个额外的预防措施。另外,这个将作为一个IIS网站,所以即使我们只设置了文件夹的读取权限,用户仍然可以尝试获取其他用户的数据(因为同一个进程为所有用户提供文件)。
  • @KlausGütter 现在只是简单的文件访问,所以它们现在不是我们关心的问题。将修复误报,感谢您指出。

标签: c# string security path filesystems


【解决方案1】:

这是一个使用Path.GetFullPath(string path)的解决方案:

创建这个函数:

private static bool VerifyPathUnderRoot(string pathToVerify, string rootPath = ".")
{
    var fullRoot = Path.GetFullPath(rootPath);
    var fullPathToVerify = Path.GetFullPath(pathToVerify);
    return fullPathToVerify.StartsWith(fullRoot);
}

然后你可以用这样的代码来测试它:

 var paths = new[]
 {
     "somepath/somefile.xxx",
     "..\\somepath/somefile.xxx",
     @"C:\this\that\the.other",
 };
 foreach (var path in paths)
 {
     var isOk = VerifyPathUnderRoot(path);
     var okString = isOk ? "OK" : "No";
     Debug.WriteLine($"{okString}: {path}");
 }

这会在调试器的“输出”窗格中产生:

OK: somepath/somefile.xxx
No: ..\somepath/somefile.xx
No: C:\this\that\the.other

我使用GetFullPath 两次来规范化路径(确保所有斜线的结尾都相同,等等)。

【讨论】:

    猜你喜欢
    • 2012-10-08
    • 2020-11-27
    • 2013-04-02
    • 2015-02-15
    • 2011-12-08
    • 1970-01-01
    • 2021-12-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多