如何在java中验证文件路径?

时间:2014-06-04 21:41:14

标签: java

我正在编写一个Java程序,它读取用户的一些输入,这些输入应该是预定义文件夹的相对路径。例如,他将输入test / subfolder,我将生成/path/to/test/subfolder

我如何检查并阻止用户输入类似../../../的内容,这会弄乱路径并允许他访问不允许的路径?

4 个答案:

答案 0 :(得分:1)

使用Java 7+,使用Path个对象,您可以在创建最终路径之前调用normalize()方法。该方法将通过取消..和前一个路径段并删除任何.段来规范化路径。

有几个案例需要考虑。如果提供的路径是相对的,例如

../first/second

在这种情况下,规范化无法删除..,因为它不知道它之前会是什么。您所要做的就是在根/上解析此路径。例如

Path path = Paths.get("../first");
path = Paths.get("/").resolve(path.normalize()).normalize();

路径可以包含任意数量的..

Path path = Paths.get("../../../../first/../second/../../more");
path = Paths.get("/").resolve(path.normalize()).normalize();

该过程将持续应用。

还有一种情况是提供的路径是绝对的。在这种情况下,您可以立即将其标准化。

Path path = Paths.get("/../../../../first/../second/../../more").normalize();

然后,您可以解析针对前缀路径提供的路径(如果提供的路径是绝对路径,请小心。)

对于其他人提出的符号链接,在使用java.nio.file.LinkOption.NOFOLLOW_LINKS时继续使用java.nio.Files的NIO。

答案 1 :(得分:1)

为了更加一致,我会让他写下他想要的东西,并在他选择路径后检查是否允许(获取所选文件并检查其路径)。他可能会找到一种你没想过的方法,例如别名。

此外(有点指出),如果您希望界面是用户友好的并且在选择路径时已经禁止通知它,请使用正则表达式检查输入路径中是否有../(或者只是进行pathString.indexOf( "../" ) == -1检查)

答案 2 :(得分:1)

之前我正好尝试过这个问题。如果使用类似

之类的内容将预定义文件夹与路径合并
new Path(basePath, givenRelativePath);

然后我不知道除..之外的任何其他内容会导致 baseDir 之外的结果(当然,假设没有符号链接指向外部)。因此,最简单的检查是检测两个连续点的存在,就像丹尼尔建议的那样。

如果你想绝对确定(并且还要处理符号链接或其他有潜在危险的东西),你可以检查这样的结果(只是草图):

if (givenPath.indexOf("..") >= 0)
    throw new IllegalArgumentException();
File result = new File(basePath, givenPath);
if (!result.getCanonicalPath().startsWith(basePath.getCanonicalPath()))
    throw new IllegalArgumentException();
serveFile(result);

这基本上是几个月前我结束的。

当然,在Java 7+中,您可以使用Pathnormalize方法而不是getCanonicalPath,这样会更快,并且不会触及文件系统。另一方面,它不考虑符号链接和其他东西。

答案 3 :(得分:1)

如果你真的想忽略用户输入,如果以'的形式输入相对路径。'或者' ..', 你可以尝试一下.. enter link description here

   File f = new File("/../../../../path/to/folder"); // Wrong user input
   Path path = f.toPath();
   String str1 = path.normalize().toString(); // ouout -> /path/to/folder