New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A wrapper to protect from decompression bombs #2339

Closed
wants to merge 1 commit into
base: master
from

Conversation

Projects
None yet
2 participants
@mikkolehtisalo
Contributor

mikkolehtisalo commented Jun 7, 2016

I tested inputs against zlib and gzip decompression bombs. The best you can probably achieve is 1:1000, and most likely 65kB -> 65MB decompressed. In my testing a steady 150 kB/s stream of messages maxed out one i7 core due the decompression, and heavily increased memory allocations and GC activity. Probably you might be able to also cause OutOfMemoryError with surprisingly small amount of simultaneously sent data, unless the amount of available memory was very high.

I wrote a simple wrapper for decompression tools. Since at least 65 kB of compressed data can reach that point, and the implementation issues are contained at Tools.decompress*, compression related issues should probably be handled there. The implementation bails at this moment out at 2 MB which is something that the next components in line will fail to handle anyways.

On ordinary message sizes there is no performance hit. On larger message sizes I got 40x+ performance boost when the decompression size limit started preventing the function from working pointlessly.

The implementation is simple, because there does not seem to be other uses for Tools.decompress* at this moment, and it did not seem useful to go for something more refined.

@mikkolehtisalo

This comment has been minimized.

Contributor

mikkolehtisalo commented Jun 8, 2016

The tests are based on test files. I tried using DeflaterOutputStream, and GZIPOutputStream on the fly, but it seemed to take ~50 seconds to run on my laptop:

    @BeforeClass
    public static void setUp() throws IOException {
        try (ByteArrayOutputStream zbaos = new ByteArrayOutputStream();
             OutputStream zout = new DeflaterOutputStream(zbaos);
             ByteArrayOutputStream gbaos = new ByteArrayOutputStream();
             OutputStream gout = new GZIPOutputStream(gbaos)) {

            // setup zlibTestData
            for (int i=1; i<(1024*1024*64); i++) {
                zout.write(0);
            }
            zlibTestData = zbaos.toByteArray();

            // setup gzipTestData
            for (int i=1; i<(1024*1024*64); i++) {
                gout.write(0);
            }
            gzipTestData = gbaos.toByteArray();
        }
    }
@joschi

This comment has been minimized.

Contributor

joschi commented Jun 13, 2016

@mikkolehtisalo Any reason you've closed this PR?

@joschi joschi closed this in 97ba566 Jul 14, 2016

@joschi

This comment has been minimized.

Contributor

joschi commented Jul 14, 2016

@mikkolehtisalo Thanks for your contribution!

I've made some modifications to the PR and merged it in 97ba566.

@joschi joschi self-assigned this Jul 14, 2016

@joschi joschi added the feature label Jul 14, 2016

@joschi joschi added this to the 2.1.0 milestone Jul 14, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment