WMX · 随记
·Java· 3 分钟阅读

路径 normalize 不等于文件访问授权

用户传入 ../private.txt 时,简单字符串拼接可能访问预期目录之外的文件。规范化路径只是边界检查的一部分。

Java 系列概览:类型与值、状态与资源、边界验证
Java 系列概览:类型与值、状态与资源、边界验证 点击图片查看大图 ↗

问题从哪里出现

用户传入 ../private.txt 时,简单字符串拼接可能访问预期目录之外的文件。规范化路径只是边界检查的一部分。

理解核心机制

resolve 与 normalize 可以消除词法上的点段,再用 startsWith 检查是否仍在根目录下。但符号链接可能改变实际访问目标,词法检查不能代替真实文件系统与权限设计。

动手做一个小实验

Java 17 或更新版本;将示例保存为 Demo.java,执行 javac Demo.java 后运行 java Demo。

Java9 行 · 可横向滚动
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);
    }
}

适用边界与常见误区

真实服务还要考虑符号链接、竞争条件、平台路径语义和最小文件权限。不要把示例当作完整安全下载实现。

继续练习

对相对路径、绝对路径和多层 ../ 构造测试,再在隔离目录中加入符号链接,观察词法与真实路径的差异。

参考资料

阅读相关官方文档或原始资料 ↗

← 返回文章归档