🇰🇷 한글 설명
CompressionFilter 클래스가 ZLib를 사용하여 데이터를 압축 해제할 때 결과물의 크기를 제어하지 않아 발생하는 취약점입니다. 압축률이 매우 높은 악성 데이터를 전송할 경우 애플리케이션의 메모리가 고갈되어 서비스 거부(DoS) 상태에 빠질 수 있습니다.
💡 쉬운 설명
압축된 파일을 풀었을 때 원래 크기가 엄청나게 커지는 '압축 폭탄' 공격에 취약합니다. 이로 인해 컴퓨터의 메모리가 가득 차서 프로그램이 멈출 수 있습니다.
🇺🇸 원문 (English)
The CompressionFilter class uses ZLib to deflate and inflate data sent and received. When we inflate incoming data, the filter does not control the resulting size, and create a buffer no matter what.
Some compressed data may have a compression ration greater than 1 thousand, leading to an exhaustion of the application memory, as we don't control the deflated size.
The fix adds such a control by allowing the application developer to provide a fixed size limit, which when reached throws an exception. It also allows the user to provide a compression ratio that should not be exceeded, protected the application from small inflated files that inflate in gigantic files, but with a grace limit for the resulting size (1Mb) to avoid false positive (like a very small file inflating with a high ratio, but resulting with a acceptable size, like a few thousands bytes)
For application using this feature, it is highly recommended to create the CompressionFilter and to pass the maximum limit as a forth constructor parameter, maxDecompressedSize:
public CompressionFilter(final boolean compressInbound, final boolean compressOutbound, final int compressionLevel, final int maxDecompressedSize)Optionally one can also provide a maxDecompressRatio fifth parameter, and a decompressRatioMinSize sixth parameter to allow small inflated files with a high compression ratio to still be accepted.
Here are the additional constructor:
public CompressionFilter(final boolean compressInbound, final boolean compressOutbound,
final int compressionLevel, final int maxDecompressedSize,
final long maxDecompressRatio, final long decompressRatioMinSize)
Also note that a fluent API has been added to spare the users the pain to call a constructor with that many parameters:
CompressionFilter compressionFilter = new CompressionFilter()
.setCompressionLevel(Zlib.COMPRESSION_MAX)
.setMaxDecompressedSize(1_000_000)
.setMaxDecompressRatio(100).
.setDecompressRatioMinSize(100_000);
Applications using Apache MINA are advised to upgrade and configure their CompressionFilter instance.
📍 영향받는 시스템
Apache MINA (CompressionFilter를 사용하는 버전)
⚔️ 공격 벡터
압축 해제 시 메모리 고갈을 유도하는 높은 압축률을 가진 악성 데이터를 전송하여 공격
🛡️ 대응 방법
Apache MINA를 최신 버전으로 업그레이드하고, CompressionFilter 생성 시 maxDecompressedSize 등의 제한 파라미터를 설정하여 사용
🔧 검증 코드
출력된 결과에서 사용 중인 Apache MINA의 버전을 확인하여 취약한 버전인지 판단
mvn dependency:list | grep mina