YAML Metadata Warning:empty or missing yaml metadata in repo card
Check out the documentation for more information.
gguf-py β Shape Spoof + OOB Offset in GGUF Python Reader
Product: gguf Python package (PyPI)
Version: All versions β confirmed 0.18.0 (latest as of 2026-04-01)
Format: .gguf
CWE: CWE-20 (Improper Input Validation)
Impact: (1) Attacker-controlled tensor shape returned silently; (2) Out-of-bounds data_offset crashes reader (DoS)
Trigger: gguf.GGUFReader(malicious_file.gguf)
Background
gguf-py is the official Python library for reading and writing GGUF model files (the format used by llama.cpp and all GGML-based inference). It is distributed separately as the gguf PyPI package (used by Hugging Face transformers, llama-cpp-python, quantization tools, and model converters).
These vulnerabilities are independent of the C/C++ gguf.cpp vulnerabilities (CVE-2025-53630, CVE-2026-27940, CVE-2026-33298) β they exist in the pure Python implementation.
Vulnerability 1 β Shape Spoof via Zero Dimension (gguf_reader.py:329)
Root Cause
gguf/gguf_reader.py, _build_tensors(), lines 329β367:
# gguf_reader.py:329-332
n_elems = int(np.prod(dims)) # β dims is uint64 array from file
np_dims = tuple(reversed(dims.tolist()))
block_size, type_size = GGML_QUANT_SIZES[ggml_type]
n_bytes = n_elems * type_size // block_size
# gguf_reader.py:367
data = self._get(data_offs, item_type, item_count).reshape(np_dims)
When dims contains a zero (e.g., [0, HUGE_VALUE]):
np.prod(dims)returns 0 βn_elems = 0βitem_count = 0_get(data_offs, float32, 0)returns an empty array (0 bytes read from file).reshape((HUGE_VALUE, 0))succeeds β numpy allows reshape into any shape with a zero dimension as long as total elements = 0
The reader returns a tensor with shape (HUGE_VALUE, 0) β entirely attacker-controlled β with no data read and no exception raised. HUGE_VALUE can be any uint64 value embedded in the GGUF file.
Impact
A malicious .gguf model can report arbitrary tensor shapes to the caller. Any downstream code that trusts tensor.n_elements or tensor.data.shape (e.g., shape validation, memory preallocation, model architecture checks) receives attacker-controlled values.
Vulnerability 2 β OOB offset_tensor (gguf_reader.py:333)
Root Cause
gguf/gguf_reader.py, _build_tensors(), line 333:
# gguf_reader.py:333
data_offs = int(start_offs + offset_tensor[0]) # β offset_tensor from file, no bounds check
offset_tensor[0] is read directly from the GGUF file with no validation against file size. When set to 0xFFFFFFFFFFFFFF00, data_offs points far past the end of the file.
_get(data_offs, ...) silently returns an empty numpy array (numpy slicing past EOF returns []), then .reshape(dims) crashes with ValueError when dims expects non-zero elements.
Impact
Any application loading a malicious .gguf file crashes with an unhandled ValueError. This is a denial-of-service via a single malformed model file.
Proof of Concept
Files
| File | Description |
|---|---|
gen_poc.py |
Generates poc_shape_spoof.gguf and poc_oob_offset.gguf |
trigger.py |
Loads both files and confirms both vulnerabilities |
Setup
uv sync
Reproduce
uv run gen_poc.py
uv run trigger.py
Expected output
[*] gguf : 0.18.0
[*] numpy : 2.4.4
=================================================================
VULN 1: gguf_reader.py:329 β silent shape spoof via zero dim
=================================================================
[*] Declared dims : [0, 1311768467294899695]
[*] Returned data.shape : (1311768467294899695, 0)
[+] SHAPE SPOOF CONFIRMED β GGUFReader returned without error
File contains 0 bytes of tensor data
Reader reports shape (1311768467294899695, 0) β attacker-controlled
=================================================================
VULN 2: gguf_reader.py:333 β offset_tensor not validated vs file size
=================================================================
[+] OOB CONFIRMED β GGUFReader crashed with: cannot reshape array of size 0 into shape (4,)
gguf_reader.py:333: data_offs = int(start_offs + offset_tensor[0])
No bounds check. offset_tensor accepted directly from file.
Security Impact
Vuln 1: A malicious
.gguffile causesGGUFReaderto return an attacker-shaped tensor object with no data. Downstream tools that trusttensor.data.shapefor architecture validation, memory allocation, or inference will operate on fabricated metadata. Model integrity checks can be bypassed.Vuln 2: A malicious
.gguffile crashes any program usingGGUFReaderβ denial of service for model converters, inference servers, and quantization pipelines that load untrusted GGUF files.
Affected users: Anyone using the gguf PyPI package to load untrusted .gguf files β including model conversion tools (convert_hf_to_gguf.py), inference servers, Hugging Face model loading pipelines, and quantization utilities.
Vulnerable Code
gguf/gguf_reader.py:329βn_elems = int(np.prod(dims))with no zero-dim validationgguf/gguf_reader.py:333βdata_offs = int(start_offs + offset_tensor[0])with no file-size bounds check
Affected versions
gguf (PyPI) all versions β confirmed on 0.18.0 (latest as of 2026-04-01).
- Downloads last month
- -
We're not able to determine the quantization variants.