airlift / aircompressor

A port of Snappy, LZO, LZ4, and Zstandard to Java
Apache License 2.0
549 stars 110 forks source link

Security vulnerability: Snappy decompressor can be made to crash JVM #183

Closed ptaoussanis closed 5 months ago

ptaoussanis commented 5 months ago

Hi there!

I've tried to reach out privately a couple times without success.

Am opening a public report here now since:

  1. I believe the issue is related to one going back to 2013, so may already be known to possible attackers.
  2. Users may be able to protect themselves in the meantime if they're made aware.

I really do appreciate all the hard work on this terrific library, and realise that the maintainers might have many priorities to juggle!

Will end the report with some tiered suggestions from low->high effort.

Thanks for reading!

Vulnerability

io.airlift.compress.snappy.SnappyDecompressor is able to crash the JVM given malicious or malformed input.

This is reproducible with at least:

Steps to reproduce

  1. Generate 1024 bytes of random data.
  2. Use io.airlift.compress.snappy.SnappyDecompressor to try to decompress the random data, trapping exceptions.
  3. Repeat until you get a core dump (usu. occurs within 10k attempts).

I.e. it seems that certain patterns of random data will cause io.airlift.compress.snappy.SnappyDecompressor to crash the JVM.

This issue seems to affect only the Snappy decompressor. Zstd, LZ4, LZO, and LZMA2 all seem to be fine under the same test.

Additional context

Implications

Users of aircompressor (directly or transitively) MAY be vulnerable to JVM crashes IF BOTH:

There's at least 3 relevant scenarios that come to mind:

  1. Snappy decompression may as part of normal operation be attempted against possibly invalid data. If this happens often, a JVM crash is possible.
  2. A malicious user is able to explicitly trigger many decompression attempts against random data.
  3. A malicious user is able to explicitly trigger even a single decompression attempt against user-controlled data known to trigger crashing.

Mitigations for users

I believe that either of the following should help:

  1. Don't use aircompressor for Snappy decompression. a. Use Zstd, LZ4, LZO, and LZMA2 instead - these all seem to be safe. b. Use https://github.com/xerial/snappy-java instead - it appears to be safe.

  2. Use some mechanism for ensuring that no decompression attempts are made against unverified (esp. arbitrary user-controlled) data.

Suggested action

Some ideas sorted from low->high effort include:

Again, my sincere thanks for all the hard work on aircompressor - it's a wonderful tool and a generous thing to make available as open source.

Marcono1234 commented 5 months ago

Relates to https://github.com/trinodb/trino/issues/20566 I have used GitHub private vulnerability reporting on trinodb/trino to report there what I have found. It is also about SnappyDecompressor, but I won't share any details publicly here yet until I got a response from the maintainers.

I assume it might be the same issue you have found, but in case you have data which reproduces your crash and the maintainers notice this GitHub issue here, it might be good to share it with them as well just to make sure nothing is overlooked.

martint commented 5 months ago

Thanks for the report. I'm unable to reproduce the issue based on the steps listed above, even after more than 100 million runs. Are you able to capture and provide a the contents of the array that's causing the crash? That will it easier to diagnose and fix the problem.

ptaoussanis commented 5 months ago

@martint Hi Martin, thanks for the response. I'll follow up with the email address on your GitHub profile 👍

ptaoussanis commented 5 months ago

@martint Thanks for enabling private vulnerability reporting, I've also submitted a draft report there with more details and a reproducible example.

Would suggest adding @Marcono1234 as a collaborator there (and/or me to their report if appropriate) so that we can better coordinate efforts.

martint commented 5 months ago

This fixed in release 0.26, which should be available in Maven Central shortly