在子目录中安全地强制执行用户输入文件路径
我知道可靠的安全建议,即避免接受用户输入,然后使用该输入来选择读/写文件的路径。但是,假设您有一个想要保留的基本目录(例如 ftp 文件夹的根目录),那么如何最好地确保给定的用户输入将我们保留在该文件夹中?
例如,
Path.Combine(_myRootFolder, _myUserInput)
仍然可以将我们带到 _myRootFolder 之外。 这也可能是狡猾的
newPath = Path.Combine(_myRootFolder, _myUserInput)
if (newPath.StartsWith(_myRootFolder))
...
考虑到用户提供的类似“/back/to/myrootfolder/../../and/out/again”的内容, 。对此有何策略?我是否缺少一个可以使用的极其明显的 .NET 方法?
I know the solid security recommendation of avoiding accepting user input that you then use to choose a path to read/write a file. However, assuming you have a base directory you want to keep within (such as the root of an ftp folder), how do you best ensure that a given user input keeps us within that folder?
For instance,
Path.Combine(_myRootFolder, _myUserInput)
could still take us outside of _myRootFolder. And this could also be dodgy
newPath = Path.Combine(_myRootFolder, _myUserInput)
if (newPath.StartsWith(_myRootFolder))
...
given something like "/back/to/myrootfolder/../../and/out/again" from the user. What are the strategies for this? Am I missing a blindingly obvious .NET method I can use?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
在 ASP.NET 应用程序中,您可以使用 Server.MapPath(filename) ,如果生成的路径超出应用程序根目录,它将引发异常。
如果您想要的只是一个安全的文件名,并且您只想要其中的所有文件,那么它会变得更简单;
如果您像您指出的那样位于 ASP.NET 之外,那么您可以使用
Path.GetFullPath
。或者您调用 Path.GetFullPath,然后检查它的开头是否与您要锁定的目录匹配。
Within ASP.NET applications you can use
Server.MapPath(filename)
which will throw an exception if the path generated goes outside of your application root.If all you want is a safe file name and you just want all files in there it becomes simpler;
If you're outside of ASP.NET like you indicate then you could use
Path.GetFullPath
.Or you call Path.GetFullPath and then check the start of it matches the directory you want locked to.
我知道,这个线程已经很老了,但是为了防止后续读者编写具有潜在安全错误的代码,我想我应该指出,使用
Path.Combine(arg1, arg2)
不是当arg2
直接基于用户输入时保存。例如,当
arg2
为“C:\Windows\System32\cmd.exe”时,arg1
参数将被完全忽略,并且您向 API 或服务器应用程序的用户授予完全权限访问整个文件系统。所以请谨慎使用此方法!
我想出了这个应该(据我所知)安全的解决方案:
编辑: 现在有一个新的
Path.Join()
方法。请使用该代码而不是上面的代码。I know, that this thread is quiet old, but to prevent following readers from writing code with potential security errors, I think I should point out, that using
Path.Combine(arg1, arg2)
isn't save whenarg2
is directly based on user input.When
arg2
is for example "C:\Windows\System32\cmd.exe" thearg1
parameter will be completely ignored and you grant the users of your API or server application full access to the whole file system.So please be very careful with using this method!
I came up with this solution that should (afaik) be secure:
Edit: There is a new
Path.Join()
method now. Please use that one instead of the code above.我相信 Path.FullPath 会满足您的需要(但我没有测试这一点):
I believe Path.FullPath will do what you need (I didn't test this though):
好吧,在您的 FTP 服务器示例中,您应该适当地设置用户主目录和权限,以便他们无法导航出该文件夹。你有什么理由不能这样做吗?
Well, in your example of an FTP server, you should set the users home-directory, and permissions appropriately, such that they can't navigate out of the folder. Any reason you can't do that?
您可以解析输入字符串并使用正则表达式剪切 ../ 。
You can parse input string and cut ../ with regex.