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
- Products
- ImageSharp
- Affected versions
- Not specified
- Fixed versions
- 3.2.0, 4.1.1
- CVEs
- CVE-2026-106117
- Confirmed fixed CVEs
- Not specified
- Updated in this feed
- 30 Oct 2026, 06:37 UTC · Revision 1
Source evidence
ImageSharp: CCITT fax decompression (T4/Modified Huffman): unbounded WriteBits overflows strip buffer — heap OOB write in SixLabors.ImageSharp
core-osv · Original sourcePublished 7 Oct 2026, 16:18 UTC
## 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
osv:GHSA-jj3q-cwqj-842r
ImageSharp
Fixed versions: 3.2.0
ImageSharp
Fixed versions: 4.1.1
Complete source record
{
"id": "2cca8940662d46257f254fe140490a6ea2ddb9537fbaff432a803723bf2ed31c",
"url": "https://osv.dev/vulnerability/GHSA-jj3q-cwqj-842r",
"method": "structured",
"payload": {
"kind": "advisory",
"title": "ImageSharp: CCITT fax decompression (T4/Modified Huffman): unbounded WriteBits overflows strip buffer — heap OOB write in SixLabors.ImageSharp",
"summary": "## 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",
"evidence": "osv:GHSA-jj3q-cwqj-842r",
"products": [
{
"name": {
"value": "ImageSharp",
"evidence": "/affected/0/package/name"
},
"prerequisites": [],
"fixed_versions": [
{
"value": "3.2.0",
"evidence": "/affected/0/ranges"
}
],
"affected_versions": []
},
{
"name": {
"value": "ImageSharp",
"evidence": "/affected/1/package/name"
},
"prerequisites": [],
"fixed_versions": [
{
"value": "4.1.1",
"evidence": "/affected/1/ranges"
}
],
"affected_versions": []
}
],
"severity": "high",
"structured": {
"id": "GHSA-jj3q-cwqj-842r",
"aliases": [
"CVE-2026-106117",
"GHSA-jj3q-cwqj-842r"
],
"metrics": [
{
"type": "CVSS_V3",
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
}
],
"affected": [
{
"ranges": [
{
"type": "ECOSYSTEM",
"events": [
{
"introduced": "3.0.0"
},
{
"fixed": "3.2.0"
}
]
}
],
"package": {
"name": "ImageSharp",
"purl": "pkg:nuget/ImageSharp",
"ecosystem": "NuGet"
},
"database_specific": {
"source": "https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/10/GHSA-jj3q-cwqj-842r/GHSA-jj3q-cwqj-842r.json"
}
},
{
"ranges": [
{
"type": "ECOSYSTEM",
"events": [
{
"introduced": "4.0.0"
},
{
"fixed": "4.1.1"
}
]
}
],
"package": {
"name": "ImageSharp",
"purl": "pkg:nuget/ImageSharp",
"ecosystem": "NuGet"
},
"database_specific": {
"source": "https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/10/GHSA-jj3q-cwqj-842r/GHSA-jj3q-cwqj-842r.json"
}
}
],
"modified": "2026-10-12T14:45:06.701457452Z",
"provider": "osv",
"references": [
"https://github.com/SixLabors/ImageSharp/security/advisories/GHSA-jj3q-cwqj-842r",
"https://nvd.nist.gov/vuln/detail/CVE-2026-106117",
"https://github.com/SixLabors/ImageSharp/pull/3176",
"https://github.com/SixLabors/ImageSharp/commit/e8892ecd8a95dee95c4480fda51cfe0b32f3b846",
"https://github.com/SixLabors/ImageSharp",
"https://github.com/SixLabors/ImageSharp/releases/tag/v3.2.0",
"https://github.com/SixLabors/ImageSharp/releases/tag/v4.1.1"
],
"provider_metadata": {
"cwe_ids": [
"CWE-787"
],
"severity": "HIGH",
"github_reviewed": true,
"nvd_published_at": "2026-10-06T18:16:53Z",
"github_reviewed_at": "2026-10-07T16:18:50Z"
}
},
"related_cves": [
{
"value": "CVE-2026-106117",
"evidence": "/aliases"
}
],
"security_relevant": true,
"severity_evidence": "/database_specific/severity"
},
"source_id": "core-osv",
"document_id": 299963,
"published_at": "2026-10-07T16:18:50+00:00"
}