我在 Web 服务器上有一个充满文件的目录层次结构,我希望用户能够通过请求访问这些文件中的任何一个。 (它比这复杂一点,这就是为什么我需要访问 Java Web 应用程序中的文件。)
实现这个的自然方法是允许用户指定文件,例如正斜杠,例如/my-web-endpoint?param=folder1/folder2/file.txt
。然后我会在 Java 中找到类似 new File(baseDirectory, param)
的文件。到目前为止一切顺利,这很有效。
但是如果用户请求,例如param=../something-private/file.txt
还是什么?我应该如何防止这种情况?
我可以只禁止带有
..
的参数,但这就足够了吗?我总是有点担心黑名单。如果有另一种我没有想到的语法怎么办? (例如,我想到了以/
开头的路径。但也许还有其他。)我可以使用
getCanonicalFile()
然后检查路径是否以基本目录开头,例如File baseDirectory = .... String param = ... File desiredFile = new File(baseDirectory, param); if ( ! desiredFile.getCanonincalPath().startsWith( baseDirectory.getCanonincalPath()+File.separator)) throw ...
这就足够了吗?会出什么问题吗?
什么是正确的做法?
最佳答案
startsWith(baseDirectory.getCanonincalPath()+"/")
应该没问题。
更好地使用新的文件和路径类。
Path path = file.toPath();
path = path.toRealPath();
// Absolute, ".." removed, sym links resolved as no param NOFOLLOW_LINKS.
path = path.normalize(); // Removes ".."
path.startsWith(baseDir); // Base path
关于java - 检查用户请求的文件是否在基目录下,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51327296/