当前位置: 首页 > article >正文

【Java代码审计 | 第八篇】文件操作漏洞成因及防范

未经许可,不得转载。

文章目录

  • 文件操作漏洞
    • 文件读取漏洞
      • 基于 InputStream 的读取
      • 基于 FileReader 的读取
    • 文件下载漏洞
    • 文件删除漏洞
    • 防范

在这里插入图片描述

文件操作漏洞

分为文件读取漏洞、文件下载漏洞与文件删除漏洞。

文件读取漏洞

在Java中,文件读取通常有两种常见方式:一种是基于InputStream,另一种是基于FileReader

漏洞成因:未对用户输入做过滤,导致读取敏感文件并返回至客户端。

以下两种代码形式都存在路径遍历问题。

基于 InputStream 的读取

String filename = request.getParameter("filename");  // 假设这是用户输入的文件名
File file = new File(filename);  // 创建文件对象,未进行任何路径验证
InputStream inputStream = new FileInputStream(file);  // 创建输入流
int len;
while (-1 != (len = inputStream.read())) {  // 循环读取文件内容outputStream.write(len);  // 将读取的字节写入输出流
}

基于 FileReader 的读取

String filename = request.getParameter("filename");  // 假设这是用户输入的文件名
String fileContent = "";  // 存储文件内容
FileReader fileReader = new FileReader(filename);  // 创建FileReader对象,未进行任何路径验证
BufferedReader bufferedReader = new BufferedReader(fileReader);  // 包装为BufferedReader
String line;
while (null != (line = bufferedReader.readLine())) {  // 逐行读取文件fileContent += (line + "\n");  // 拼接每一行内容
}

文件下载漏洞

漏洞成因:未对用户输入做过滤,导致用户端可下载敏感文件。

filename 参数未经过任何验证或过滤,攻击者可以通过构造恶意路径下载系统敏感文件。

String filename = request.getParameter("filename");  // 获取文件名
File file = new File(filename);  // 创建文件对象
response.reset();  // 重置响应
response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes("utf-8")));  // 设置下载文件名
response.addHeader("Content-Length", "" + file.length());  // 设置文件大小
response.setContentType("application/octet-stream; charset=utf-8");  // 设置响应内容类型为二进制流InputStream inputStream = new FileInputStream(file);  // 创建输入流读取文件
OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());  // 获取输出流
int len;
while (-1 != (len = inputStream.read())) {  // 读取文件并写入响应outputStream.write(len);
}
inputStream.close();  // 关闭输入流
outputStream.close();  // 关闭输出流

文件删除漏洞

漏洞成因:未对用户输入做过滤,导致敏感文件被删除。

filename 参数未经过任何验证或过滤,攻击者可以通过构造恶意路径删除系统关键文件。

String filename = request.getParameter("filename");  // 获取文件名
File file = new File(filename);  // 创建文件对象
if (file != null && file.exists() && file.delete()) {  // 检查文件存在并删除response.getWriter().println("Delete success");  // 删除成功
} else {response.getWriter().println("Delete failed");  // 删除失败
}

防范

1、使用 getCanonicalPath() 方法获取文件的规范路径,并与预期的基路径进行比较,确保文件路径在允许的范围内。

String basePath = "/allowed/directory/";  // 允许访问的基路径
File file = new File(basePath, filename);  // 拼接文件路径
if (!file.getCanonicalPath().startsWith(new File(basePath).getCanonicalPath())) {throw new SecurityException("非法文件路径");  // 路径不在允许范围内,抛出异常
}

对以下语句进行解读:

if (!file.getCanonicalPath().startsWith(new File(basePath).getCanonicalPath())) {

file.getCanonicalPath():这个方法返回文件的规范化路径,即将路径中的 .(当前目录)和 …(上级目录)等符号解析成实际的绝对路径。

1、假设:basePath = “/allowed/directory/”
2、用户输入 filename = “…/…/etc/passwd”
3、new File(basePath):创建 /allowed/directory/ 的 File 对象。
4、file = new File(basePath, filename):用户提供的路径是 …/…/etc/passwd,所以拼接后的 file 实际路径为 /allowed/directory/…/…/etc/passwd,这是一个潜在的路径遍历。
5、file.getCanonicalPath():获取文件的规范化路径,经过解析后变为 /etc/passwd(因为路径 …/…/ 会使路径跳转到根目录)。
6、new File(basePath).getCanonicalPath():获取 /allowed/directory/ 的规范化路径,即 /allowed/directory/。
7、在这种情况下,file.getCanonicalPath()(即 /etc/passwd)不会以 /allowed/directory/ 开头,因此会进入 if 语句块,阻止访问该文件。

其次是检查文件后缀是否在允许的后缀白名单中,举个例子:

// 定义允许的文件后缀白名单
Set<String> allowedExtensions = new HashSet<>(Arrays.asList("txt", "pdf", "jpg", "png", "doc", "xls"
));String filename = request.getParameter("filename");  // 获取文件名
String fileExtension = filename.substring(filename.lastIndexOf(".") + 1).toLowerCase();  // 提取后缀并转为小写// 检查后缀是否在白名单中
if (!allowedExtensions.contains(fileExtension)) {throw new SecurityException("非法文件类型");  // 文件类型不在白名单中,抛出异常
}File file = new File(filename);  // 创建文件对象// 使用 try-with-resources 读取文件
try (InputStream inputStream = new FileInputStream(file);OutputStream outputStream = new BufferedOutputStream(response.getOutputStream())) {int len;while (-1 != (len = inputStream.read())) {outputStream.write(len);}
} catch (IOException e) {e.printStackTrace();
}

相关文章:

【Java代码审计 | 第八篇】文件操作漏洞成因及防范

未经许可&#xff0c;不得转载。 文章目录 文件操作漏洞文件读取漏洞基于 InputStream 的读取基于 FileReader 的读取 文件下载漏洞文件删除漏洞防范 文件操作漏洞 分为文件读取漏洞、文件下载漏洞与文件删除漏洞。 文件读取漏洞 在Java中&#xff0c;文件读取通常有两种常见…...

在Linux开发板中使用.NET实现音频开发

本文将以Linux开发板为基础&#xff0c;使用ALSA音频框架和C#语言&#xff0c;演示如何实现基础的音频录制与播放功能。 1. 背景 音频处理是嵌入式开发中常见的需求&#xff0c;无论是语音交互、环境监测还是多媒体应用都离不开音频模块的支持。在Linux系统中&#xff0c;ALSA…...

SQL Server核心知识总结

SQL Server核心知识总结 &#x1f3af; 本文总结了SQL Server核心知识点,每个主题都提供实际可运行的示例代码。 一、SQL Server基础精要 1. 数据库核心操作 -- 1. 创建数据库&#xff08;核心配置&#xff09; CREATE DATABASE 学生管理系统 ON PRIMARY (NAME 学生管理系统…...

基于RNN+微信小程序+Flask的古诗词生成应用

项目介绍 平台采用B/S结构&#xff0c;后端采用主流的Flask框架进行开发&#xff0c;古诗词生成采用RNN模型进行生成&#xff0c;客户端基于微信小程序开发。是集成了Web后台开发、微信小程序开发、人工智能&#xff08;RNN&#xff09;等多个领域的综合性应用&#xff0c;是课…...

基于单片机的智慧农业大棚系统(论文+源码)

1系统整体设计 经过上述的方案分析&#xff0c;采用STM32单片机为核心&#xff0c;结合串口通信模块&#xff0c;温湿度传感器&#xff0c;光照传感器&#xff0c;土壤湿度传感器&#xff0c;LED灯等硬件设备来构成整个控制系统。系统可以实现环境的温湿度检测&#xff0c;土壤…...

【AGI】智谱开源2025:一场AI技术民主化的革命正在到来

智谱开源2025&#xff1a;一场AI技术民主化的革命正在到来 引言&#xff1a;开源&#xff0c;一场技术平权的革命一、CogView4&#xff1a;中文AI生成的里程碑1. 破解汉字生成的“AI魔咒”2. 开源协议与生态赋能 二、AutoGLM&#xff1a;人机交互的范式跃迁1. 自然语言驱动的跨…...

2025-03-08 学习记录--C/C++-PTA 习题8-9 分类统计各类字符个数

合抱之木&#xff0c;生于毫末&#xff1b;九层之台&#xff0c;起于累土&#xff1b;千里之行&#xff0c;始于足下。&#x1f4aa;&#x1f3fb; 一、题目描述 ⭐️ 二、代码&#xff08;C语言&#xff09;⭐️ #include <stdio.h> #define MAXS 15void StringCount( …...

yolov8改进|MobileNetV4替换Backbone,轻量化!!

yolov8改进|MobileNetV4替换Backbone,轻量化!! 一级目录二级目录三级目录MobileNetV4简介论文地址核心代码将核心代码放入`ultralytics/nn/modules`中,新建MobileNetV4.py修改`tasks.py``ultralytics/utils/torch_utils.py`中yaml文件一级目录 二级目录 三级目录 各位哥哥…...

OTP单片机调试工具

大部分的OTP单片机开发流程是先用仿真器进行仿真&#xff0c;f仿真完成之后再烧录OTP单片机芯片进行验证&#xff0c;但是很多少时候会发现有一个问题&#xff0c;仿真器仿真都是OK的&#xff0c;但是一旦焊接在板上了&#xff0c;就往往发现有问题&#xff0c;因为硬件条件变化…...

二次SQL注入

原理 用户向数据库存入恶意数据&#xff0c;当数据被送进数据库的时候&#xff0c;会对存入的信息进行转义然后再储存&#xff0c;但是存进去的数据会再次被转义回来&#xff08;也就是原样不变的存进数据库里&#xff0c;只是害怕攻击者在存入数据的时候捣蛋而已&#xff09;…...

机器学习:愚者未完成的诗篇(零)

当算法在数据海洋中打捞支离破碎的韵律时&#xff0c;机器学习系统展现出的智慧如同断臂的维纳斯雕像——完美与残缺构成令人战栗的美学悖论。愚者&#xff0c;在词语的混沌中编织逻辑经纬&#xff0c;却总在即将触及诗性本质的瞬间&#xff0c;暴露出认知维度的致命裂隙。 一…...

论文阅读-秦汉时期北方边疆组织的空间互动模式与直道的定位(中国)

论文英文题目&#xff1a;A spatial interaction model of Qin-Han Dynasty organisation on the northern frontier and the location of the Zhidao highway (China) 发表于&#xff1a;journal of archaeological science&#xff0c;影响因子&#xff1a;3.030 论文主要是…...

【贪心算法】将数组和减半的最小操作数

1.题目解析 2208. 将数组和减半的最少操作次数 - 力扣&#xff08;LeetCode&#xff09; 2.讲解算法原理 使用当前数组中最大的数将它减半&#xff0c;&#xff0c;直到数组和减小到一半为止&#xff0c;从而快速达到目的 重点是找到最大数&#xff0c;可以采用大根堆快速达到…...

Dify部署踩坑指南(Windows+Mac)

组件说明 Dify踩坑及解决方案 ⚠️ 除了修改镜像版本&#xff0c;nginx端口不要直接修改docker-compose.yaml &#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 1、更换镜像版本 这个文件是由.env自动生成的&#xff0c;在.env配置 …...

无人机端部署 AI 模型,实现实时数据处理和决策

在无人机端部署 AI 模型&#xff0c;实现实时数据处理和决策&#xff0c;是提升无人机智能化水平的关键技术之一。通过将 AI 模型部署到无人机上&#xff0c;可以实现实时目标检测、路径规划、避障等功能。以下是实现这一目标的详细方案和代码示例。 一、实现方案 1. 硬件选择…...

你为什么要写博客?

契机&#xff1a;最近CSDN系统给我发了一条私信&#xff0c;说我成为博主已经四年了&#xff0c;写一篇博客纪念可以得一枚纪念勋章&#xff0c;遂有此文。 机缘 最开始的这篇博客&#xff0c;是为了公司内部的一次分享会准备的&#xff0c;完全是YY出来的&#xff0c;现在看…...

【VUE2】第三期——样式冲突、组件通信、异步更新、自定义指令、插槽

目录 1 scoped解决样式冲突 2 data写法 3 组件通信 3.1 父子关系 3.1.1 父向子传值 props 3.1.2 子向父传值 $emit 3.2 非父子关系 3.2.1 event bus 事件总线 3.2.2 跨层级共享数据 provide&inject 4 props 4.1 介绍 4.2 props校验完整写法 5 v-model原理 …...

P8685 [蓝桥杯 2019 省 A] 外卖店优先级--优先队列“数组”!!!!!

P8685 [蓝桥杯 2019 省 A] 外卖店优先级 题目 解析优先队列如何判断是否使用优先队列&#xff1f;省略规则优先队列常用操作大顶堆 vs 小顶堆定义队列h队列数组 代码 题目 解析 每个外卖店会在不同的时间点收到订单&#xff0c;我们可以看见测试用例的时间顺序是不同的&#x…...

VsCode + EIDE + OpenOCD + STM32(野火DAP) 开发环境配置

VsCode EIDE OpenOCD STM32(野火DAP) 开发环境配置 接受了新时代编辑器的我&#xff0c;实在受不了Keil的上古编辑页面&#xff0c;周树人说过&#xff1a;由奢入俭难&#xff0c;下面我们一起折腾一下开源软件Vscode&#xff0c; 用以开发51和STM32&#xff0c;有错误之处&…...

JVM类加载器面试题及原理

JVM只会运行二进制文件&#xff0c;类加载器的作用就是将字节码文件加载到JVM中&#xff0c;从而让Java程序能够启动起来。 1. 类加载器的种类 启动类加载器&#xff08;BootStrap ClassLoader&#xff09;&#xff1a;加载JAVA_HOME/jre/lib目录下的库扩展类加载器&#xff…...

在 Maven 中使用 <scope> 元素:全面指南

目录 前言 在 Maven 中&#xff0c; 元素用于定义依赖项的作用范围&#xff0c;即依赖项在项目生命周期中的使用方式。正确使用 可以帮助我们优化项目的构建过程&#xff0c;减少不必要的依赖冲突&#xff0c;并提高构建效率。本文将详细介绍 的使用步骤、常见作用范围、代码…...

tomcat的安装与配置(包含在idea中配置tomcat)

Tomcat 是由 Apache 软件基金会开发的开源 Java Web 应用服务器&#xff0c;主要用于运行 Servlet 和 JSP&#xff08;JavaServer Pages&#xff09;程序。它属于轻量级应用服务器&#xff0c;适用于中小型系统及开发调试场景&#xff0c;尤其在处理动态内容&#xff08;如 Jav…...

问题解决:AttributeError: ‘NoneType‘ object has no attribute ‘text‘

项目环境&#xff1a; 我的环境&#xff1a;Window10&#xff0c;Python3.12&#xff0c;Anaconda3&#xff0c;Pycharm2024.3.4 问题描述&#xff1a; 找不到’text’这个对象 部分代码&#xff1a; Traceback (most recent call last):File "D:\IT DateFiles\PyDate\FQ…...

量子计算测试挑战:软件测试将如何迎接新纪元?

引言 在计算机技术的飞速发展中&#xff0c;量子计算(Quantum Computing)正成为下一个颠覆性的科技热点。随着谷歌、IBM、微软等科技巨头纷纷投入巨资研究量子计算&#xff0c;其应用场景正逐步扩展&#xff0c;从优化计算到密码安全&#xff0c;再到人工智能和材料科学。然而…...

读书报告」网络安全防御实战--蓝军武器库

一眨眼&#xff0c;20天过去了&#xff0c;刷完了这本书「网络安全防御实战--蓝军武器库」&#xff0c;回味无穷&#xff0c;整理概览如下&#xff0c;可共同交流读书心得。在阅读本书的过程中&#xff0c;我深刻感受到网络安全防御是一个综合性、复杂性极高的领域。蓝军需要掌…...

《机器学习数学基础》补充资料:过渡矩阵和坐标变换推导

尽管《机器学习数学基础》这本书&#xff0c;耗费了比较长的时间和精力&#xff0c;怎奈学识有限&#xff0c;错误难免。因此&#xff0c;除了在专门的网页&#xff08; 勘误和修订 &#xff09;中发布勘误和修订内容之外&#xff0c;对于重大错误&#xff0c;我还会以专题的形…...

深度学习与普通神经网络有何区别?

深度学习与普通神经网络的主要区别体现在以下几个方面&#xff1a; 一、结构复杂度 普通神经网络&#xff1a;通常指浅层结构&#xff0c;层数较少&#xff0c;一般为2-3层&#xff0c;包括输入层、一个或多个隐藏层、输出层。深度学习&#xff1a;强调通过5层以上的深度架构…...

Flutter底层实现

1. Dart 语言 Dart 是 Flutter 的主要编程语言。Dart 设计之初就是为了与 JavaScript 兼容&#xff0c;并且可以编译为机器代码运行。Dart 提供了一些特性&#xff0c;如异步支持&#xff08;通过 async 和 await&#xff09;&#xff0c;这使得编写高效的网络请求和复杂动画变…...

【芯片验证】verificationguide上的36道UVM面试题

跟上一篇一样,verificationguide上的36到UVM面试题,通义回答ds判卷。 1. What is uvm_transaction, uvm_seq_item, uvm_object, uvm_component? uvm_transaction、uvm_seq_item、uvm_object、uvm_component是什么? uvm_transaction是UVM中所有事务的基础类,用于表示仿真…...

AI日报 - 2025年3月10日

AI日报 - 2025年3月10日 &#x1f31f; 今日概览&#xff08;60秒速览&#xff09; ▎&#x1f916; AGI突破 | Anthropic CEO预测强AI最早2026年到来 &#x1f52c; SAGE框架提升问答质量61.25%&#xff0c;Reflexion框架将GPT-4成功率提至91% ▎&#x1f4bc; 商业动向 | xA…...