SV.PATH

路径和文件名注入

如果未经验证的或受污染的数据直接用于方法(用于系统文件或读取/写入文件)的文件或路径名称中,此错误将检测到该情况。攻击者可使用文件分隔符和相对路径名称来读取他们不应访问的文件。

从 2023.2 版本开始,此检查器将支持 Jakarta EE。

从 2026.3 版本开始,此检查器还将 LLM 响应文本视为不受信任的来源。

漏洞与风险

通常,应用程序内对主机系统的文件访问和创建涉及安全问题。如果在用于执行的文件或路径字符串的任何部分中使用未经检查的用户输入,则会存在安全漏洞。攻击者可对文件和路径进行操纵,以在主机系统上写入数据或访问数据。典型的攻击可能涉及操纵文件名以从主机系统访问 /etc/passwd 文件。通常,路径注入可能威胁主机服务器上文件系统的安全。

Klocwork 安全漏洞 (SV) 检查器可识别可能创建危险数据的调用;这些调用被视为不安全的来源。用户所提供的任何数据都可能是不安全的来源,因为用户可能是攻击者,或者可能引入人为错误。

缓解与预防

通过验证来自应用程序外部的任何及所有输入(用户输入、文件输入、系统参数等),可预防来自用户输入的路径注入攻击。验证应包括长度和内容。通常仅需要字母数字字符(即 A-Z、a-z、0-9)。应对任何其他接受的字符进行转义。应该在每个数据源处进行该验证,例如从 HTTP 请求读取每个参数时。

漏洞代码示例 1

复制
     import javax.servlet.http.*;
     public void processUserProfile(ServletRequest req) throws IOException {
         // Source of data from HTTP request in servlet
         String userName = req.getParameter("userName");
         String profile = profileDir + File.separator + userName;
         BufferedReader reader = new BufferedReader(new FileReader(profile));
         try {
             //...
         } finally {
             reader.close();
         }
     }

Klocwork 在第 6 行报告 SV.PATH 缺陷,指出:userName 包含来自 HTTP 请求参数的数据,因此可能已被污染(第 5 行)。此值与常量字符串连接,并存储于第 6 行的 profile 中。第 7 行的 profile 用于访问本地文件系统中的文件。文件和路径名称可用于揭示重要信息或用于更改应用程序行为。

漏洞代码示例 2

复制
     import jakarta.servlet.http.*;
     public void processUserProfile(ServletRequest req) throws IOException {
         // Source of data from HTTP request in servlet
         String userName = req.getParameter("userName");
         String profile = profileDir + File.separator + userName;
         BufferedReader reader = new BufferedReader(new FileReader(profile));
         try {
             //...
         } finally {
             reader.close();
         }
     }

Klocwork 在第 6 行报告 SV.PATH 缺陷,指出:userName 包含来自 HTTP 请求参数的数据,因此可能已被污染(第 5 行)。此值与常量字符串连接,并存储于第 6 行的 profile 中。第 7 行的 profile 用于访问本地文件系统中的文件。文件和路径名称可用于揭示重要信息或用于更改应用程序行为。

漏洞代码示例 3

复制
import dev.langchain4j.model.chat.ChatModel;
import java.io.FileInputStream;
import java.io.IOException;

public class Example {
    public FileInputStream run(ChatModel model) throws IOException {
        String path = model.chat("Which file holds the config?"); // untrusted LLM output
        return new FileInputStream(path); // opens a model-supplied path
    }
}

Klocwork 在第 7 行报告了一个 SV.PATH 缺陷,因为 LLM 输出直接用作文件路径。

修正代码示例 3

复制
import dev.langchain4j.model.chat.ChatModel;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Path;

public class Example {
    public FileInputStream run(ChatModel model) throws IOException {
        String name = model.chat("Which file holds the config?");
        Path base = Path.of("/srv/config").toRealPath();
        Path resolved = base.resolve(name).normalize();
        if (!resolved.startsWith(base)) { // reject traversal outside the base directory
            throw new SecurityException("path outside allowed directory");
        }
        return new FileInputStream(resolved.toFile());
    }
}

在这个修正示例中,Klocwork 不再报告 SV.PATH 缺陷,因为模型提供的路径会根据允许的基本目录进行解析,如果超出该目录则会被拒绝。

安全培训

应用程序安全培训材料由 Secure Code Warrior 提供。

扩展

此检查器可通过 Klocwork 知识库进行扩展。有关详情,请参阅调整 Java 分析。