Decompression attack in `MinecraftCompressDecoder#decode`
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 2.3k
- Forks
- 959
- Avg merge
- 5d 10h
- Merged PRs (30d)
- 2
Description
Proxies of a large network I'm working for were constantly being restarted due to OOM kills. I highly suspect this is due to a malicious decompression attack.
I had added the following logs in MinecraftCompressDecoder#decode:
if (claimedUncompressedSize > UNCOMPRESSED_CAP * 0.95) {
LOGGER.warn("Received a packet with a large uncompressed size: {} bytes ({}% of the {} byte cap) from {}",
claimedUncompressedSize,
(int) (claimedUncompressedSize * 100.0 / UNCOMPRESSED_CAP),
UNCOMPRESSED_CAP,
ctx.channel().remoteAddress());
}
When we were under attack we got spammed by the following logs:
[17:36:45 WARN]: Received a packet with a large uncompressed size: 8380416 bytes (99% of the 8388608 byte cap) from /x.x.x.x:16643
All from the same IP address, all with the same packet size. Moments later the proxy got OOM killed.
When we blacklisted this IP at the firewall level the proxies stayed alive.
I've implemented the following fix on a fork to try to block these kinds of attacks, at least on the short term: https://github.com/GemstoneGG/Velocity-CTD/commit/3fd2f11b3b35d066f2ee064e1f4b7c785b709997
However the limits (0.95 * UNCOMPRESSED_CAP and MAX_COMPRESSION_RATIO = 1024) are not really based on anything. Since we're running the fork with this commit we haven't been attacked again, so I'm not sure if the commit prevents the attack. Luckily, legitimate connections aren't being affected.
-Dvelocity.increased-compression-cap=true is NOT set, so the UNCOMPRESSED_CAP is 8MB.
Decompressing a really small packet to 8MB over and over again ideally shouldn't OOM kill a proxy. I wonder if the proper fix for this is a "rate-limiter" approach like in my temporary-ish fix commit, or to take a closer look at why allocating "just" 8MB constantly gets an OOM kill. Something might be going wrong with (de)allocating this buffer.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with MinecraftCompressDecoder#decode and compare its behavior with the proposed fork commit 3fd2f11b3b35d066f2ee064e1f4b7c785b709997. Investigate repeated small packets claiming near the 8 MB uncompressed cap, including allocation and release behavior. Done means the proxy no longer risks OOM under this attack while legitimate compressed connections remain unaffected.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- networking
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100