【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.hqwc.cn/news/277929.html

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

相关文章

Github 2023-12-15 开源项目日报 Top10

根据Github Trendings的统计&#xff0c;今日(2023-12-15统计)共有10个项目上榜。根据开发语言中项目的数量&#xff0c;汇总情况如下&#xff1a; 开发语言项目数量TypeScript项目3非开发语言项目3JavaScript项目1Python项目1Rust项目1PHP项目1 基于项目的学习 创建周期&am…

HTTP 302错误:临时重定向

在Web开发中&#xff0c;HTTP状态码是用于表示Web服务器响应的各种状态。其中&#xff0c;HTTP 302错误表示临时重定向&#xff0c;这意味着请求的资源已被临时移动到其他位置&#xff0c;并且服务器已经提供了新的URL&#xff0c;以便客户端可以重新发送请求。 了解HTTP 302错…

【采坑分享】npm login/publish/whoami失败采坑,解决npmERR426、ETIMEDOUT、ECONNREFUSED等错误

目录 前言背景&#xff1a; 采坑之路&#xff1a; 1.修改https为http&#xff0c;问题还在 2.修改为淘宝镜像&#xff0c;问题还在 3.修改为官网地址&#xff0c;问题还在 4.升级node和npm&#xff0c;问题还在 5.猜想网络问题&#xff0c;问题解决 采坑总结&#xff1a…

VG3225EFN压控晶体振荡器(VCXO)

5G脞2020年开始&#xff0c;商业服务正在全球范围内快速部署。5G通信网络需要保持高速率和可靠性&#xff0c;这2两者都需要低噪声&#xff0c;使用高频基模晶体振荡器&#xff08;高达50MHz&#xff09;&#xff0c;该晶体振荡器可以提供低相位噪声参考时钟&#xff0c;从而降…

[每周一更]-(第27期):HTTP压测工具之wrk

[补充完善往期内容] wrk是一款简单的HTTP压测工具,托管在Github上,https://github.com/wg/wrkwrk 的一个很好的特性就是能用很少的线程压出很大的并发量. 原因是它使用了一些操作系统特定的高性能 io 机制, 比如 select, epoll, kqueue 等. 其实它是复用了 redis 的 ae 异步事…

大数据生态圈kafka在物联网中的应用测试

背景 由物联网项目中使用到了Tbox应用管理车辆&#xff0c;在上报数据的过程中&#xff0c;需要将终端产生的数据通过kafka的produce topic customer对数据进行处理后&#xff0c;放置到mysql中。完成数据二进制到json转换工作。 Kafka的使用 查看kafka的topic ./kafka-topi…

lv12 linux内核的安装与加载

目录 1 tftp加载Linux内核及rootfs 1.1 uboot内核启动命令 1.2 uboot自启动参数环境变量 1.3 实验 2 EMMC加载Linux 内核及rootfs ​编辑 2.1 emmc中写入uimage ​编辑 2.2 emmc中写入dtb 2.3 emmc中写入根文件系统 2.4 设置环境变量 3 tftp加载Linux内核nfs挂载ro…

Tekton 克隆 git 仓库

Tekton 克隆 git仓库 介绍如何使用 Tektonhub 官方 git-clone task 克隆 github 上的源码到本地。 git-clone task yaml文件下载地址&#xff1a;https://hub.tekton.dev/tekton/task/git-clone 查看git-clone task yaml内容&#xff1a; 点击Install&#xff0c;选择一种…

5G工业网关视频传输应用

随着科技的不断进步&#xff0c;5G网络技术已经成为了当前最热门的话题之一。而其中一个引人注目的领域就是5G视频传输和5G工业网关应用。在传统网络通信中&#xff0c;由于带宽和延迟的限制&#xff0c;视频传输常常受到限制&#xff0c;而工业网关应用也存在着链路不稳定、数…

HTML基础标签

但实际上无论声明为中文还是英文都可以写&#xff0c;中文/英文 主要是浏览器在进行调用翻译功能的时候&#xff0c;会按照声明的语言来进行翻译。 标签语义&#xff1a; 标签的属性一般都是在第一个标签中定义该标签效果所拥有的属性。 即标签的作用是什么 <>标签功能…

十四、YARN核心架构

1、目标 &#xff08;1&#xff09;掌握YARN的运行角色和角色之间的关系 &#xff08;2&#xff09;理解使用容器做资源分配和隔离 2、核心架构 &#xff08;1&#xff09;和HDFS架构的对比 HDFS架构&#xff1a; YARN架构&#xff1a;&#xff08;主从模式&#xff09; &…

随机森林1(了解整体知识架构)

很多人想学习或者了解随机森林&#xff0c;查到的资料都是先讲熵&#xff0c;再讲决策树&#xff0c;然后再讲随机森林&#xff0c;前面坚持不下来或者一个地方没理解透彻&#xff0c;导致无法向下学习&#xff0c;而且公式讲解不够清晰&#xff0c;例子不够详细&#xff0c;很…