路径 normalize 不等于文件访问授权
用户传入 ../private.txt 时,简单字符串拼接可能访问预期目录之外的文件。规范化路径只是边界检查的一部分。
问题从哪里出现
用户传入 ../private.txt 时,简单字符串拼接可能访问预期目录之外的文件。规范化路径只是边界检查的一部分。
理解核心机制
resolve 与 normalize 可以消除词法上的点段,再用 startsWith 检查是否仍在根目录下。但符号链接可能改变实际访问目标,词法检查不能代替真实文件系统与权限设计。
动手做一个小实验
Java 17 或更新版本;将示例保存为 Demo.java,执行 javac Demo.java 后运行 java Demo。
import java.nio.file.Path;
public class Demo {
public static void main(String[] args) {
Path root = Path.of("/srv/downloads").toAbsolutePath().normalize();
Path target = root.resolve("reports/../readme.txt").normalize();
if (!target.startsWith(root)) throw new SecurityException("outside root");
System.out.println(target);
}
}适用边界与常见误区
真实服务还要考虑符号链接、竞争条件、平台路径语义和最小文件权限。不要把示例当作完整安全下载实现。
继续练习
对相对路径、绝对路径和多层 ../ 构造测试,再在隔离目录中加入符号链接,观察词法与真实路径的差异。