【Java代码审计 | 第九篇】文件写入漏洞成因及防范

未经许可,不得转载。

在这里插入图片描述

文件写入功能不同于上文的文件下载、读取、删除功能。

文件写入漏洞

文件写入漏洞是指在应用程序中,攻击者通过未经授权或不安全的方式,将恶意数据写入系统文件或敏感文件的漏洞,可能导致执行恶意操作,导致系统泄露、破坏或其他严重安全问题。

漏洞成因

1、没有足够的路径验证,缺乏权限检查,允许用户向系统或敏感目录中的文件写入数据;
2、不当的文件名(如文件名XSS)、文件类型(如exe)验证;
4、没有严格的文件内容限制。

漏洞代码

String filename = request.getParameter("filename");  // 获取用户输入的文件名
String content = request.getParameter("content");   // 获取文件内容

File file = new File(filename);  // 创建文件对象
try (FileWriter writer = new FileWriter(file)) {
    writer.write(content);  // 写入文件内容
    response.getWriter().println("文件写入成功");
} catch (IOException e) {
    response.getWriter().println("文件写入失败");
}

漏洞分析:
1、如果文件内容被直接写入 HTML 文件且未进行转义,攻击者可以注入恶意脚本(如 <script>alert('XSS')</script>),导致 XSS 攻击。
2、如果文件名未经过滤,攻击者可以通过构造恶意路径(如 ../../etc/passwd)覆盖系统文件。
3、如果文件内容未经过滤,攻击者可以写入恶意代码(如 JSP 脚本、SQL 语句等),导致服务器被攻击。

防范

1、对文件内容进行字符实体化

import org.apache.commons.text.StringEscapeUtils;

String content = request.getParameter("content");  // 获取文件内容
content = StringEscapeUtils.escapeHtml4(content);  // 对内容进行字符实体化

try (FileWriter writer = new FileWriter(file)) {
    writer.write(content);  // 写入字符实体化后的内容
} catch (IOException e) {
    e.printStackTrace();
}

2、对文件名、文件类型进行过滤

String filename = request.getParameter("filename");  // 获取文件名

// 过滤非法字符(如 ../、<、> 等)
if (filename.contains("..") || filename.contains("<") || filename.contains(">")) {
    throw new SecurityException("非法文件名");
}

// 限制文件后缀
Set<String> allowedExtensions = new HashSet<>(Arrays.asList("txt", "log", "csv"));
String fileExtension = filename.substring(filename.lastIndexOf(".") + 1).toLowerCase();
if (!allowedExtensions.contains(fileExtension)) {
    throw new SecurityException("非法文件类型");
}

3、对写入内容做黑名单过滤

List<String> blackContents = Arrays.asList("<%@page", "<%!", "<?php", "SELECT", "INSERT", "DELETE");

String content = request.getParameter("content");  // 获取文件内容

// 检查是否包含黑名单内容
for (String blackContent : blackContents) {
    if (content.contains(blackContent)) {
        throw new SecurityException("非法文件内容");
    }
}

try (FileWriter writer = new FileWriter(file)) {
    writer.write(content);  // 写入过滤后的内容
} catch (IOException e) {
    e.printStackTrace();
}

4、限制文件写入目录

将文件写入操作限制在特定的安全目录中,防止攻击者通过路径遍历覆盖系统文件。

String basePath = "/safe/directory/";  // 安全目录
String filename = request.getParameter("filename");  // 获取文件名

File file = new File(basePath, filename);  // 将文件限制在安全目录中
if (!file.getCanonicalPath().startsWith(new File(basePath).getCanonicalPath())) {
    throw new SecurityException("非法文件路径");
}

关于以下语句的说明,可参考:【Java代码审计 | 第八篇】文件操作漏洞成因及防范

if (!file.getCanonicalPath().startsWith(new File(basePath).getCanonicalPath())) {
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秋说

感谢打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值