CVE-2026-106117
ImageSharp: CCITT fax decompression (T4/Modified Huffman): unbounded WriteBits overflows strip buffer — heap OOB write in SixLabors.ImageSharp
ImageSharp is a 2D graphics library. From 3.0.0 until 4.1.1, decoding a strip TIFF using CCITT Group 3 or Modified Huffman compression can pass attacker-expanded runs to BitWriterUtils.WriteBits without first checking the current row width. T4TiffCompression.WritePixelRun can accumulate oversized makeup-code runs, and ModifiedHuffmanTiffCompression.Decompress validates the width only after writing. The unchecked writes can overflow the strip buffer, corrupt heap memory, and terminate the process. This strip-path vulnerability is distinct from the tiled decompressor-width mismatch. 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
What each source reports
CVE List Score used
7.5
ImageSharp: CCITT fax decompression (T4/Modified Huffman): unbounded WriteBits overflows strip buffer — heap OOB write in SixLabors.ImageSharp
ImageSharp is a 2D graphics library. From 3.0.0 until 4.1.1, decoding a strip TIFF using CCITT Group 3 or Modified Huffman compression can pass attacker-expanded runs to BitWriterUtils.WriteBits without first checking the current row width. T4TiffCompression.WritePixelRun can accumulate oversized makeup-code runs, and ModifiedHuffmanTiffCompression.Decompress validates the width only after writing. The unchecked writes can overflow the strip buffer, corrupt heap memory, and terminate the process. This strip-path vulnerability is distinct from the tiled decompressor-width mismatch. This issue is fixed in version 4.1.1.
- Record
CVE-2026-106117- CVSS 3.1
- 7.5 High
CVSS: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-93560
7.5
ImageSharp is a 2D graphics library. From 3.0.0 until 4.1.1, decoding a strip TIFF using CCITT Group 3 or Modified Huffman compression can pass attacker-expanded runs to BitWriterUtils.WriteBits without first checking the current row width. T4TiffCompression.WritePixelRun can accumulate oversized makeup-code runs, and ModifiedHuffmanTiffCompression.Decompress validates the width only after writing. The unchecked writes can overflow the strip buffer, corrupt heap memory, and terminate the process. This strip-path vulnerability is distinct from the tiled decompressor-width mismatch. This issue is fixed in version 4.1.1.
- Record
EUVD-2026-93560- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-jj3q-cwqj-842r
7.5
ImageSharp: CCITT fax decompression (T4/Modified Huffman): unbounded WriteBits overflows strip buffer — heap OOB write in SixLabors.ImageSharp
Summary
When decoding a fax-compressed strip TIFF (Compression=3 / Group 3 1D, or Compression=2 / Modified Huffman), the CCITT decompressors write decoded runs through BitWriterUtils.WriteBits/WriteBit/WriteZeroBit, which advance and write bits via Unsafe.Add with read-modify-write semantics — without ever comparing the write position against the target buffer length. The strip buffer is sized ImageWidth × RowsPerStrip (8 bytes in the PoC), but two independent defects let an attacker write tens of millions of bits past it: (a) T4 only increments rowsWritten when an EOL code is read, and one ReadNextRun accumulates unlimited makeup codes (+2560 px per 12-bit code) into a single RunLength that WritePixelRun then writes in one shot; (b) Modified Huffman writes before validating (pixelsWritten > Width is checked at :90-93, after the write at :56-63), so the overflow completes even though an exception is thrown later. One crafted ~90 KB file writes ~19.2 MB linearly past an 8-byte buffer and deterministically kills the process; the write offset and length are fully attacker-controlled (classic heap-corruption primitive on the managed heap).
Verified at commit 5cd4d0d26a82a9549f297a237aea9cf665bddff8 (main; latest release v4.1.0, the supported major). A related tiled-path variant (tile-buffer width mismatch) was reported separately as GHSA-v76p-62qx-wwq2 — this report covers the distinct strip-path root cause.
Details
Root cause: the bit-writing sink has no bounds check, and neither decompressor constrains run lengths against the strip buffer.
- Unchecked write primitive: BitWriterUtils.cs#L51 (
WriteBit), :58 (WriteZeroBit— also read-modify-write, so even all-white runs really write), :11 (WriteBits) - T4 trigger: T4TiffCompression.cs#L75 and L109-L119 —
rowsWrittenonly increments on EOL; consecutive makeup codes accumulate into oneRunLength, thenWritePixelRunwrites it in full - MH trigger: ModifiedHuffmanTiffCompression.cs#L56-L63 — write happens before the width check at L90-L93
- Buffer size: TiffDecoderCore.cs#L932-L967 —
CalculateStripBufferSize= width × bpp/8 × rowsPerStrip
Attack surface: Image.Load(stream) on an attacker-supplied strip TIFF (TiffDecoderCore.DecodeStripsChunky → TiffDecompressorsFactory.Create → Decompress). Default configuration, no authentication, no user interaction — a plain strip TIFF (far more common than the tiled variant) with Compression=2 or 3 and a chain of CCITT makeup codes.
Relationship to GHSA-v76p-62qx-wwq2: that report is the tiled variant — a caller-side width mismatch (TiffDecompressorsFactory drops tile parameters) that overflows with perfectly legal run codes. This report is the strip variant — the callee-side missing bounds check plus T4's EOL-only row accounting and MH's write-before-validate. Fixing the caller mismatch does not address this vector; bounding BitWriterUtils addresses both (see remediation).
Suggested remediation:
- Bound
BitWriterUtils.WriteBits/WriteBit/WriteZeroBitagainstbuffer.Length*8(return bool / throwImageFormatException) — do not rely on caller discipline. - In the T4/MH decompress loops, validate
(bitsWritten + RunLength) <= buffer.Length*8before writing; abort T4 when accumulated rows exceed…
- Record
GHSA-jj3q-cwqj-842r- CVSS 3.1
- 7.5 High
CVSS: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, decoding a strip TIFF using CCITT Group 3 or Modified Huffman compression can pass attacker-expanded runs to BitWriterUtils.WriteBits without first checking the current row width. T4TiffCompression.WritePixelRun can accumulate oversized makeup-code runs, and ModifiedHuffmanTiffCompression.Decompress validates the width only after writing. The unchecked writes can overflow the strip buffer, corrupt heap memory, and terminate the process. This strip-path vulnerability is distinct from the tiled decompressor-width mismatch. This issue is fixed in version 4.1.1.
- Record
CVE-2026-106117- CVSS 3.1
- 7.5 High
CVSS: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: CCITT fax decompression (T4/Modified Huffman): unbounded WriteBits overflows strip buffer — heap OOB write in SixLabors.ImageSharp
ImageSharp is a 2D graphics library. From 3.0.0 until 4.1.1, decoding a strip TIFF using CCITT Group 3 or Modified Huffman compression can pass attacker-expanded runs to BitWriterUtils.WriteBits without first checking the current row width. T4TiffCompression.WritePixelRun can accumulate oversized makeup-code runs, and ModifiedHuffmanTiffCompression.Decompress validates the width only after writing. The unchecked writes can overflow the strip buffer, corrupt heap memory, and terminate the process. This strip-path vulnerability is distinct from the tiled decompressor-width mismatch. This issue is fixed in version 4.1.1.
- Record
CVE-2026-106117- CVSS 3.1
- 7.5 High
CVSS: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-jj3q-cwqj-842r
7.5
ImageSharp: CCITT fax decompression (T4/Modified Huffman): unbounded WriteBits overflows strip buffer — heap OOB write in SixLabors.ImageSharp
Summary
When decoding a fax-compressed strip TIFF (Compression=3 / Group 3 1D, or Compression=2 / Modified Huffman), the CCITT decompressors write decoded runs through BitWriterUtils.WriteBits/WriteBit/WriteZeroBit, which advance and write bits via Unsafe.Add with read-modify-write semantics — without ever comparing the write position against the target buffer length. The strip buffer is sized ImageWidth × RowsPerStrip (8 bytes in the PoC), but two independent defects let an attacker write tens of millions of bits past it: (a) T4 only increments rowsWritten when an EOL code is read, and one ReadNextRun accumulates unlimited makeup codes (+2560 px per 12-bit code) into a single RunLength that WritePixelRun then writes in one shot; (b) Modified Huffman writes before validating (pixelsWritten > Width is checked at :90-93, after the write at :56-63), so the overflow completes even though an exception is thrown later. One crafted ~90 KB file writes ~19.2 MB linearly past an 8-byte buffer and deterministically kills the process; the write offset and length are fully attacker-controlled (classic heap-corruption primitive on the managed heap).
Verified at commit 5cd4d0d26a82a9549f297a237aea9cf665bddff8 (main; latest release v4.1.0, the supported major). A related tiled-path variant (tile-buffer width mismatch) was reported separately as GHSA-v76p-62qx-wwq2 — this report covers the distinct strip-path root cause.
Details
Root cause: the bit-writing sink has no bounds check, and neither decompressor constrains run lengths against the strip buffer.
- Unchecked write primitive: BitWriterUtils.cs#L51 (
WriteBit), :58 (WriteZeroBit— also read-modify-write, so even all-white runs really write), :11 (WriteBits) - T4 trigger: T4TiffCompression.cs#L75 and L109-L119 —
rowsWrittenonly increments on EOL; consecutive makeup codes accumulate into oneRunLength, thenWritePixelRunwrites it in full - MH trigger: ModifiedHuffmanTiffCompression.cs#L56-L63 — write happens before the width check at L90-L93
- Buffer size: TiffDecoderCore.cs#L932-L967 —
CalculateStripBufferSize= width × bpp/8 × rowsPerStrip
Attack surface: Image.Load(stream) on an attacker-supplied strip TIFF (TiffDecoderCore.DecodeStripsChunky → TiffDecompressorsFactory.Create → Decompress). Default configuration, no authentication, no user interaction — a plain strip TIFF (far more common than the tiled variant) with Compression=2 or 3 and a chain of CCITT makeup codes.
Relationship to GHSA-v76p-62qx-wwq2: that report is the tiled variant — a caller-side width mismatch (TiffDecompressorsFactory drops tile parameters) that overflows with perfectly legal run codes. This report is the strip variant — the callee-side missing bounds check plus T4's EOL-only row accounting and MH's write-before-validate. Fixing the caller mismatch does not address this vector; bounding BitWriterUtils addresses both (see remediation).
Suggested remediation:
- Bound
BitWriterUtils.WriteBits/WriteBit/WriteZeroBitagainstbuffer.Length*8(return bool / throwImageFormatException) — do not rely on caller discipline. - In the T4/MH decompress loops, validate
(bitsWritten + RunLength) <= buffer.Length*8before writing; abort T4 when accumulated rows exceed…
- Record
GHSA-jj3q-cwqj-842r- CVSS 3.1
- 7.5 High
CVSS: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
| Package | Affected | Fixed |
|---|---|---|
ImageSharpNuGet |
3.0.0 up to 3.2.0 | 3.2.0 |
ImageSharpNuGet |
4.0.0 up to 4.1.1 | 4.1.1 |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-106117 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.39%, the 32nd percentile. Fixed in ImageSharp 3.2.0.
References
github.com/SixLabors/ImageSharp/security/advisories/GHSA-jj3q-cwqj-842r
github.com/SixLabors/ImageSharp/pull/3176
github.com/SixLabors/ImageSharp/commit/e8892ecd8a95dee95c4480fda51cfe0b32f3b846
github.com/SixLabors/ImageSharp/releases/tag/v4.1.1
nvd.nist.gov/vuln/detail/CVE-2026-106117
github.com/SixLabors/ImageSharp/releases/tag/v3.2.0
github.com/advisories/GHSA-jj3q-cwqj-842r
github.com/CVEProject/cvelistV5/tree/main/cves/2026/106xxx/CVE-2026-106117.json
github.com/SixLabors/ImageSharp
Left out here: the rest of 2 source descriptions. The JSON record has them.