我有一个asp.net mvc应用程序,其路由允许用户请求存储在Web应用程序目录之外的文件。
我将通过告诉您最终将它们限制在一个他们有完全访问权限的安全目录中来简化方案。
例如:
如果用户(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 :(得分:4)
怎么样
var fileName = System.IO.Path.GetFileName(userFileName);
var targetPath = System.IO.Path.Combine(userDirectory, fileName);
这应该确保你只获得一个简单的文件名。
答案 1 :(得分:0)
也许您应该验证路径是否以用户的目录路径开头?
e.g。 "C:\ImageRepository\Customers\100\"
在比较它们时,您还应该将路径规范化为大写字母。
答案 2 :(得分:0)
最安全的方法,如果它是一个选项(您正在使用Windows身份验证),则通过对文件夹使用Active Directory权限使其成为非问题,因此如果用户尝试访问目录则无关紧要这是无效的。
如果没有,请存储文件,以便从用户中提取路径。也就是说,使用用户提供的任何名称作为具有该文件的REAL路径的表中的查找。
Cannolocalization保护是一项棘手的业务,尝试并且考虑潜在的攻击者是危险的。
答案 3 :(得分:0)
使用Request.MapPath重载是一种检查方法:
try
{
string mappedPath = Request.MapPath( inputPath.Text, Request.ApplicationPath, false);
}
catch (HttpException)
{
// do exception handling
}
你也可以爆炸字符串并用斜杠分隔它,并检查用户名匹配。
答案 4 :(得分:0)
还可以在您可以使用的路径中包含一个子目录:
string SafeCombine(string basePath, string path)
{
string testPath = Path.GetFullPath(Path.Combine(basePath, path));
if (testPath.startsWith(basePath))
return testPath;
throw new InvalidOperationException();
}