java - 检查用户请求的文件是否在基目录下

标签 java

我在 Web 服务器上有一个充满文件的目录层次结构,我希望用户能够通过请求访问这些文件中的任何一个。 (它比这复杂一点,这就是为什么我需要访问 Java Web 应用程序中的文件。)

实现这个的自然方法是允许用户指定文件,例如正斜杠,例如/my-web-endpoint?param=folder1/folder2/file.txt。然后我会在 Java 中找到类似 new File(baseDirectory, param) 的文件。到目前为止一切顺利,这很有效。

但是如果用户请求,例如param=../something-private/file.txt 还是什么?我应该如何防止这种情况?

  1. 我可以只禁止带有 .. 的参数,但这就足够了吗?我总是有点担心黑名单。如果有另一种我没有想到的语法怎么办? (例如,我想到了以 / 开头的路径。但也许还有其他。)

  2. 我可以使用 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/

相关文章:

java - 从字符串读取对象时出现 StreamCorruptedException

java控制台菜单

java - 为什么这个正则表达式不起作用?

java - Android Listview 文本对齐

java - 使用代码而不是 beans.xml 注入(inject) @alternative bean

java - JSF2 : Open Session in View with EJBs?

java - RxJava/Rx绑定(bind) : how to handle errors on RxView

java - 如何使用 Couchbase Java SDK 3 使用不同的端口

java - 在 JEditorPane/JTextArea 上显示和附加图标,每个图标都以换行符显示?

java - 设置图标图像 JFrame