我的下面的代码中是否存在路径遍历漏洞?

时间:2016-05-23 05:23:57

标签: c# security

任何人都可以确认,在我的下面的代码片段中是否可以使用Path Traversal Vulnerabilities?如果是,那么我应该做出哪些改变。

[RedirectingAction]
public ActionResult Download(string fileName)
{
    byte[] fileBytes = System.IO.File.ReadAllBytes(Server.MapPath("~/ClientDocument/") + fileName);
    return File(fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, fileName);
}

2 个答案:

答案 0 :(得分:7)

是的,它很脆弱。

为了证明这一点,我建立了一个名为WebApplication1.sln

的新MVC项目

以下请求下载解决方案文件:

http://localhost:56548/Home/Download?fileName=../../WebApplication1.sln

你可以写一个天真的检查:

private static readonly char[] InvalidFilenameChars = Path.GetInvalidFileNameChars();
public ActionResult Download(string fileName)
{
    if (fileName.IndexOfAny(InvalidFilenameChars) >= 0)
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);

    var rootPath = Server.MapPath("~/ClientDocument/");
    byte[] fileBytes = System.IO.File.ReadAllBytes(Path.Combine(rootPath, fileName));
    return File(fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, fileName);
}

将检查fileName参数是否为有效文件名。此排除了目录分隔符,因此它们无法将路径作为文件名传递。

但是,完全安全的唯一方法是限制应用程序拥有的权限。只授予您对虚拟目录的权限,而不是其他内容。

答案 1 :(得分:0)

从概念上讲,减轻路径遍历漏洞应该采取的措施是将basePath评估为真实路径,同样对basePath和fileName进行同样的处理。如果第二个操作的结果文件仍位于basePath的文件夹中,则说明尚未进行路径遍历。

我使用的是.NET的更高版本,因此Server.MapPath无效。结果,我不确定是否会为您运行;但这至少说明了如何在概念上进行修复:

[RedirectingAction]
public ActionResult Download(string fileName)
{
    var baseFolder = Path.GetFullPath(Server.MapPath("~/ClientDocument/"));
    var targetFile = Path.GetFullPath(Path.Combine(baseFolder, fileName));
    if(targetFile.StartsWith(baseFolder){
      byte[] fileBytes = System.IO.File.ReadAllBytes(Server.MapPath("~/ClientDocument/") + fileName);
      return File(fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, fileName);
    } else {
      //Don't do the download and do something else.
    }  
}