2009-11-18 125 views
3

我有一个asp.net mvc应用程序,其路线允许用户请求存储在Web应用程序目录之外的文件。如何确保文件路径在C#中安全?

我只是告诉你它最终将它们限制在一个他们有权访问的安全目录中,从而简化了这个场景。

例如:

如果用户(其ID为100)请求:

http://mysite.com/Read/Image/Cool.png 

然后我的应用程序将要追加 “Cool.png” 到“C:\ ImageRepository \ Users \用户100“并将这些字节写入响应。工作进程有权访问此路径,但匿名用户不能。我已经有这个工作。

但将一些恶意用户能够请求是这样的:

http://mysite.com/Read/Image/..\101\Cool.png 

并将其解析为

"C:\ImageRepository\Customers\101\Cool.png" 

(其他一些用户的形象?)

或者类似的东西那?有没有办法确保路径是干净的,这样用户被限制到他们自己的目录?

+0

我不认为“http://mysite.com/Read/Image/..\101\Cool。 PNG“将与ASP.NET MVC路线一起工作,如果你有正确的设置。你应该做的是确保你的动作查找用户ID“101”的文件夹,然后在该文件夹中查找图像“Cool.png”,而不是将所有输入附加到特定文件夹路径,这本质上是用户输入注入。 – Omar 2009-11-18 01:10:56

+1

是不是请求URI'http://mysite.com/Read/Image/ .. \ 101 \ Cool.png'在它之前被清理为'http:// mysite.com/Read/101/Cool.png'通过将URI路由到asp.net-mvc中的处理程序的机制解释? – dtb 2009-11-18 01:13:43

+0

未知 - 我想过,但我需要支持http://mysite.com/Read/Image/Favorites/Randy/Cool.png等合法请求。 dtb - 我只是平原不知道。看起来我的例子不起作用(好!),但我更一般地询问这类攻击中的东西,我甚至没有想到。 – Chris 2009-11-18 01:25:51

回答

4

如何

​​

这应该确保你只能得到一个简单的文件名。

+0

我将立即阅读这些方法,并在Linqpad中与他们一起玩。我有一个预感,这是正确的方向。 – Chris 2009-11-18 01:23:27

+0

每当我乱入输入时,都会抛出异常,所以我认为这是要走的路。 – Chris 2009-11-18 02:12:16

0

也许你应该验证路径是从用户的目录路径开始的?

例如"C:\ImageRepository\Customers\100\"

在比较路径时,还应将路径标准化为大写字母。

+2

那么C:\ ImageRepository \ Customers \ 100 \ .. \ 101 \ secretstuff.png怎么样? – 2009-11-18 01:12:29

+0

他应该首先将路径解析为最简单的形式,然后验证路径是否以正确的路径作为前缀。 – 2009-11-18 01:17:19

+0

好的,也许是Tor的答案和.StartsWith()建议的结合? – Chris 2009-11-18 01:22:55

0

最安全的方法是,如果它是一个选项(您正在使用Windows身份验证),则通过在文件夹上使用Active Directory权限使其成为非问题,因此无论用户尝试访问目录无效。

如果没有,请存储文件以便从用户提取路径。也就是说,使用用户提供的任何名称作为具有文件的实际路径的表中的查找。

Cannolocalization保护是棘手的业务,尝试和超出潜在的攻击者是危险的。

+0

不幸的是,这个程序是注定要上网的。 – Chris 2009-11-18 01:22:20

+0

这意味着什么,到底是什么? – JohnFx 2009-11-18 02:30:34

0

使用Request.MapPath超载是检查这一个办法:

try 
{ 
    string mappedPath = Request.MapPath(inputPath.Text,         Request.ApplicationPath, false); 
} 
catch (HttpException) 
{ 
    // do exception handling 
} 

你也可能爆炸的字符串,并用斜杠分隔它,并检查用户名比赛也。

0

为了也能够在路径中包含子目录,你可以使用:

string SafeCombine(string basePath, string path) 
{ 
    string testPath = Path.GetFullPath(Path.Combine(basePath, path)); 
    if (testPath.startsWith(basePath)) 
     return testPath; 
    throw new InvalidOperationException(); 
}