25

When I am trying to write data to an Excel sheet, using Apache POI which contains more than 64000 records, where SXSSF is used, I am getting the below error:

Zip bomb detected! The file would exceed the max. ratio of compressed file size to the size of the expanded data. This may indicate that the file is used to inflate memory usage and thus could pose a security risk. You can adjust this limit via ZipSecureFile.setMinInflateRatio() if you need to work with files which exceed this limit. Counter: 820224, cis.counter: 8192, ratio: 0.009987515605493134Limits: MIN_INFLATE_RATIO: 0.01

I found a solution stating by adding ZipSecureFile.setMinInflateRatio(0.009), but why is it happening and what is the limit I need to provide for the above error? And where should I add the solution?

Reference for the solution: How can I determine if a Zip Bomb error thrown when retrieving an Excel files Styles Table is legitimate?

Is there another solution for this?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
user3428736
  • 864
  • 2
  • 13
  • 33
  • 1
    Sounds like you're writing a large amount of nul characters (0x00) that will compress down to (asymptotically) nothing. Examine the output stream before compression to see what is being written. If the output is correct, then you may just need to set the compression ratio limit lower than the default. – Jim Garrison Jul 04 '17 at 05:29
  • What, exactly, don't you like about the solution you already found? – Dawood ibn Kareem Jul 04 '17 at 05:30
  • what is the root cause of the issue and is it can be avoid without using this fix. I haven't used it because this error occured only in server but not in local machine and so I am curious to understand why it is happening only in server. I don't know where to add the solution and what this solution will do – user3428736 Jul 04 '17 at 05:42

3 Answers3

45

The workaround is to add this line before you open the workbook:

ZipSecureFile.setMinInflateRatio(0);
Tung Nguyen
  • 1,486
  • 2
  • 18
  • 13
  • 1
    This solution worked for me. I have used spring-boot project with Apache-Poi library. – Muhammad Bilal Aug 15 '21 at 10:07
  • 3
    An explanation would be in order. E.g., what is it supposed to do? Please respond by [editing (changing) your answer](https://stackoverflow.com/posts/50641893/edit), not here in comments (***without*** "Edit:", "Update:", or similar - the answer should appear as if it was written today). – Peter Mortensen Sep 03 '21 at 03:45
  • This is helped me thanks bro – Bexzod Xayrullayev Sep 21 '22 at 07:08
23

"Zip bomb" is a term used for an attack vector where a small zip file expands to a very large uncompressed file and thus can cause issues like exhausting memory or disk space.

Usually such zips are created with the intent of causing a denial of service attack on systems that receive zip files from external sources.

As .xlsx files are actually zipped files which contain XML files, there is a chance of causing such a zip bomb vulnerability in POI.

In order to prevent this from happening, Apache POI has some safeguards built in and enabled by default. So if you create a file with unusual content, e.g. many rows/columns with the same content, you can run into these safeguards and receive the exception as shown above.

If you fully control the creation of the processed files, you can adjust the setting given in the error message to avoid the exception.

See https://bz.apache.org/bugzilla/show_bug.cgi?id=58499 for the related issue and ZIp-bomb exception while writing a large formatted Excel (.xlsx) and How to determine if a Zip Bomb error thrown when retrieving an Excel files Styles Table is legitimate? for similar discussions.

centic
  • 15,565
  • 9
  • 68
  • 125
  • This answer is exemplary, from explanation upto solution. Just a technical solution cleaning up the XML, sharing strings and XML attributes - a cleanup -, would have topped it. Fine. – Joop Eggen Jul 04 '17 at 08:28
1

You can avoid zip bomb issues reading from an InputStream instead of reading from a File like this

File fp = new File(excelFile);
FileInputStream fpis = new FileInputStream(fp);
try {
    wb = WorkbookFactory.create(fpis);
} finally {
    fpis.close();
}

But be aware that the documentation at WorkbookFactory.create(java.io.InputStream) says that "loading from an InputStream requires more memory than loading from a File"

IgnacioHR
  • 568
  • 4
  • 20
  • Theoretically the same ZipBomb-checks should apply here as well, are you sure the checks are not done in this case? – centic Feb 16 '18 at 09:57
  • Hi, yes we are sure. The simple reason is that using a File parameter the WorkbookFactory.create method can obtain the file size and perform checks. But using the InputStream parameter the WorkbookFactory.create cannot obtain the file size. – IgnacioHR Feb 16 '18 at 11:06
  • Please check the code, actually the implementation uses a wrapper-InputStream which continuously tracks file size and uncompressed size, otherwise the zip-bomb avoiding would only be used in half of the use cases, which is not a good idea for a security related feature. – centic Feb 17 '18 at 19:36
  • Please check the code, actually the implementation uses a wrapper-InputStream which continuously tracks file size and uncompressed size, otherwise the zip-bomb avoiding would only be used in half of the use cases, which is not a good idea for a security related feature. – centic Feb 17 '18 at 19:37
  • 1
    I did not look into the code, but with poi 5.0.0 I get a zip bomb exception using input streams. Could be a feature of the new poi version, don't know. – Peter May 18 '21 at 10:42
  • this not worked and I'am used this https://stackoverflow.com/a/50641893/12782217 it is worked – Bexzod Xayrullayev Sep 21 '22 at 07:06