This is an automated email from the ASF dual-hosted git repository.

pjfanning pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/poi.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 7607d1bbee Apply zip bomb checks to encrypted temp ZIP processing 
(#1057)
7607d1bbee is described below

commit 7607d1bbeeef45f5bb2c7492e1c41d153dfa78ee
Author: jmestwa-coder <[email protected]>
AuthorDate: Tue May 12 01:58:33 2026 +0530

    Apply zip bomb checks to encrypted temp ZIP processing (#1057)
---
 .../util/ZipArchiveThresholdInputStream.java       |  2 +-
 .../poifs/crypt/temp/AesZipFileZipEntrySource.java |  4 ++-
 .../poi/poifs/crypt/tests/TestSecureTempZip.java   | 41 ++++++++++++++++++++++
 3 files changed, 45 insertions(+), 2 deletions(-)

diff --git 
a/poi-ooxml/src/main/java/org/apache/poi/openxml4j/util/ZipArchiveThresholdInputStream.java
 
b/poi-ooxml/src/main/java/org/apache/poi/openxml4j/util/ZipArchiveThresholdInputStream.java
index 65e79b1f39..6949404c8d 100644
--- 
a/poi-ooxml/src/main/java/org/apache/poi/openxml4j/util/ZipArchiveThresholdInputStream.java
+++ 
b/poi-ooxml/src/main/java/org/apache/poi/openxml4j/util/ZipArchiveThresholdInputStream.java
@@ -148,7 +148,7 @@ public class ZipArchiveThresholdInputStream extends 
FilterInputStream {
         throw new IOException(String.format(Locale.ROOT, 
MIN_INFLATE_RATIO_MSG, payloadSize, rawSize, ratio, MIN_INFLATE_RATIO, 
entryName));
     }
 
-    ZipArchiveEntry getNextEntry() throws IOException {
+    public ZipArchiveEntry getNextEntry() throws IOException {
         if (!(in instanceof ZipArchiveInputStream)) {
             throw new IllegalStateException("getNextEntry() is only allowed 
for stream based zip processing.");
         }
diff --git 
a/poi-ooxml/src/main/java/org/apache/poi/poifs/crypt/temp/AesZipFileZipEntrySource.java
 
b/poi-ooxml/src/main/java/org/apache/poi/poifs/crypt/temp/AesZipFileZipEntrySource.java
index f9d5b6fd2f..e748bc578c 100644
--- 
a/poi-ooxml/src/main/java/org/apache/poi/poifs/crypt/temp/AesZipFileZipEntrySource.java
+++ 
b/poi-ooxml/src/main/java/org/apache/poi/poifs/crypt/temp/AesZipFileZipEntrySource.java
@@ -39,6 +39,7 @@ import org.apache.commons.io.output.CloseShieldOutputStream;
 import org.apache.logging.log4j.Logger;
 import org.apache.poi.logging.PoiLogManager;
 import org.apache.poi.openxml4j.util.ZipEntrySource;
+import org.apache.poi.openxml4j.util.ZipArchiveThresholdInputStream;
 import org.apache.poi.poifs.crypt.ChainingMode;
 import org.apache.poi.poifs.crypt.CipherAlgorithm;
 import org.apache.poi.poifs.crypt.CryptoFunctions;
@@ -130,7 +131,8 @@ public final class AesZipFileZipEntrySource implements 
ZipEntrySource {
         SecretKeySpec skeySpec = new SecretKeySpec(keyBytes, 
CipherAlgorithm.aes128.jceId);
         Cipher ciEnc = CryptoFunctions.getCipher(skeySpec, 
CipherAlgorithm.aes128, ChainingMode.cbc, ivBytes, Cipher.ENCRYPT_MODE, 
PADDING);
 
-        try (ZipArchiveInputStream zis = new ZipArchiveInputStream(is);
+        try (ZipArchiveInputStream zipStream = new ZipArchiveInputStream(is);
+             ZipArchiveThresholdInputStream zis = new 
ZipArchiveThresholdInputStream(zipStream);
              OutputStream fos = Files.newOutputStream(tmpFile.toPath());
              ZipArchiveOutputStream zos = new ZipArchiveOutputStream(fos)) {
 
diff --git 
a/poi-ooxml/src/test/java/org/apache/poi/poifs/crypt/tests/TestSecureTempZip.java
 
b/poi-ooxml/src/test/java/org/apache/poi/poifs/crypt/tests/TestSecureTempZip.java
index 7dbbbe3d2a..90e4b018fe 100644
--- 
a/poi-ooxml/src/test/java/org/apache/poi/poifs/crypt/tests/TestSecureTempZip.java
+++ 
b/poi-ooxml/src/test/java/org/apache/poi/poifs/crypt/tests/TestSecureTempZip.java
@@ -18,9 +18,12 @@
 package org.apache.poi.poifs.crypt.tests;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.junit.jupiter.api.Assumptions.assumeTrue;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
@@ -29,9 +32,12 @@ import java.security.GeneralSecurityException;
 
 import javax.crypto.Cipher;
 
+import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
+import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
 import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
 import org.apache.poi.openxml4j.opc.OPCPackage;
 import org.apache.poi.openxml4j.util.ZipEntrySource;
+import org.apache.poi.openxml4j.util.ZipSecureFile;
 import org.apache.poi.poifs.crypt.Decryptor;
 import org.apache.poi.poifs.crypt.EncryptionInfo;
 import org.apache.poi.poifs.crypt.temp.AesZipFileZipEntrySource;
@@ -126,4 +132,39 @@ class TestSecureTempZip {
         fis.close();
     }
 
+    @Test
+    void rejectsZipBombInput() throws IOException {
+        byte[] zipBytes = buildHighlyCompressedZip("xl/workbook.xml", 256 * 
1024);
+
+        double defaultRatio = ZipSecureFile.getMinInflateRatio();
+        long defaultGrace = ZipSecureFile.getGraceEntrySize();
+        ZipSecureFile.setGraceEntrySize(0);
+        ZipSecureFile.setMinInflateRatio(0.50d);
+        try {
+            IOException exception = assertThrows(IOException.class, () -> {
+                try (InputStream is = new ByteArrayInputStream(zipBytes);
+                     AesZipFileZipEntrySource source = 
AesZipFileZipEntrySource.createZipEntrySource(is)) {
+                    // no-op
+                }
+            });
+            
assertTrue(exception.getMessage().contains("ZipSecureFile.setMinInflateRatio()"),
+                    "unexpected exception message: " + exception.getMessage());
+        } finally {
+            ZipSecureFile.setMinInflateRatio(defaultRatio);
+            ZipSecureFile.setGraceEntrySize(defaultGrace);
+        }
+    }
+
+    private static byte[] buildHighlyCompressedZip(String entryName, int 
payloadSize) throws IOException {
+        byte[] payload = new byte[payloadSize];
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        try (ZipArchiveOutputStream zos = new ZipArchiveOutputStream(bos)) {
+            ZipArchiveEntry entry = new ZipArchiveEntry(entryName);
+            zos.putArchiveEntry(entry);
+            zos.write(payload);
+            zos.closeArchiveEntry();
+        }
+        return bos.toByteArray();
+    }
+
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to