Every CVE Search/ Get API key

CVE-2026-106118

ImageSharp: Tiled fax TIFF: tile buffer sized by TileWidth but fax decompressor writes scanlines of ImageWidth — heap OOB write

7.5 HighFix available

ImageSharp is a 2D graphics library. From 3.0.0 until 4.1.1, tiled TIFF decoding allocates a destination buffer using TileWidth but TiffDecompressorsFactory.Create constructs T4, T6, and Modified Huffman decompressors using the full frame width. TiffDecoderCore.DecodeTilesChunky can therefore direct frame-width fax scanlines into a tile-width buffer when TileWidth is smaller than ImageWidth. The mismatch causes attacker-controlled out-of-bounds writes, heap corruption, and process termination even with legal per-row run codes. This tiled-path vulnerability is distinct from oversized CCITT runs in strip decoding. This issue is fixed in version 4.1.1.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
None
User interaction
None

What an attacker can affect

Confidentiality
None
Integrity
None
Availability
High

Exploit likelihood

0.60%Unchanged since Oct 7, 2026
90%50%10%1%

What each source reports

CVE List Score used 7.5

ImageSharp: Tiled fax TIFF: tile buffer sized by TileWidth but fax decompressor writes scanlines of ImageWidth — heap OOB write

ImageSharp is a 2D graphics library. From 3.0.0 until 4.1.1, tiled TIFF decoding allocates a destination buffer using TileWidth but TiffDecompressorsFactory.Create constructs T4, T6, and Modified Huffman decompressors using the full frame width. TiffDecoderCore.DecodeTilesChunky can therefore direct frame-width fax scanlines into a tile-width buffer when TileWidth is smaller than ImageWidth. The mismatch causes attacker-controlled out-of-bounds writes, heap corruption, and process termination even with legal per-row run codes. This tiled-path vulnerability is distinct from oversized CCITT runs in strip decoding. This issue is fixed in version 4.1.1.

Record
CVE-2026-106118
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-787
Updated
2026-11-02
EUVDEUVD-2026-93770 7.5

ImageSharp is a 2D graphics library. From 3.0.0 until 4.1.1, tiled TIFF decoding allocates a destination buffer using TileWidth but TiffDecompressorsFactory.Create constructs T4, T6, and Modified Huffman decompressors using the full frame width. TiffDecoderCore.DecodeTilesChunky can therefore direct frame-width fax scanlines into a tile-width buffer when TileWidth is smaller than ImageWidth. The mismatch causes attacker-controlled out-of-bounds writes, heap corruption, and process termination even with legal per-row run codes. This tiled-path vulnerability is distinct from oversized CCITT runs in strip decoding. This issue is fixed in version 4.1.1.

Record
EUVD-2026-93770
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Updated
2026-11-02
GitHub AdvisoriesGHSA-v76p-62qx-wwq2 7.5

ImageSharp: Tiled fax TIFF: tile buffer sized by TileWidth but fax decompressor writes scanlines of ImageWidth — heap OOB write

Summary

When decoding a tiled TIFF with fax compression (T4/T6/MH), DecodeTilesChunky allocates each tile buffer from TileWidth (ceil(TileWidth*bpp/8)*TileLength bytes) but constructs the fax decompressor with frame.Width: TiffDecompressorsFactory ignores the isTiled/tileWidth/tileHeight parameters entirely. The T4/T6/MH decompressors treat the full image width as the scanline length and advance (and really write, via read-modify-write bit ops) frame.Width bits per row, with no bounds check against the tile buffer. The very first tile therefore writes linearly out of bounds — about ImageWidth/8 bytes per row × TileLength rows into a TileWidth-sized buffer. With ImageWidth=4,000,000, TileWidth=16, TileLength=16 this writes ~2 MB past a 32-byte buffer and kills the process deterministically; a T6 all-white variant advances the bit offset by >512 MB silently, showing an alarm-free heap-corruption window for the same defect. A crafted file fully controls the OOB length per tile and works with perfectly legal per-row run codes (no overlong runs needed).

Verified at commit 5cd4d0d26a82a9549f297a237aea9cf665bddff8 (main; latest release v4.1.0, the supported major).

Details

Root cause: a size mismatch between tile buffer allocation and decompressor width, because the factory drops the tile parameters.

  • Allocation: TiffDecoderCore.cs#L792-L794 — bytesPerTileRow = RoundUpToMultipleOfEight(tileWidth*bitsPerPixel); tile buffer = bytesPerTileRow*tileLength bytes (32 bytes in the PoC)
  • Mismatch: TiffDecoderCore.cs#L797 — CreateDecompressor<TPixel>(frame.Width, ..., isTiled: true, tileWidth, tileLength) passes the full frame width
  • Factory drops tile params: TiffDecompressorsFactory.cs#L56-L64 — T4/T6/MH decompressors receive only width (= frame.Width); isTiled/tileWidth/tileHeight ignored
  • OOB write sink: T4TiffCompression.cs#L69-L119, T6TiffCompression.cs#L76-L108 — per-row advance of this.width bits via BitWriterUtils.WriteBits with no buffer-length check (BitWriterUtils.cs#L51); note TiffDecoderCore.cs:829-831 later reads the buffer in bytesPerTileRow strides, confirming the protocol expects tile-width rows

Attack surface: Image.Load(stream) on an attacker-supplied tiled TIFF (TiffDecoderCore.DecodeImageWithTiles → DecodeTilesChunky). Default configuration; only requirement is a standard tiled TIFF header (TileWidth=16, TileLength=16) + Compression=3 (T4; T6 also constructible).

Suggested remediation:

  1. Short-term: when isTiled, construct the T4/T6/MH decompressor with tileWidth (not frame width), or clip row writes to the caller-provided buffer length.
  2. Root fix: bound the write side of BitWriterUtils (pass remaining bits), and validate every fax row advance against buffer capacity on both tiled and strip paths.
  3. Regression tests: Compression=2/3/4 × tiled with TileWidth < ImageWidth, including a T6 black-pixel row (forces real WriteBit).

PoC

Full PoC posted as the first comment below: Program.cs (driver), poc-tiled-t4.tif (crafted file, ~9.8 KB, base64 inline), README.

  1. Build a small console project referencing src/ImageSharp/ImageSharp.csproj and run it against…
Record
GHSA-v76p-62qx-wwq2
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-787
Updated
2026-11-02
NVD 7.5

ImageSharp is a 2D graphics library. From 3.0.0 until 4.1.1, tiled TIFF decoding allocates a destination buffer using TileWidth but TiffDecompressorsFactory.Create constructs T4, T6, and Modified Huffman decompressors using the full frame width. TiffDecoderCore.DecodeTilesChunky can therefore direct frame-width fax scanlines into a tile-width buffer when TileWidth is smaller than ImageWidth. The mismatch causes attacker-controlled out-of-bounds writes, heap corruption, and process termination even with legal per-row run codes. This tiled-path vulnerability is distinct from oversized CCITT runs in strip decoding. This issue is fixed in version 4.1.1.

Record
CVE-2026-106118
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-787
Updated
2026-11-02
OSV 7.5

ImageSharp: Tiled fax TIFF: tile buffer sized by TileWidth but fax decompressor writes scanlines of ImageWidth — heap OOB write

ImageSharp is a 2D graphics library. From 3.0.0 until 4.1.1, tiled TIFF decoding allocates a destination buffer using TileWidth but TiffDecompressorsFactory.Create constructs T4, T6, and Modified Huffman decompressors using the full frame width. TiffDecoderCore.DecodeTilesChunky can therefore direct frame-width fax scanlines into a tile-width buffer when TileWidth is smaller than ImageWidth. The mismatch causes attacker-controlled out-of-bounds writes, heap corruption, and process termination even with legal per-row run codes. This tiled-path vulnerability is distinct from oversized CCITT runs in strip decoding. This issue is fixed in version 4.1.1.

Record
CVE-2026-106118
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-787
Updated
2026-11-02
OSVGHSA-v76p-62qx-wwq2 7.5

ImageSharp: Tiled fax TIFF: tile buffer sized by TileWidth but fax decompressor writes scanlines of ImageWidth — heap OOB write

Summary

When decoding a tiled TIFF with fax compression (T4/T6/MH), DecodeTilesChunky allocates each tile buffer from TileWidth (ceil(TileWidth*bpp/8)*TileLength bytes) but constructs the fax decompressor with frame.Width: TiffDecompressorsFactory ignores the isTiled/tileWidth/tileHeight parameters entirely. The T4/T6/MH decompressors treat the full image width as the scanline length and advance (and really write, via read-modify-write bit ops) frame.Width bits per row, with no bounds check against the tile buffer. The very first tile therefore writes linearly out of bounds — about ImageWidth/8 bytes per row × TileLength rows into a TileWidth-sized buffer. With ImageWidth=4,000,000, TileWidth=16, TileLength=16 this writes ~2 MB past a 32-byte buffer and kills the process deterministically; a T6 all-white variant advances the bit offset by >512 MB silently, showing an alarm-free heap-corruption window for the same defect. A crafted file fully controls the OOB length per tile and works with perfectly legal per-row run codes (no overlong runs needed).

Verified at commit 5cd4d0d26a82a9549f297a237aea9cf665bddff8 (main; latest release v4.1.0, the supported major).

Details

Root cause: a size mismatch between tile buffer allocation and decompressor width, because the factory drops the tile parameters.

  • Allocation: TiffDecoderCore.cs#L792-L794 — bytesPerTileRow = RoundUpToMultipleOfEight(tileWidth*bitsPerPixel); tile buffer = bytesPerTileRow*tileLength bytes (32 bytes in the PoC)
  • Mismatch: TiffDecoderCore.cs#L797 — CreateDecompressor<TPixel>(frame.Width, ..., isTiled: true, tileWidth, tileLength) passes the full frame width
  • Factory drops tile params: TiffDecompressorsFactory.cs#L56-L64 — T4/T6/MH decompressors receive only width (= frame.Width); isTiled/tileWidth/tileHeight ignored
  • OOB write sink: T4TiffCompression.cs#L69-L119, T6TiffCompression.cs#L76-L108 — per-row advance of this.width bits via BitWriterUtils.WriteBits with no buffer-length check (BitWriterUtils.cs#L51); note TiffDecoderCore.cs:829-831 later reads the buffer in bytesPerTileRow strides, confirming the protocol expects tile-width rows

Attack surface: Image.Load(stream) on an attacker-supplied tiled TIFF (TiffDecoderCore.DecodeImageWithTiles → DecodeTilesChunky). Default configuration; only requirement is a standard tiled TIFF header (TileWidth=16, TileLength=16) + Compression=3 (T4; T6 also constructible).

Suggested remediation:

  1. Short-term: when isTiled, construct the T4/T6/MH decompressor with tileWidth (not frame width), or clip row writes to the caller-provided buffer length.
  2. Root fix: bound the write side of BitWriterUtils (pass remaining bits), and validate every fax row advance against buffer capacity on both tiled and strip paths.
  3. Regression tests: Compression=2/3/4 × tiled with TileWidth < ImageWidth, including a T6 black-pixel row (forces real WriteBit).

PoC

Full PoC posted as the first comment below: Program.cs (driver), poc-tiled-t4.tif (crafted file, ~9.8 KB, base64 inline), README.

  1. Build a small console project referencing src/ImageSharp/ImageSharp.csproj and run it against…
Record
GHSA-v76p-62qx-wwq2
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-787
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
SixLabors.ImageSharp
NuGet
3.0.0 up to 3.2.0
3.2.0
SixLabors.ImageSharp
NuGet
4.0.0 up to 4.1.1
4.1.1
SixLabors.ImageSharp
NuGet
3.0.0 up to 3.2.0, plus listed versions
3.0.13.0.23.1.03.1.13.1.10
Show 10 moreShow less
3.1.113.1.123.1.23.1.33.1.43.1.53.1.63.1.73.1.83.1.9
3.2.0
SixLabors.ImageSharp
NuGet
4.0.0 up to 4.1.1, plus listed versions
4.1.0
4.1.1

History

History
RecordedChangedSources
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-106118 is a high vulnerability (CVSS 7.5) in Sixlabors Imagesharp, published October 6, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.60%, the 48th percentile. Fixed in SixLabors.ImageSharp 3.2.0.

References

Show 5 moreShow less
This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open