system.getproperty() 本身安全,但误用易致路径遍历、越权访问等风险;应区分系统属性与环境变量,校验空值,锚定可信根路径,避免依赖 user.dir 构建敏感路径,并妥善处理 securitymanager 权限中断。

System.getProperty() 本身不直接带来安全风险,但**误用或依赖它构建路径时,容易引发路径遍历、文件越权访问、配置失效等实际风险**。关键不在方法本身,而在使用场景和逻辑设计。
误把环境变量当系统属性读取
开发者常写 System.getProperty("PATH") 或 System.getProperty("HOME"),期望获取操作系统级路径,结果返回 null。这看似只是功能失效,但在路径拼接逻辑中若未做空值校验,可能触发 NPE;更严重的是,后续代码可能 fallback 到硬编码路径或默认值,导致配置错乱、日志写入错误目录,甚至被攻击者利用构造异常路径绕过校验。
- 正确做法:读取环境变量必须用
System.getenv("PATH") - 系统属性只包含 JVM 内部键(如
java.home、user.home),不含PATH、PWD等 OS 环境变量 - 建议在启动时就校验关键属性是否存在,避免运行时静默失败
依赖 user.dir 构建敏感路径
System.getProperty("user.dir") 返回的是 JVM 启动时的工作目录,不是项目根目录或代码位置。在服务化部署(如 systemd、Docker、cron)中,该值往往为 /、/root 或容器工作目录,极易导致:
- 相对路径指向系统根目录或任意挂载卷,造成文件误删/覆盖
- 配置文件从预期的
./conf/app.yaml变成/conf/app.yaml,暴露敏感内容 - 日志写入
/logs/而非应用专属目录,引发权限冲突或磁盘占满
尤其在 Web 容器(Tomcat/Jetty)中,user.dir 常指向服务器 bin 目录,与开发预期严重偏离。
未经校验拼接用户输入路径
常见错误模式:Paths.get(System.getProperty("user.dir"), userInput)。若 userInput 是 "../../etc/shadow",归一化后可能突破应用沙箱。
- 必须锚定可信根路径(如
Paths.get("/opt/myapp/data")) - 用
resolve()拼接,再调用normalize() - 严格校验最终路径是否以可信根的绝对规范化路径开头
- 禁止将
user.dir或java.io.tmpdir直接作为可写根目录开放给外部输入
安全管理器启用时的权限中断
当 JVM 启用 SecurityManager(如某些金融或政府系统),System.getProperty() 可能抛出 SecurityException,特别是读取敏感属性(如 sun.*、java.class.path)时。
- 不要假设所有属性都可读,需包裹 try-catch 并提供合理 fallback
- 生产环境应明确声明所需权限(如
permission java.util.PropertyPermission "user.home", "read";) - 避免在关键路径逻辑中依赖未授权属性,优先选用
System.getenv()(其权限模型不同)或显式配置项











