【java任意文件漏洞修复,使用文件魔数解决】
java任意文件漏洞修复,使用文件魔数解决
背景: 客户进行渗透测试,验证上传文件的程序没有对上传文件作任何过滤,导致可以上传任意文件到服务器,甚至是病毒文件和Webshell木马文件。
解决办法:对于上传的附件,验证程序要做严格验证,使用服务器端校验,而不能仅用前端验证。
代码实例
// 允许上传文件后缀
private static final String[] ALLOWED_FILE_EXTENSIONS = {"jpg", "jpeg", "png", "gif", "doc", "docx", "xls", "xlsx", "pdf", "ppt", "pptx"};
// 允许上传文件头魔数十六进制字符串
private static final List<String> ALLOWED_MAGIC_NUMBERS = Arrays.asList("FFD8FF", "89504E47", "47494638", "25504446", "D0CF11E0", "504B0304"
); // JPEG (jpg),PNG (png),GIF (gif),pdf,(doc、xls、ppt),(xls、pptx)// 允许上传文件的MIME类型
private static final Set<String> ALLOWED_MIME_TYPES = new HashSet<>();
static {ALLOWED_MIME_TYPES.add("image/jpeg"); // jpg, jpeg ALLOWED_MIME_TYPES.add("image/png"); // png ALLOWED_MIME_TYPES.add("image/gif"); // gif ALLOWED_MIME_TYPES.add("application/msword"); // doc ALLOWED_MIME_TYPES.add("application/vnd.openxmlformats-officedocument.wordprocessingml.document"); // docx ALLOWED_MIME_TYPES.add("application/vnd.ms-excel"); // xls ALLOWED_MIME_TYPES.add("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); // xlsx ALLOWED_MIME_TYPES.add("application/pdf"); // pdf ALLOWED_MIME_TYPES.add("application/vnd.ms-powerpoint"); // pptALLOWED_MIME_TYPES.add("application/vnd.openxmlformats-officedocument.presentationml.presentation"); // pptx
} @SuppressWarnings("unchecked")
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.setCharacterEncoding("UTF-8");String fileType="";// 1.创建文件上传工厂类DiskFileItemFactory fac = new DiskFileItemFactory();// 2.创建文件上传核心类对象ServletFileUpload upload = new ServletFileUpload(fac);// 【一、设置单个文件最大1024M】upload.setFileSizeMax(1024 * 1024 * 1024);// 1024MM// 【二、设置总文件大小:2048M】upload.setSizeMax(2048 * 1024 * 1024); // 2048MList<String> StringArr=new ArrayList<String>();// 判断,当前表单是否为文件上传表单if (upload.isMultipartContent(request)) {try {// 3.把请求数据转换为FileItem对象的集合List<FileItem> list = upload.parseRequest(request);Calendar calendar = Calendar.getInstance();int year = calendar.get(Calendar.YEAR);// 遍历,得到每一个上传项for (FileItem item : list) {// 判断:是普通表单项,还是文件上传表单项if (item.isFormField()) {// 普通表单xString fieldName = item.getFieldName();// 获取元素名称String value = item.getString("UTF-8"); // 获取元素值fileType=value;System.out.println(fieldName + " : " + value);} else {// 文件上传表单//文件保存目录路径String savePath = getServletContext().getRealPath("/") + "uploadFiles/wjgl/"+fileType+"/"+year+"/";File uploadFile = new File(savePath);if (!uploadFile.exists()) {uploadFile.mkdirs();}String oldname = item.getName(); // 上传的文件名称String fileExtension = item.getName().substring(item.getName().lastIndexOf(".") + 1);//获取到文件后缀if (!Arrays.asList(ALLOWED_FILE_EXTENSIONS).contains(fileExtension)) {//验证文件后缀response.setStatus(500);throw new FileUploadException("if1无效的文件扩展名: " + fileExtension);}String contentType = item.getContentType();if(!ALLOWED_MIME_TYPES.contains(contentType)){response.setStatus(500);throw new FileUploadException("if2无效的文件扩展名: " + fileExtension);}if (!isFileValid(item)) {// 文件有效,进行处理response.setStatus(500);throw new FileUploadException("被改了后缀,判断文件内容魔术无效的文件扩展名: " + fileExtension);}//时间戳String time=String.valueOf(new Date().getTime());String name = time+oldname;// 【三、上传到指定目录:获取上传目录路径】String realPath = "uploadFiles/wjgl/"+fileType+"/"+year+"/";// 创建文件对象File file = new File(savePath, name);item.write(file);item.delete();response.setContentType("application/json");response.setCharacterEncoding("UTF-8");JSONObject obj = new JSONObject();obj.put("fileName", oldname);obj.put("filePath", realPath + name);StringArr.add(obj.toString());}}response.getWriter().println(StringArr);} catch (Exception e) {e.printStackTrace();}} else {System.out.println("不处理!");}}//校验是否为jpg,jpeg,png,gif,doc,docx,xls,xlsx,pdf,pptx格式
public static boolean isFileValid(FileItem fileItem) throws IOException {String fileName = fileItem.getName();try (InputStream inputStream = fileItem.getInputStream()) {return isValidFileMagicNumber(inputStream);}
}
//验证文件魔数
public static boolean isValidFileMagicNumber(InputStream inputStream) throws IOException {boolean bl=false;byte[] buffer = new byte[8];inputStream.read(buffer, 0, 8);String hexMagicNumber = bytesToHex(buffer);for(int i = 0; i<ALLOWED_MAGIC_NUMBERS.size(); i++){String ms=ALLOWED_MAGIC_NUMBERS.get(i);if(hexMagicNumber.toUpperCase().startsWith(ms)){bl=true;break;}}return bl;
}
//字节转换16进制
private static String bytesToHex(byte[] bytes) {StringBuilder hexString = new StringBuilder();for (byte b : bytes) {hexString.append(String.format("%02X", b));}return hexString.toString();
}相关文章:
【java任意文件漏洞修复,使用文件魔数解决】
java任意文件漏洞修复,使用文件魔数解决 背景: 客户进行渗透测试,验证上传文件的程序没有对上传文件作任何过滤,导致可以上传任意文件到服务器,甚至是病毒文件和Webshell木马文件。 解决办法:对于上传的附件…...
LeetCode 热题 100 | 二叉树(二)
目录 1 543. 二叉树的直径 2 102. 二叉树的层序遍历 3 108. 将有序数组转换为二叉搜索树 菜鸟做题,语言是 C 1 543. 二叉树的直径 这道题和 124. 二叉树中的最大路径和 太像了 题眼:二叉树的 直径 是指树中任意两个节点之间 最长路径的长度 。…...
mini-spring|定义标记类型Aware接口,实现感知容器对象
**前言:**如果我们想获得 Spring 框架提供的 BeanFactory、ApplicationContext、BeanClassLoader等这些能力做一些扩展框架的使用时该怎么操作呢。所以我们本章节希望在 Spring 框架中提供一种能感知容器操作的接口,如果谁实现了这样的一个接口ÿ…...
83. 删除排序链表中的重复元素
给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。 输入:head = [1,1,2] 输出:[1,2] 输入:head = [1,1,2,3,3] 输出:[1,2,3] 提示: 链表中节点数目在范围 [0, 300] 内-100 <= Node.val <= 100题目数据保证链表已…...
贪心算法
贪心算法 例题1、股票买卖题目信息思路题解 2、货仓选址题目信息思路题解 3、糖果传递题目信息思路题解 4、雷达设备题目信息思路题解 例题 1、股票买卖 题目信息 思路 相邻两天,后>前,则交易一次 题解 #include <bits/stdc.h> #define en…...
MySQL基本知识
目录 一,MySQL的元数据库 1.1.什么是元数据库 1.2.有哪些元数据库 1.3.切换数据库 二,账户管理 2.1.设置权限 2.2.授权用户 2.3.查看权限 2.4.撤销权限 三,MySQL引擎 3.1什么是数据库引擎 3.2.查看数据引擎 3.3.MyISAM引擎 3.4…...
Vue3 (unplugin-auto-import自动导入的使用)
安装 参考链接 npm i -D unplugin-auto-importvite.config.ts里面配置 import AutoImport from unplugin-auto-import/viteAutoImport({imports:[ vue,vue-router]})重新运行项目会生成一个auto-imports.d.ts的文件 /* eslint-disable */ /* prettier-ignore */ // ts-nochec…...
【漏洞复现】大华智慧园区综合管理平台信息泄露漏洞
Nx01 产品简介 大华智慧园区综合管理平台是一款综合管理平台,具备园区运营、资源调配和智能服务等功能。该平台旨在协助优化园区资源分配,满足多元化的管理需求,同时通过提供智能服务,增强使用体验。 Nx02 漏洞描述 大华智慧园区…...
JavaScript的书写方式
JavaScript的书写方式 目前较为流行的是第二种和第三种,第一种很少见。在第二种和第三种推荐使用第三种,因为在日常开发/工作中,第三种是最为常见的 1.行内式 把JS代码嵌入到html元素内部 示例代码 运行效果 由于JS中字符串常量可以使用单引…...
第二十篇-推荐-纯CPU(E5-2680)推理-llama.cpp-qwen1_5-72b-chat-q4_k_m.gguf
环境 系统:CentOS-7 CPU: Intel Xeon CPU E5-2680 v4 2.40GHz 14C28T 内存: 48G DDR3 依赖安装 make --version GNU Make 4.3gcc --version gcc (GCC) 11.2.1 20220127 (Red Hat 11.2.1-9)g --version g (GCC) 11.2.1 20220127 (Red Hat …...
CSS常见选择器
CSS常见选择器 在Web开发中,层叠样式表(CSS)是用于描述HTML或XML(包括SVG和XHTML等其他XML语言)文档的样式的语言。CSS描述了文档的表现形式,包括布局、颜色和字体等。在CSS中,选择器是一种模式…...
[LWC] Components Communication
目录 Overview Summary Sample Code 1. Parent -> Child - Public Setter / Property / Function a. Public Property b. Public getters and setters c. Public Methods 2. Child -> Parent - Custom Event 3. Unrelated Components - LMS (Lightning Message…...
Unity中URP实现水体(水下的扭曲)
文章目录 前言一、使用一张法线纹理,作为水下扭曲的纹理1、在属性面板定义一个纹理,用于传入法线贴图2、在Pass中,定义对应的纹理和采样器3、在常量缓冲区,申明修改 Tilling 和 Offset 的ST4、在顶点着色器,计算得到 应…...
anaconda指定目录创建环境无效/环境无法创建到指定位置
已经设置目录到D盘 创建环境时还是分配到C盘 可能是指定位置没有开启读写权限,如我在这里安装到了anaconda文件夹,则打开该文件夹的属性->安全->编辑 allusers下的权限全都打勾...
《Docker极简教程》--Docker在生产环境的应用--Docker在生产环境的部署
一、准备工作 1.1 硬件和基础设施要求 硬件和基础设施要求是在部署 Docker 到生产环境之前需要认真考虑和准备的重要方面,以下是一般性的要求: 服务器硬件: CPU:建议使用多核处理器,以支持同时运行多个容器。内存&a…...
算法D31 | 贪心算法1 | 455.分发饼干 376. 摆动序列 53. 最大子序和
贪心算法其实就是没有什么规律可言,所以大家了解贪心算法 就了解它没有规律的本质就够了。 不用花心思去研究其规律, 没有思路就立刻看题解。 基本贪心的题目 有两个极端,要不就是特简单,要不就是死活想不出来。 学完贪心之后再…...
在IDEA中创建vue hello-world项目
工作中最近在接触vue前端项目,记录一下从0搭建一个vue hello world项目的步骤 1、本地电脑安装配置node、npm D:\Project\vue\hello-world>node -v v14.21.3 D:\Project\vue\hello-world>npm -v 6.14.18 D:\Project\vue\hello-world> 2、设置npm国内淘…...
如何获取pnpm存储目录
现在你可以做 得到:\path\to.pnpm-store\v3 pnpm store path注:从v7.0.0开始,pnpm 存储位于不同的文件夹中。它将位于$XDG_DATA_HOMELinux Linux : ~/.local/share/pnpm/store (default) Windows : C:\Users\YOUR_NAME\AppData\Local\pn…...
QT两个类之间使用信号槽
在做一些东西的时候,习惯性的引入头文件并且调用,因此出现了很多bug,qt的信号槽机制便可以有效的避免一些问题。 A类 #ifndef A_H #define A_H#include <QObject> #include <QDebug> class A : public QObject {Q_OBJECT public:explicit A…...
【Ubuntu】使用WSL安装Ubuntu
WSL 适用于 Linux 的 Windows 子系统 (WSL) 是 Windows 的一项功能,可用于在 Windows 计算机上运行 Linux 环境,而无需单独的虚拟机或双引导。 WSL 旨在为希望同时使用 Windows 和 Linux 的开发人员提供无缝高效的体验。安装 Linux 发行版时,…...
Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...
MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...
scikit-learn机器学习
# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...
C# 表达式和运算符(求值顺序)
求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如,已知表达式3*52,依照子表达式的求值顺序,有两种可能的结果,如图9-3所示。 如果乘法先执行,结果是17。如果5…...
