9

如果我有一个在调用时删除文件的 Web 方法,并且它接受三个参数(cNum、year 和 fileName)。我是否需要担心这种方法的漏洞。我唯一能想到的就是将..\..\..\删除进一步推进文件夹结构。这应该很容易删除。但是还有什么我应该担心的吗?

[WebMethod(EnableSession = true, 
           Description = "Method for deleting files uploaded by customers")]
[ScriptMethod(ResponseFormat = ResponseFormat.Xml)]
public Boolean deleteCustFiles(string cNum, string year, string fileName)
{
    try
    {
        if (String.IsNullOrEmpty(cNum) 
            || String.IsNullOrEmpty(year) 
            || String.IsNullOrEmpty(fileName))
                throw new Exception();

        string path = Server.MapPath(@"~\docs\custFiles\" 
                                        + year + @"\" 
                                        + cNum + @"\" + fileName);
        File.Delete(path);
    }
    catch
    {
        throw new Exception("Unable to delete file");
    }
    return true;
}
4

3 回答 3

12

我建议使用上的GetFileName方法来清理文件名参数,如下所示:Path

public Boolean deleteCustFiles(string cNum, string year, string fileName)
{
    // Cleanse fileName.
    fileName = Path.GetFileName(fileName);

GetFileName方法从路径中删除所有目录信息,这正是您想要在此处执行的操作。

输入如下:

..\..\..\filename.ext

你会得到:

filename.ext

作为回报,您不必担心有人注入的路径会转义您的目标目录(假设此文件名是用户输入或来自某人可以输入他们想要的任何输入的开放端点)。

然后,这允许您将自定义路径附加到fileName.

当然,这只有在您的所有文件都在预定义目录中时才有效,看起来确实如此。

但是,这不会任何事情来处理删除用户无权访问的文件。如果文件属于该目录中的另一个用户,那么这里没有检查是否是这种情况(但如果所有用户都有权删除这些文件,那么没关系)。

此外,您可能希望使用类上的Combine方法Path来组合您的路径,如下所示:

string path = Server.MapPath(@"~\docs\custFiles\")
path = Path.Combine(path, year);
path = Path.Combine(path, cNum);
path = Path.Combine(path, fileName);

如果您使用的是 .NET 4.0 或更高版本,则可以使用将路径部分作为参数数组的方法的重载Combine

string path = Path.Combine(
    Server.MapPath(@"~\docs\custFiles\"),
    year, cNum, fileName);

最后,正如Shai 指出的那样,如果可能(对于一个完整的解决方案),为了使这更加安全,您应该在文件系统级别启用权限。

如果您正在模拟用户或使用受限用户帐户来处理所有请求,那么您应该授予该用户对 ~\docs\custFiles\目录(和任何子目录)的访问权限。

用户帐户不应访问该目录之上任何内容。

于 2013-01-03T18:36:05.690 回答
1

检查文件名和目录名是否是有效文件名是一个好主意,请对照此 char 数组检查它们:

Path.GetInvalidFileNameChars

编辑:

您可能还应该像这样验证年份和数字:

bool valid = int.TryParse(num, out temp);

于 2013-01-03T18:40:08.490 回答
1

您可能还需要考虑在文件系统上使用内置安全性来防止用户删除不需要的目录中的文件。如果 Web 应用程序在特定用户下运行,该用户仅有权删除一个目录中的文件,则无论用户尝试什么,应用程序都无权执行删除。

此外,这将使维护(即:添加新目录)非常容易,而无需重新部署应用程序。

然后,您可以捕获访问无效访问尝试的尝试,并根据需要对其进行处理。

[WebMethod(EnableSession = true, 
    Description = "Method for deleting files uploaded by customers")]
[ScriptMethod(ResponseFormat = ResponseFormat.Xml)]
public Boolean deleteCustFiles(string cNum, string year, string fileName)
{
    try
    {
        if (String.IsNullOrEmpty(cNum) || String.IsNullOrEmpty(year) ||
            String.IsNullOrEmpty(fileName))
            throw new Exception();
        string path = 
            Server.MapPath(@"~\docs\custFiles\" + year + @"\" + cNum + 
                @"\" + fileName);
        File.Delete(path);
    }
    catch (System.Security.SecurityException e)
    {
        throw new Exception("Unauthorized attempt to delete file");
    }
    catch
    {
        throw new Exception("Unable to delete file");
    }

    return true;
}
于 2013-01-03T18:40:46.357 回答