java-sec-code中的文件上传

java-sec-code中的文件上传
这里仅讨论文件上传,不讨论后续利用(中间件解析漏洞等不做讨论)
任意文件伤害上传

any-->uploada.html-->upload

访问any路由时,会出现upload.html的上传文件界面,指向upload路由

@GetMapping("/any")
public String index() {
    return "upload"; // return upload.html page
}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<body>

<h3>file upload</h3>

<form method="POST" th:action="upload" enctype="multipart/form-data">
    <input type="file" name="file" /><br/><br/>
    <input type="submit" value="Submit" />
</form>

</body>
</html>
private static final String UPLOADED_FOLDER = "D:\\alibaba\\upload\\";
@PostMapping("/upload")
    public String singleFileUpload(@RequestParam("file") MultipartFile file,
                                   RedirectAttributes redirectAttributes) {
        if (file.isEmpty()) {//接受请求数据包中的file参数,如果为null,则输出Please select a file to upload
            redirectAttributes.addFlashAttribute("message", "Please select a file to upload");
            return "redirect:/file/status";
        }
        try {
            // Get the file and save it somewhere
            byte[] bytes = file.getBytes();//读取上传的文件内容
            Path path = Paths.get(UPLOADED_FOLDER + file.getOriginalFilename());//这里的UPLOADED_FOLDER是开头定义的保存文件路径,与上传的文件名拼接。
            Files.write(path, bytes);//在拼接完成的文件路径内写入数据

            redirectAttributes.addFlashAttribute("message",
                    "You successfully uploaded '" + UPLOADED_FOLDER + file.getOriginalFilename() + "'");//输出上传成功信息

        } catch (IOException e) {
            redirectAttributes.addFlashAttribute("message", "upload failed");
            logger.error(e.toString());
        }

        return "redirect:/file/status";
    }

代码段并未对用户上传的文件进行任何过滤,导致任意文件上传漏洞

只允许上传图片

 pic-->uploadPic.html-->/upload/picture
@GetMapping("/pic")
    public String uploadPic() {
        return "uploadPic"; 
    }
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<body>

<h3>file upload only picture</h3>

<form method="POST" th:action="@{upload/picture}" enctype="multipart/form-data">
    <input type="file" name="file" /><br/><br/>
    <input type="submit" value="Submit" />
</form>

</body>
</html>
@PostMapping("/upload/picture")
    @ResponseBody
    public String uploadPicture(@RequestParam("file") MultipartFile multifile) throws Exception {//从请求参数中获取file的属性值,并将其赋值给multifile
        if (multifile.isEmpty()) {
            return "Please select a file to upload";
        }//检测是否为空

        String fileName = multifile.getOriginalFilename();//获取文件名
        String Suffix = fileName.substring(fileName.lastIndexOf(".")); // 获取文件后缀名
        String mimeType = multifile.getContentType(); // 获取MIME类型
        String filePath = UPLOADED_FOLDER + fileName;//拼接上传路径和文件名
        File excelFile = convert(multifile);//将multifile传入convert方法中  在最下面


        // 判断文件后缀名是否在白名单内  校验1
        String[] picSuffixList = {".jpg", ".png", ".jpeg", ".gif", ".bmp", ".ico"};
        boolean suffixFlag = false;
        for (String white_suffix : picSuffixList) {
            if (Suffix.toLowerCase().equals(white_suffix)) {
                suffixFlag = true;
                break;
            }
        }//将后缀名转换为小写与白名单中的数据进行比对
        if (!suffixFlag) {//如果不在白名单中,则进入方法中
            logger.error("[-] Suffix error: " + Suffix);
            deleteFile(filePath);
            return "Upload failed. Illeagl picture.";
        }


        // 判断MIME类型是否在黑名单内 校验2
        String[] mimeTypeBlackList = {
                "text/html",
                "text/javascript",
                "application/javascript",
                "application/ecmascript",
                "text/xml",
                "application/xml"
        };
        for (String blackMimeType : mimeTypeBlackList) {
            // 用contains是为了防止text/html;charset=UTF-8绕过
            if (SecurityUtil.replaceSpecialStr(mimeType).toLowerCase().contains(blackMimeType)) {//replaceSpecialStr方法在最下面,去除MIME类型中除数字小写字母.点/斜杠-破折号之外的其他字符
                logger.error("[-] Mime type error: " + mimeType);
                deleteFile(filePath);
                return "Upload failed. Illeagl picture.";
            }
        }

        // 判断文件内容是否是图片 校验3
        boolean isImageFlag = isImage(excelFile);//使用ImageIO类的read方法,检测是否为JPEG、PNG、GIF 等图片格式文件
        deleteFile(randomFilePath);

        if (!isImageFlag) {
            logger.error("[-] File is not Image");
            deleteFile(filePath);
            return "Upload failed. Illeagl picture.";
        }


        try {
            // Get the file and save it somewhere
            byte[] bytes = multifile.getBytes();//获取文件内容
            Path path = Paths.get(UPLOADED_FOLDER + multifile.getOriginalFilename());//拼接完整路径
            Files.write(path, bytes);//写入文件内容
        } catch (IOException e) {
            logger.error(e.toString());
            deleteFile(filePath);
            return "Upload failed";
        }

        logger.info("[+] Safe file. Suffix: {}, MIME: {}", Suffix, mimeType);
        logger.info("[+] Successfully uploaded {}", filePath);
        return String.format("You successfully uploaded '%s'", filePath);
    }

    private void deleteFile(String filePath) {
        File delFile = new File(filePath);//新建一个file类
        if(delFile.isFile() && delFile.exists()) {//检测对应目录下是否有相应文件
            if (delFile.delete()) {//进行删除
                logger.info("[+] " + filePath + " delete successfully!");
                return;
            }
        }
        logger.info(filePath + " delete failed!");
    }

    /**
     * 为了使用ImageIO.read()
     *
     * 不建议使用transferTo,因为原始的MultipartFile会被覆盖
     * https://stackoverflow.com/questions/24339990/how-to-convert-a-multipart-file-to-file
     */
    private File convert(MultipartFile multiFile) throws Exception {
        String fileName = multiFile.getOriginalFilename();//获取文件名
        String suffix = fileName.substring(fileName.lastIndexOf("."));//获取后缀名
        UUID uuid = Generators.timeBasedGenerator().generate();//生成一个唯一的字符串标识uuid
        randomFilePath = UPLOADED_FOLDER + uuid + suffix;
        // 拼接路径,uuid和后缀名
        File convFile = new File(randomFilePath);//创建一个新的对象,路径由randomFilePath指定
        boolean ret = convFile.createNewFile();//创建一个新的文件
        if (!ret) {
            return null;
        }//检测创建文件是否成功
        FileOutputStream fos = new FileOutputStream(convFile);//创建一个新的FileOutputStream用于向convfile中写入内容
        fos.write(multiFile.getBytes());//写入文件内容
        fos.close();
        return convFile;
    }

    /**
     * Check if the file is a picture.
     */
    private static boolean isImage(File file) throws IOException {
        BufferedImage bi = ImageIO.read(file);
        return bi != null;
    }
}
public static String replaceSpecialStr(String str) {
    StringBuilder sb = new StringBuilder();
    str = str.toLowerCase();
    for(int i = 0; i < str.length(); i++) {
        char ch = str.charAt(i);
        // 如果是0-9
        if (ch >= 48 && ch <= 57 ){
            sb.append(ch);
        }
        // 如果是a-z
        else if(ch >= 97 && ch <= 122) {
            sb.append(ch);
        }
        else if(ch == '/' || ch == '.' || ch == '-'){
            sb.append(ch);
        }
    }

    return sb.toString();
}

表面上使用了多种方式验证了用户上传的文件,但实际上存在诸多问题
一,如果用户上传的是其他类型文件(例如jsp文件),虽然过不了后缀名白名单和ImageIO.read 方法过滤,但是/upload/picture方法开头有个convert方法,在未经任何过滤的前提下,进行了文件写入,虽然有个uuid使得上传后的文件名随机,但实际上的文件内容的确被写入到随机命名的jsp文件中,演示
创建一个名为test.jsp的文件,内容随机,进行上传,对应目录下生成的新文件内容和test.jsp一模一样,如果存在目录遍历漏洞则可以进行组合利用,
修改方案:在代码107行修改为 deleteFile(randomFilePath);在后缀名不符合时,删除临时文件即可,
在这里插入图片描述
二,deleteFile方法的错误利用
首先在convert方法中,上传的文件被重新命名,但deleteFile方法获取的filePath参数是方法开头直接获取的用户上传的文件名,然后直接进行删除
,在

String[] picSuffixList = {".jpg", ".png", ".jpeg", ".gif", ".bmp", ".ico"};
        boolean suffixFlag = false;
        for (String white_suffix : picSuffixList) {
            if (Suffix.toLowerCase().equals(white_suffix)) {
                suffixFlag = true;
                break;
            }
        }
        if (!suffixFlag) {
            logger.error("[-] Suffix error: " + Suffix);
            deleteFile(filePath);
            return "Upload failed. Illeagl picture.";
        }

这段代码中,如果用户上传的文件后缀名不符合这个要求,则进入deleteFile方法,删除filePath文件,假设上传文件夹中有个名为test.jsp的文件,当用户上传的文件也命名为test.jsp时,程序就会删除上传目录中的
test.jsp文件
演示
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
至于是否存在任意文件删除的问题,这里不做讨论
由于ImageIO.read必须要读取到文件,所以只能够先进行上传操作,等待检验完成,在进行删除操作

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

java SSM教师业绩管理系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java SSM教师业绩管理系统是一套完善的web设计系统&#xff08;系统采用SSM框架进行设计开发&#xff0c;springspringMVCmybatis&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代 码和数据库&#xff0c;系统主要采…

谷歌发布Gemini 1.0,开启生成式AI模型新时代!

&#x1f3a5; 屿小夏 &#xff1a; 个人主页 &#x1f525;个人专栏 &#xff1a; IT杂谈 &#x1f304; 莫道桑榆晚&#xff0c;为霞尚满天&#xff01; 文章目录 &#x1f4d1;前言一. Gemini的发布前期1.1 Gemini的准备1.2 DeepMnid 二. Gemini的三大杀手锏2.1 多模态能力2…

Linux 音视频SDK开发实践

一、兼容性适配处理 为什么需要兼容处理&#xff1f; 1、c兼容处理 主要有ABI兼容性问题&#xff0c;不同ubuntu系统依赖的ABI版本如下&#xff1a; ubuntu 18.04ubuntu 16.04ubuntu 14.04g7.55.44.8stdc版本libstdc.so.6.0.25libstdc.so.6.0.21libstdc.so.6.0.19GLIBCXXG…

详解YOLOv5网络结构/数据集获取/环境搭建/训练/推理/验证/导出/部署

一、本文介绍 本文给大家带来的教程是利用YOLOv5训练自己的数据集&#xff0c;以及有关YOLOv5的网络结构讲解/数据集获取/环境搭建/训练/推理/验证/导出/部署相关的教程&#xff0c;同时通过示例的方式让大家来了解具体的操作流程&#xff0c;过程中还分享给大家一些好用的资源…

电脑备忘录小工具怎么添加?怎么在电脑桌面添加备忘录?

作为一名天天用电脑办公的上班族&#xff0c;如果你需要对某个项目或问题进入深入思考&#xff0c;想要快速记录想法和思路&#xff0c;这时候会选择什么样的记事方式呢&#xff1f;如果你需要记录常用的工作文字内容、工作注意事项、项目流程、待办的工作安排等&#xff0c;用…

vue 将后端返回的二进制流进行处理并实现下载

什么是二进制流文件&#xff1f; 二进制文件是一种计算机文件格式&#xff0c;它的数据以二进制形式存储&#xff0c;与文本文件不同。二进制文件可以包含任意类型的数据&#xff0c;例如图像、音频、视频、可执行文件、压缩文件等&#xff0c;而文本文件则仅仅包含 ASCII 码或…

PCL 点云匹配 之NICP(Normal ICP)

一、概述 上面一篇中我们已经得出了一个结论&#xff0c;就是ICP虽然简单&#xff0c;但是也有明显的缺点 1、计算速度慢&#xff0c;收敛慢&#xff0c;迭代次数多 2、对内存的开销比较大 3、很容易陷入局部最优的困局 因此我们在经典ICP的基础上添加一两个约束&#xff1a; 第…

鸿蒙开发之简单登录页面

Entry Component struct Index {State loading:booleanfalse;build() {Row() {Column({ space: 5 }) {Image($r("app.media.app_icon")).width(100).height(100).borderRadius(10).margin({top: 60})Text("登录界面").fontSize(40).fontWeight(FontWeight.…

Apollo Planning——PathLaneBorrowDecider

引用 组件数据缓存 DependencyInjector DependencyInjector&#xff1a;依赖注入器&#xff0c;这是一个过于专业的名词&#xff0c;来自软件设计模式的依赖倒置原则的一种具体实现方式&#xff0c;起到模块解耦作用。“依赖倒置原则(Dependence Inversion Principle)是程序要…

全国国控监测点点位数据,shp/excel格式,已可视化

基本信息. 数据名称: 全国国控监测点点位数据 数据格式: shpexcel 时间版本&#xff1a;2023年 数据几何类型: 点 数据精度&#xff1a;全国 数据坐标系: WGS84 数据来源&#xff1a;网络公开数据 数据字段&#xff1a; 序号字段名称字段说明1province省名称2city城市…

设计模式 原型模式 与 Spring 原型模式源码解析(包含Bean的创建过程)

原型模式 原型模式(Prototype模式)是指&#xff1a;用原型实例指定创建对象的种类&#xff0c;并且通过拷贝这些原型&#xff0c;创建新的对象。 原型模式是一种创建型设计模式&#xff0c;允许一个对象再创建另外一个可定制的对象&#xff0c;无需知道如何创建的细节。 工作原…

SQLturning:定位连续值范围起点和终点

在上一篇blog说到&#xff0c;如何去优化查询连续值范围&#xff0c;没看过的朋友&#xff0c;上篇blog链接[在此]。(https://blog.csdn.net/weixin_42575078/article/details/135067645?spm1001.2014.3001.5501) 那么今天来说说怎么将连续的数据合并&#xff0c;然后返回合并…

Android的组件、布局学习

介绍 公司组织架构调整&#xff0c;项目组需要承接其他项目组的android项目&#xff0c;负责维护和开发新需求&#xff0c;故学习下基础语法和项目开发。 组件学习 Toolbarheader布局部分 就是app最顶部的部分 他的显示与否&#xff0c;是与F:\androidProject\android_lear…

HTML有哪些列表以及具体的使用!!!

文章目录 一、HTML列表二、列表的应用1、无序列表2、有序列表3、自定义列表 三、总结 一、HTML列表 html的列表有三种&#xff0c;一种是无序列表&#xff0c;一种是有序列表&#xff0c;还有一种为自定义列表。 二、列表的应用 1、无序列表 <ul> <li>无序列表…

【ONE·English || 翻译作业 Development: Mendel‘s Legacy to Genetics】

总言 作业&#xff1a;没有严格按照语句结构进行翻译&#xff0c;有不规范之处。下述目录中每一小节是按照原文段落划分。   相关链接&#xff1a;pubmed中查阅的链接&#xff0c;提供了两处文章平台。 文章目录 总言part11.11.21.3 part2&#xff1a;Entwicklung and develo…

LabVIEW开发自动驾驶的双目测距系统

LabVIEW开发自动驾驶的双目测距系统 随着车辆驾驶技术的不断发展&#xff0c;自动驾驶技术正日益成为现实。从L2级别的辅助驾驶技术到L3级别的受条件约束的自动驾驶技术&#xff0c;车辆安全性和智能化水平正在不断提升。在这个过程中&#xff0c;车辆主动安全预警系统发挥着关…

hive企业级调优策略之Join优化

测试所用到的数据参考&#xff1a; 原文链接&#xff1a;https://blog.csdn.net/m0_52606060/article/details/135080511 本教程的计算环境为Hive on MR。计算资源的调整主要包括Yarn和MR。 Join算法概述 Hive拥有多种join算法&#xff0c;包括Common Join&#xff0c;Map …

Android 应用基准分析

先推荐一个作者的开源项目 最快的Json解析方式 参考 benchmark数据参考 benchmark的例子 可以参考json-benchmark 应用基准分析 是衡量时间维度的框架,是App界的鲁大师跑分,常用于耗时判断,冷启动,热启动,框架对比 预热对比等方面 开局一张图 下面再编 今天要做的是Microbe…

使用Python编写简单网络爬虫实例:爬取图片

&#x1f34e;个人主页 &#x1f3c6;个人专栏&#xff1a;日常聊聊 ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 ​编辑 简介 步骤 1. 安装依赖库 2. 创建目录 3. 发送HTTP请求并解析页面 4. 查找图片标签并下载图片 注意事项 结语 我的其他博客 简介 网络爬虫是一种…

我的游戏被DDoS攻击了怎么办?

“我的游戏最近一直在被攻击&#xff0c;有什么办法可以解决”&#xff0c;最近遇到不少用户来问德迅云安全提到了自己目前遇到的这个攻击问题&#xff0c;询问有没有什么好的解决办法&#xff1f; 那遇到用户反馈的DDOS攻击&#xff0c;德迅云安全是怎么做的。 很多用户现在遇…