SV.DATA.FILE
可能会上传并自动处理潜在的有害文件
从 2023.2 版本开始,此检查器将支持 Jakarta EE。
漏洞与风险
带有某些扩展名的文件在某些环境下可以自动处理,如果未检查这些文件,则会允许攻击者注入恶意文件。
缓解与预防
实施以下做法:
- 尽可能将上传的文件存储在 Web 根目录以外的位置。
- 为上传的文件使用随机生成的文件名。
- 确保在文件名中仅使用一个扩展名。如果允许上传 .htm 文件,则要考虑跨站点脚本的可能性。
- 在区分大小写的系统上,确保执行文件扩展名的区分大小写评估。
- 在上传文件之前检查 MIME 类型是否正确,但不要只依赖于 MIME 类型。
- 尽可能确保只有带有允许的扩展名的文件才能从上传目录直接访问。例如,如果目录仅应包含图像,则限制对目录中任何 PHP/ASP 文件的访问。
漏洞代码示例 1
复制
import javax.servlet.http.*;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream()));
String pLine = br.readLine();
String filename = pLine.substring(pLine.lastIndexOf("\\"), pLine.lastIndexOf("\""));
BufferedWriter bw = new BufferedWriter(new FileWriter(UPLOAD_DIRECTORY_STRING + filename, true)); // <- Defect detected here because of a new file been created with tainted name
for (String line; (line=br.readLine())!=null; ) {
if (line.indexOf(boundary) == -1) {
bw.write(line);
bw.newLine();
bw.flush();
}
}
bw.close();
}
在此示例中,Klocwork 在第 6 行报告 SV.DATA.FILE 缺陷,指出“可能会上传并自动处理潜在的有害文件”。文件的内容和名称来自请求中,这会允许攻击者指定文件扩展名,因此可以自动处理文件。一些危险的文件扩展名包括 .exe、.py、.php。
修正代码示例 1
复制
import javax.servlet.http.*;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream()));
String pLine = br.readLine();
String filename = UUID.randomUUID().toString();
BufferedWriter bw = new BufferedWriter(new FileWriter(UPLOAD_DIRECTORY_STRING + filename, true));
for (String line; (line=br.readLine())!=null; ) {
if (line.indexOf(boundary) == -1) {
bw.write(line);
bw.newLine();
bw.flush();
}
}
bw.close();
}
克服 SV.DATA.FILE 缺陷的一种简单方式是分配无扩展名的文件名。Klocwork 不再报告缺陷,因为文件名将设置为随机生成的 UUID。
漏洞代码示例 2
复制
import jakarta.servlet.http.*;
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
//get the file chosen by the user
Part filePart = request.getPart("fileToUpload");
//get the InputStream to store the file somewhere
InputStream fileInputStream = filePart.getInputStream();
//for example, you can copy the uploaded file to the server
File fileToSave = new File("fileName.exe");
Files.copy(fileInputStream, fileToSave.toPath(), StandardCopyOption.REPLACE_EXISTING); // Detect defect here because: filename is dangerous and content is from user request
}
在此示例中,Klocwork 在第 11 行报告 SV.DATA.FILE 缺陷,指出“可能会上传并自动处理潜在的有害文件”。代码将来自请求的文件内容直接复制到可执行文件中。此请求可以自动处理或稍后故意运行,同时文件的扩展名可能会被修改或移除。
修正代码示例 2
复制
import jakarta.servlet.http.*;
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
//get the file chosen by the user
Part filePart = request.getPart("fileToUpload");
//get the InputStream to store the file somewhere
InputStream fileInputStream = filePart.getInputStream();
//for example, you can copy the uploaded file to the server
File fileToSave = new File(UUID.randomUUID().toString());
Files.copy(fileInputStream, fileToSave.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
Klocwork 不再报告缺陷,因为最简单的解决方案是为文件提供一个生成的无扩展名的名称。
相关检查器
扩展
此检查器可通过 Klocwork 知识库进行扩展。有关详情,请参阅调整 Java 分析。