DoS Decompression Bomb

ID

go.dos_decompression_bomb

Severity

critical

Resource

Resource Management

Language

Go

Tags

CWE:409, NIST.SP.800-53, OWASP:2021:A4, PCI-DSS:6.5.6

Description

A decompression bomb is a type of denial-of-service (DoS) attack where a small compressed file is crafted to decompress into a very large file, consuming excessive system resources and potentially crashing the application or system.

Rationale

Decompression bombs exploit the disproportionate resource usage between compressed data size and decompressed data size.

In Go, using packages like compress/zlib without proper limits can lead to such vulnerabilities. Here’s an example demonstrating improper handling:

package main

import (
    "compress/zlib"
    "io"
    "os"
)

func processCompressedData(b io.Reader) {
    r, err := zlib.NewReader(b)
    if err != nil {
        panic(err)
    }
    defer r.Close()

    _, err = io.Copy(os.Stdout, r) // FLAW: No size limit leads to potential decompression bomb
    if err != nil {
        panic(err)
    }
}

In this example, decompressing data without size constraints can exhaust memory or disk resources, causing denial of service.

Remediation

  1. Set Limits: Always set limits on the size of data being decompressed. Use a controlled buffer to manage memory consumption.

  2. Monitor Resource Usage: Implement resource monitoring to detect unusual consumption patterns indicative of decompression attacks.

  3. Validate Input: Perform validation on compressed data, ensuring integrity and expected compression ratios.

  4. Use Specialized Libraries: Consider using libraries that offer built-in protections against decompression bombs.

By implementing these strategies, the risk of decompression bomb attacks can be effectively mitigated in Go applications.

The remediation example would look like this:

package main

import (
    "compress/zlib"
    "io"
    "os"
)

func processCompressedData(b io.Reader) {
    r, err := zlib.NewReader(b)
    if err != nil {
        panic(err)
    }
    defer r.Close()

    _, err = io.CopyN(os.Stdout, r, 2048) // Set N accordingly to your resources
    if err != nil {
        panic(err)
    }
}

References

  • CWE-409 : Improper Handling of Highly Compressed Data (Data Amplification).