zip解压及zip炸弹的防御

解压功能验证正常,zip炸弹防御部分还没验证完,后续验证后再确认

    private static final int MAX_COUNT = 10000;
    // 注意,long类型后面要加L
    private static final long MAX_SIZE = 4L * 1024 * 1024 * 1024;
    private static final int PATH_LENGTH = 512;

    /**
     *  zip解压及zip炸弹的防御
     *   防御要点:1.校验解压后文件大小 2.校验解压后的条目总数 3.解压时防止跨目录攻击
     *   4.校验解压文件路径 5.校验文件路径长度
     * @param zipFilePath
     */
    public static void unzip(String zipFilePath) throws Exception {
        InputStream inputStream = null;
        FileOutputStream fileOutputStream = null;
        // 判断是否zip文件
        if (!isZipFile(zipFilePath)) {
            return;
        }
        // 创建解压文件存放目录
        File file = new File("D:\\unzip");
        if (!file.exists()) {
            file.mkdirs();
        }
        // 使用ZipFile获得解压文件对象,第二个参数是编码
        ZipFile zipFile = new ZipFile(zipFilePath, Charset.forName("GBK"));
        // 用Enumeration接收压缩文件中的每一个条目(目录或文件)
        Enumeration<? extends ZipEntry> zipEntries = zipFile.entries();
        // 统计条目数量
        int count = 0;
        // 统计解压文件大小
        long size = 0L;
        // 遍历zipEntries
        while (zipEntries.hasMoreElements()) {
            // 校验zip解压条目总数
            if (++count > MAX_COUNT) {
                //TODO delete unzip files
                return;
            }
            // 获得压缩文件中此次的条目
            ZipEntry zipEntry = zipEntries.nextElement();
            size += zipEntry.getSize();
            // 校验解压后的文件大小
            if (size > MAX_SIZE) {
                // TODO delete unzip files
                return;
            }
            // 获取此条目(文件或目录)的路径
            String path = "D:\\unzip\\" + zipEntry.getName();
            // 校验文件路径长度
            if (path.length() > PATH_LENGTH) {
                // TODO delete unzip file
                return;
            }
            // 判断解压文件路径是否合法
            if (!isLegalPath(path)) {
                // TODO delete unzip files
                return;
            }
            // 是目录则创建文件夹,是文件则用流读写出来
            LOG.info("判断是文件夹还是文件");
            if (zipEntry.isDirectory()) {
                LOG.info("是文件夹");
                new File(path).mkdirs();
            } else {
                try {
                    LOG.info("开始用流读写文件");
                    inputStream = zipFile.getInputStream(zipEntry);
                    fileOutputStream = new FileOutputStream(path);
                    byte[] data = new byte[8 * 1024];
                    int num = -1;
                    while ((num = inputStream.read(data)) != -1) {
                        fileOutputStream.write(data, 0, num);
                    }
                } finally {
                    if (fileOutputStream != null) {
                        fileOutputStream.close();
                    }
                    if (inputStream != null) {
                        inputStream.close();
                    }
                }
            }
        }
    }

    /**
     * 判断是否是zip文件
     * @param zipFilePath
     * @return
     */
    private static boolean isZipFile(String zipFilePath) {
        if (zipFilePath == null) {
            return false;
        }
        File file = new File(zipFilePath);
        if (file.exists() && file.getName().endsWith("zip")) {
            return true;
        }
        return false;
    }

    /**
     *  判断解压文件路径是否合法
     * @param path
     * @return
     */
    private static boolean isLegalPath(String path) throws Exception {
        if (path == null) {
            return false;
        }
        if (new File(path).getCanonicalPath().startsWith("D:\\unzip\\")) {
            return true;
        }
        return false;
    }

修正后删除本句话

原文地址:https://www.cnblogs.com/hello4world/p/12227391.html

时间: 2024-11-05 21:49:57

zip解压及zip炸弹的防御的相关文章

linux 打包 解压 tar zip tgz

.tar 解包:tar xvf FileName.tar 打包:tar cvf FileName.tar DirName (注:tar是打包,不是压缩!) --------------------------------------------- .gz 解压1:gunzip FileName.gz 解压2:gzip -d FileName.gz 压缩:gzip FileName .tar.gz 解压:tar zxvf FileName.tar.gz 压缩:tar zcvf FileName.t

liux之我用过的zip解压命令

用途说明 zip文件是一种常用的压缩文件格式,WinZip.WinRar等压缩软件都支持zip文件格式,就连java的jar包也是zip格式 的,Firefox插件xpi文件也是zip格式的.Linux在zip文件上的支持也是很周到的,它提供了zip.unzip和zcat等命令来支持. 本文的主题是讲一下使用unzip命令来解压zip格式的压缩文件.当我们需要把Windows上的很多文件(比如一个目录中的所有文件)上传到 Linux时,可以先把这些文件打包到一个zip文件中,然后再上传,再在Li

C# .NET 使用第三方类库DotNetZip解压/压缩Zip文件 (ZT)

DotNetZip on CodePlex: http://dotnetzip.codeplex.com/ 详细的可以看源代码--总之感觉比SharpZipLib好用.而且DotNetZip支持VB,C#以及任何.NET语言. 加压:(从CodePlex上偷过来的) using (ZipFile zip = new ZipFile()) { // add this map file into the "images" directory in the zip archive 把这个PN

CentOS7下zip解压和unzip压缩文件

1.安装zip.unzip应用. yum install zip unzip 2.压缩和解压文件 以下命令均在/home目录下操作 cd /home #进入/home目录 a.把/home目录下面的mydata目录压缩为mydata.zip zip -r mydata.zip mydata #压缩mydata目录 b.把/home目录下面的mydata.zip解压到mydatabak目录里面 unzip mydata.zip -d mydatabak c.把/home目录下面的abc文件夹和12

windows下tomcat zip解压版安装方法

下面记录一下在win7(32位)系统下,安装zip解压版的方法: 一.下载zip压缩包 地址:http://tomcat.apache.org/download-80.cgi 二.解压 我把解压包解压放在了D盘下,具体的路径是:D:\Java IDE\apache-tomcat-8.0.39 三.配置jdk到tomcat 在tomcat安装目录下的bin目录中有startup.bat和shutdown.bat这两个文件, 都使用记事本打开,在第一行"@echo off"的下一行追加新行

[转]unzip解压windows zip乱码的处理

[转]unzip解压windows zip乱码的处理 http://blog.sina.com.cn/s/blog_6c9d65a101012gz0.html 朋友从windows传过来的zip文件,我解压之后就乱码,很郁闷. 之前有一个方法,用命令行把文件的编码变成utf8,之后再解压或解压后再转. 具体方法:http://blog.sina.com.cn/s/blog_6c9d65a10100nev8.html 不过很麻烦,今天找到一个更快捷的方法: unzip -O 字符集   xxx.z

C# .NET 使用第三方类库DotNetZip解压/压缩Zip文件

dotNetZip on CodePlex: http://dotnetzip.codeplex.com/ 详细的可以看源代码……总之感觉比SharpZipLib好用.而且DotNetZip支持VB,C#以及任何.NET语言. 加压:(从CodePlex上偷过来的) using (ZipFile zip = new ZipFile()) { // add this map file into the "images" directory in the zip archive 把这个PN

20140220-MySQL的安装(使用zip解压绿色安装方式)

20140220-MySQL的安装(使用zip解压绿色安装方式) 谷歌输入MySQL可以直接找到官网的下载地址.下载绿色版. 选择:MySQL Community Server. 如果你已经安装了MySQL可以先执行: (1)停止MySQL的服务:net stop mysql(不需要分号) (2)移除MySQL的服务:mysqld remove(不需要分号) 安装步骤 1.将压缩包解压,复制到指定位置: 2.添加环境变量: 将以下目录添加到环境变量path中:F:\app\mysql-5.6.1

linux ubuntu12.04 解压中文zip文件,解压之后乱码

在windows下压缩后的zip包,在ubuntu下解压后显示为乱码问题 1.zip文件解压之后文件名乱码: 第一步 首先安装7zip和convmv(如果之前没有安装的话) 在命令行执行安装命令如下: sudo apt-get install p7zip-full convmv 第二步 假设zip文件名为y05文档.zip,那么先进入zip文件所在的目录,然后命令行执行 LANG=C 7z x y05文档.zip convmv -f cp936 -t utf8 -r --notest * 2.文