From 47cba89085995d7181460cd8ab27a763e5934bef Mon Sep 17 00:00:00 2001 From: Looly Date: Thu, 20 Jul 2023 08:19:06 +0800 Subject: [PATCH] =?UTF-8?q?ZipReader=E5=A2=9E=E5=8A=A0setMaxSizeDiff?= =?UTF-8?q?=E6=96=B9=E6=B3=95=EF=BC=8C=E8=87=AA=E5=AE=9A=E4=B9=89=E6=88=96?= =?UTF-8?q?=E5=85=B3=E9=97=ADZipBomb?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 5 ++-- .../cn/hutool/core/compress/ZipReader.java | 25 ++++++++++++++++--- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index af4e19b8c..9e2ef8b19 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ # 🚀Changelog ------------------------------------------------------------------------------------------------------------- -# 5.8.21(2023-07-19) +# 5.8.21(2023-07-20) ### 🐣新特性 * 【core 】 list 为空时,CollUtil.max等返回null而非异常(pr#1027@Gitee) @@ -12,7 +12,8 @@ * 【core 】 RandomUtil增加可选是否包含边界的重载(issue#3182@Github) * 【core 】 StrUtil增加truncateByByteLength方法(pr#3176@Github) * 【core 】 身份证工具类isValidCard18、isValidCard15入参null直接返回null(pr#1034@Gitee) -* 【http 】 使用multiparty方式支持body参数(issue#3158@Gitee) +* 【http 】 使用multiparty方式支持body参数(issue#3158@Github) +* 【core 】 ZipReader增加setMaxSizeDiff方法,自定义或关闭ZipBomb(issue#3018@Github) ### 🐞Bug修复 * 【core 】 修复MapUtil工具使用filter方法构造传入参数结果问题(issue#3162@Github) diff --git a/hutool-core/src/main/java/cn/hutool/core/compress/ZipReader.java b/hutool-core/src/main/java/cn/hutool/core/compress/ZipReader.java index 4fd03d4f4..f7b461a05 100755 --- a/hutool-core/src/main/java/cn/hutool/core/compress/ZipReader.java +++ b/hutool-core/src/main/java/cn/hutool/core/compress/ZipReader.java @@ -28,10 +28,14 @@ import java.util.zip.ZipInputStream; public class ZipReader implements Closeable { // size of uncompressed zip entry shouldn't be bigger of compressed in MAX_SIZE_DIFF times - private static final int MAX_SIZE_DIFF = 100; + private static final int DEFAULT_MAX_SIZE_DIFF = 100; private ZipFile zipFile; private ZipInputStream in; + /** + * 检查ZipBomb文件差异倍数,-1表示不检查ZipBomb + */ + private int maxSizeDiff = DEFAULT_MAX_SIZE_DIFF; /** * 创建ZipReader @@ -93,6 +97,18 @@ public class ZipReader implements Closeable { this.in = zin; } + /** + * 设置检查ZipBomb文件差异倍数,-1表示不检查ZipBomb + * + * @param maxSizeDiff 检查ZipBomb文件差异倍数,-1表示不检查ZipBomb + * @return this + * @since 6.0.0 + */ + public ZipReader setMaxSizeDiff(final int maxSizeDiff) { + this.maxSizeDiff = maxSizeDiff; + return this; + } + /** * 获取指定路径的文件流
* 如果是文件模式,则直接获取Entry对应的流,如果是流模式,则遍历entry后,找到对应流返回 @@ -235,7 +251,10 @@ public class ZipReader implements Closeable { * @param entry {@link ZipEntry} * @return 检查后的{@link ZipEntry} */ - private static ZipEntry checkZipBomb(ZipEntry entry) { + private ZipEntry checkZipBomb(ZipEntry entry) { + if(maxSizeDiff < 0){ + return entry; + } if (null == entry) { return null; } @@ -243,7 +262,7 @@ public class ZipReader implements Closeable { final long uncompressedSize = entry.getSize(); if (compressedSize < 0 || uncompressedSize < 0 || // 默认压缩比例是100倍,一旦发现压缩率超过这个阈值,被认为是Zip bomb - compressedSize * MAX_SIZE_DIFF < uncompressedSize) { + compressedSize * maxSizeDiff < uncompressedSize) { throw new UtilException("Zip bomb attack detected, invalid sizes: compressed {}, uncompressed {}, name {}", compressedSize, uncompressedSize, entry.getName()); }