【Java代码审计】文件上传篇

【Java代码审计】文件上传篇

  • 1.Java常见文件上传方式
  • 2.文件上传漏洞修复

1.Java常见文件上传方式

1、通过文件流的方式上传

public static void uploadFile(String targetURL, String filePath) throws IOException {File file = new File(filePath);FileInputStream fileInputStream = new FileInputStream(file);URL url = new URL(targetURL);HttpURLConnection connection = (HttpURLConnection) url.openConnection();connection.setDoOutput(true);connection.setRequestMethod("POST");// 设置请求头,根据实际需求进行更改connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=---boundary");// 创建文件流输出流OutputStream outputStream = connection.getOutputStream();// 写入文件数据byte[] buffer = new byte[4096];int bytesRead;while ((bytesRead = fileInputStream.read(buffer)) != -1) {outputStream.write(buffer, 0, bytesRead);}// 关闭文件流和连接fileInputStream.close();outputStream.flush();outputStream.close();// 获取服务器返回的响应int responseCode = connection.getResponseCode();if (responseCode == HttpURLConnection.HTTP_OK) {// 上传成功System.out.println("文件上传成功!");} else {// 上传失败System.out.println("文件上传失败!错误代码:" + responseCode);}
}

2、通过ServletFileUpload方式上传

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 检查请求是否为multipart/form-data类型boolean isMultipart = ServletFileUpload.isMultipartContent(request);if (isMultipart) {FileItemFactory factory = new DiskFileItemFactory();ServletFileUpload upload = new ServletFileUpload(factory);try {// 解析请求,获取所有表单项List<FileItem> items = upload.parseRequest(request);// 遍历表单项for (FileItem item : items) {if (!item.isFormField()) { // 如果是文件字段String fileName = item.getName();InputStream fileContent = item.getInputStream();// 进行文件保存操作,可以根据实际需求自行实现saveFile(fileName, fileContent);}}response.getWriter().write("文件上传成功!");} catch (Exception e) {response.getWriter().write("文件上传失败!");e.printStackTrace();}} else {response.getWriter().write("请求未包含文件!");}
}

3、通过MultipartFile方式上传

public String singleFileUpload(@RequestParam("file") MultipartFile file, RedirectAttributes redirectAttributes) {try {byte[] bytes = file.getBytes();Path dir = Paths.get(UPLOADED_FOLDER);Path path = Paths.get(UPLOADED_FOLDER + file.getOriginalFilename());Files.write(path, bytes);redirectAttributes.addFlashAttribute("message","上传文件成功:" + path + "");} catch (Exception e) {return e.toString();}return "redirect:upload_status";
}

该代码没有对上传文件的后缀类型等进行限制,现在我们可以上传一个恶意的jsp脚本到服务器解析执行:

在这里插入图片描述

上传成功:

在这里插入图片描述

一个非常有效的防御方法是对上传文件后缀名做白名单处理:

public String singleFileUploadSafe(@RequestParam("file") MultipartFile file,RedirectAttributes redirectAttributes) {try {byte[] bytes = file.getBytes();String fileName = file.getOriginalFilename();Path dir = Paths.get(UPLOADED_FOLDER);Path path = Paths.get(UPLOADED_FOLDER + file.getOriginalFilename());// 获取文件后缀名String Suffix = fileName.substring(fileName.lastIndexOf("."));String[] SuffixSafe = {".jpg", ".png", ".jpeg", ".gif", ".bmp", ".ico"};boolean flag = false;for (String s : SuffixSafe) {if (Suffix.toLowerCase().equals(s)) {flag = true;break;}}if (!flag) {return "只允许上传图片,[.jpg, .png, .jpeg, .gif, .bmp, .ico]";}       

此时继续上传恶意脚本,已经成功拦截:

在这里插入图片描述

在审计文件上传漏洞时,关注的重点往往是在上传表单的代码段。我们可以总结出以下一些经典的关键字:

在这里插入图片描述


2.文件上传漏洞修复

对于文件上传漏洞的修复一般最有效的方法是限制上传类型并对文件进行重命名,采取白名单策略限制运行上传的类型;对文件名字进行重命名;去除文件名中的特殊字符;上传图片时,通过图片库检测上传文件是否为图片

通过“String Suffix=fileName.substring(fileName.lastIndexOf("."))”中的“fileName.lastIndexOf(".")”获取文件的真实后缀,避免了上文中通过“fileName.substring(fileName.indexOf("."))”获取文件后缀,以.jpg.jsp的方式绕过检测的情况。通过“String whitetype[]={"image/gif","image/jpeg","image/jpg","image/png"}”对文件的类型进行判断,虽然可以通过抓包的方式修改Content-Type来绕过,但也有一定限制作用。通过验证后,在文件存储时将文件进行了随机重命名,且重命名后的文件要保证不可预测,不显示在回包和日志文件中,避免上传的文件被恶意利用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/225839.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

太阳能电池特性测试用太阳光模拟器24H光源

概述 太阳能模拟器是一种在室内模拟太阳光的设备&#xff0c;能够较为准确地模拟太阳辐射的准直性、均匀性和光谱特性。它的基本原理是利用人工光源模拟太阳光辐射&#xff0c;以克服太阳光辐射受环境、时间和气候等因素影响&#xff0c;并且总辐照度不能调节等缺点&#xff0c…

继续看回溯问题

关卡名 继续看回溯问题 我会了✔️ 内容 1.复习递归和N叉树&#xff0c;理解相关代码是如何实现的 ✔️ 2.理解回溯到底怎么回事 ✔️ 3.掌握如何使用回溯来解决二叉树的路径问题 ✔️ 1 复原IP地址 这也是一个经典的分割类型的回溯问题。LeetCode93.有效IP地址正好由四…

sourcetree使用详解

介绍 SourceTree 是 Windows 和Mac OS X 下免费的 Git 和 Hg 客户端管理工具&#xff0c;同时也是Mn版本控制系统工具。支持创建、克隆、提交、push、pull 和合并等操作。——百度百科 是一款比较好用的图形化GUI的git、hg管理工具。还有一些其他的可视化代码管理工具&#x…

vivado约束方法7

输出延迟 与“输入延迟”步骤类似&#xff0c;“定时约束”向导分析所有输出的路径端口&#xff0c;以识别其在设计内部的源时钟及其活动边缘。模板选择规则与输入延迟中描述的相同。下图显示了几个由向导提出并由用户部分编辑的输出约束。 对于每个约束&#xff0c;可以编辑三…

zync spi flash 频率配置

spi flash的频率配置 代码流程及最终的频率值。 驱动目录 基于4.14.55 内核&#xff0c; \drivers\spi\spi-dw-fmsh.c (控制器) \drivers\spi\spi-dw.c \drivers\mtd\devices\m25p80.c &#xff08;设备&#xff09; \drivers\spi\spi.c spi dts配置说明 spi0: spie000100…

2. 学成在线 - 项目搭建

文章目录 一、基础工程搭建1.1 构建父工程1.2 构建基础工程 二、数据库环境2.1 内容管理content数据库 三、模块需求分析介绍四、部署前端和系统管理服务 一、基础工程搭建 整个项目分为三大类工程&#xff1a;父工程、基础工程 和微服务工程。 父工程&#xff1a;xuecheng-pl…

Android Studio 实现音乐播放器

目录 一、引言 视频效果展示&#xff1a; 1.启动页效果 2.登录页效果 3.注册页效果 4.歌曲列表页效果 5.播放页效果 二、详细设计 1.登陆注册功能 2.音乐列表页面 2.音乐播放功能 三、源码获取 一、引言 Android初学者开发第一个完整的实例项目应该就属《音乐播放器…

Docker中的常见命令

Docker开机自启 systemctl enable dockerDocker容器开机自启 docker update --restartalways [容器名/容器id]案例&#xff1a;docker操作nginx 拉取Nginx镜像 docker pull nginx查看镜像 docker images创建并运行Nginx容器 docker run -d --name nginx -p 80:80 nginx查…

LT8711HE方案《任天堂Switch底座方案》

LT8711HE Type-c转HDMI方案 LT8711HE是高性能的Type-C/DP1.2转HDMI2.0转换器&#xff0c;设计用于连接 USB Type-C 源或 DP1.2 源到 HDMI2.0 接收器。该LT8711HE集成了符合 DP1.2 标准的接收器和符合 HDMI2.0 标准的发射器。此外&#xff0c;两个 CC 控制器是包括用于 CC 通信以…

1.6 实战:Postman请求Get接口-获取用于登录的图形验证码

上一小节我们学习了Postman的布局,对Postman有了一个整体的认知,本小节我们就来实操一下Get接口。 我们打开Postman,点击我们之前创建的请求”获取登录页验证码“。我们在地址栏里填入获取登录页验证码的接口地址。怎么查看这个接口地址呢?我们打开校园二手交易系统,打开…

Leetcode—2414.最长的字母序连续子字符串的长度【中等】

2023每日刷题&#xff08;六十&#xff09; Leetcode—2414.最长的字母序连续子字符串的长度 实现代码 class Solution { public:int longestContinuousSubstring(string s) {int ans 1;int t 1;for(int i 1; i < s.size(); i) {if(s[i] - s[i - 1] 1) {t;ans max(an…

师兄啊师兄第二季开播:男主成海神?玄机是懂联动的!

《师兄啊师兄》动画第二季在12月14日终于正式开播&#xff0c;首播两集&#xff0c;还是很有诚意的。 这部动画改编自言归正传的小说《我师兄实在太稳健了》&#xff0c;原著的知名度不算很高&#xff0c;但玄机制作的动画让这个IP火出了圈。 动画第一季就凭借高颜值的人物建模…

spring boot 实现直播聊天室

spring boot 实现直播聊天室 技术方案: spring bootwebsocketrabbitmq 使用 rabbitmq 提高系统吞吐量 引入依赖 <dependencies><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>2.0.42&…

LeetCode 300最长递增子序列 674最长连续递增序列 718最长重复子数组 | 代码随想录25期训练营day52

动态规划算法10 LeetCode 300 最长递增子序列 2023.12.15 题目链接代码随想录讲解[链接] int lengthOfLIS(vector<int>& nums) {//创建变量result存储最终答案,设默认值为1int result 1;//1确定dp数组&#xff0c;dp[i]表示以nums[i]为结尾的子数组的最长长度ve…

VS Code连接远程Linux服务器调试C程序

1.在 VS Code 上安装扩展 C/C 2.通过 VS Code 连接远程 Linux 服务器 3.通过 VS Code 在远程 Linux 服务器上安装扩展 C/C 4.打开远程 Linux 服务器上的文件夹 【注】本文以 /root/ 为例。 5.创建项目文件夹&#xff0c;并在项目文件夹下创建C程序 6.按 F5&#xff0c;选…

mysql中的int(1)和int(10)的区别

今天偶然发现同事在写sql建表的时候把int类型括号后面的数字写成了1&#xff0c;但是我发现数据库里面的值已经远远超过了1位所能表示的范围&#xff0c;所以括号里面的数字肯定不是表示长度了&#xff08;印象中早期的navivat建表的时候&#xff0c;int类型如果默认不指定长度…

devc++如何建立一个c++项目?devc++提示源文件未编译?

打开devc APP后是这样的界面&#xff1b; 点击文件-> 新建->项目&#xff0c;这一点应该不难&#xff0c;主要是最后这个选择什么&#xff1f; 这样即可。 devc提示源文件未编译&#xff1f; 点击工具->编译选项&#xff1b; 如果不能解决&#xff0c;那就是可能路径…

文物数字化建模纹理贴图

在线工具推荐&#xff1a; 3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 1、文物3D数字化建模的特点 文物埋在地下历经千年&#xff0c;由于时…

转动惯量与惯性张量 的推导

从牛顿第二定律推出绕固定轴旋转的转动惯量&#xff0c;再用类似方法从牛顿第二定律推出绕固定点转动的惯性张量 基础定义 角速度 ω \omega ω是一个三维向量&#xff0c;方向表示旋转轴&#xff0c;用右手定则代表旋转方向&#xff0c;长度代表旋转弧度的速度 线速度&#…

WebGL+Three.js入门与实战——给画布换颜色、绘制一个点、三维坐标系

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1f4c3;个人状态&#xff1a; 研发工程师&#xff0c;现效力于中国工业软件事业 &#x1f680;人生格言&#xff1a; 积跬步…