[英]How to validate a file path in java?
我正在编写一个Java程序,该程序从用户读取一些输入,这些输入应该是预定义文件夹的相对路径。 例如,他将输入test / subfolder,而我将生成/path/to/test/subfolder
。
我如何检查并防止用户输入../../../
东西,会弄乱路径并允许他访问不允许的路径?
在Java 7+中,使用Path
对象,可以在创建最终路径之前调用normalize()
方法。 该方法将通过消除..
和前面的路径段来规范化路径,并消除任何.
段。
有几种情况需要考虑。 例如,如果提供的路径是相对的
../first/second
在这种情况下,规范化无法删除..
因为它不知道之前的内容。 您要做的就是在root /
上解析此路径。 例如
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.Files
时继续将NIO与java.nio.file.LinkOption.NOFOLLOW_LINKS
使用。
为了更加一致,我让他写他想要的内容,并在他选择允许的路径后检查(允许选择的File并检查其路径)。 他可能会找到您没有想到的方法,例如别名。
此外(尽管如此),如果您希望界面易于使用并通知他在选择路径时已经禁止使用该界面,请使用正则表达式检查输入路径中是否存在../(或简单地执行pathString.indexOf( "../" ) == -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+中,您可以使用Path
和normalize
方法来代替getCanonicalPath
,这是更快的并且不会影响文件系统。 另一方面,它不考虑符号链接和其他内容。
如果您确实要忽略用户输入,则以“。”形式键入相对路径。 或“ ..”,您可以尝试这个。. 在此处输入链接说明
File f = new File("/../../../../path/to/folder"); // Wrong user input
Path path = f.toPath();
String str1 = path.normalize().toString(); // ouout -> /path/to/folder
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.