What Happened

On May 5, 2026, Cyera Research publicly disclosed CVE-2026-7482 — nicknamed “Bleeding Llama” — a critical vulnerability in Ollama, the most popular tool for running local LLMs. The bug lives in Ollama’s GGUF model parser. An unauthenticated attacker can upload a single malicious model file, call one API endpoint, and get back a dump of the Ollama server’s heap memory — environment variables, API keys, system prompts, in-flight user conversations.

The CVSS score is 9.1 (Critical). The number of publicly reachable Ollama servers is roughly 300,000. Every Ollama version before 0.17.1 is affected.

This article is based on Cyera Research’s detailed disclosure of the vulnerability.

How the Attack Works

The Root Cause — A Tensor Shape Nobody Checks

GGUF is the binary format Ollama (and llama.cpp) use for model weights. Every tensor in a GGUF file declares its shape — the dimensions of the multi-dimensional array — in the file header.

Ollama’s quantization path reads those shape values and feeds them straight into a conversion loop (ConvertToF32). The loop walks shape[0] * shape[1] * ... elements out of the buffer. The buffer itself is bounded by the file size. The shape values are not.

If an attacker puts a very large number in the shape field, the loop will blindly read past the end of the buffer — that’s our out-of-bounds heap read.

To make matters worse, the conversion uses Go’s unsafe package, which bypasses Go’s runtime memory safety guarantees. There is no bounds check between the manifest-declared shape and the actual file payload.

The Four-Step Exploit Chain

The attack doesn’t require authentication, doesn’t need a victim user, and works against any Ollama server reachable on the network.

StepEndpointWhat Happens
1POST /api/blobs/sha256:...Attacker uploads a crafted GGUF file with inflated tensor shape values
2POST /api/createTriggers quantization → ConvertToF32 reads far past the buffer → heap data spills into the output tensor
3(internal)Attacker chooses F16 → F32 conversion — a lossless transform, so leaked bytes survive intact in the new model artifact
4POST /api/pushPush the new “model” (now containing heap memory) to an attacker-controlled registry via a URI-formatted model name

The leaked heap can contain anything the Ollama process has touched: environment variables, vendor API keys passed in for proxy mode, system prompts, other users’ chat content, session tokens.

Disclosure Timeline

This was reported responsibly. The fix landed before public disclosure.

DateEvent
2026-02-02Cyera Research reports the vulnerability to Ollama
2026-02-25Ollama acknowledges and proposes a fix
2026-03-02CVE requested from MITRE
2026-04-28Echo CNA assigns CVE-2026-7482
2026-05-01CVE published
2026-05-05Cyera publishes the full technical write-up

Why “300,000 Servers” Is Not Hyperbole

Ollama’s default bind is 127.0.0.1, which would have been fine. But the documented production recipe — including in Ollama’s own README and most “self-host an LLM” tutorials — is:

OLLAMA_HOST=0.0.0.0 ollama serve

OLLAMA_HOST=0.0.0.0 binds Ollama to every network interface, with no authentication, on port 11434. Shodan and Censys queries return ~300,000 internet-reachable instances. The /api/create, /api/blobs, and /api/push endpoints are unauthenticated in the upstream distribution.

How Do I Know If I’m Affected

Check Your Ollama Version

The fixed version is 0.17.1. Anything earlier is vulnerable.

# Check your installed version
ollama --version

# If you're running it as a service
systemctl status ollama | grep -i version

Check If You’re Network-Exposed

# Is Ollama bound to all interfaces?
ss -tlnp | grep 11434

# A line containing 0.0.0.0:11434 or [::]:11434 means
# you're exposed on every interface. 127.0.0.1:11434 is the safe state.
# Check the environment of a running ollama process
ps -ef | grep ollama
cat /proc/$(pgrep ollama | head -1)/environ 2>/dev/null | tr '\0' '\n' | grep OLLAMA_HOST

Check the Server Logs for Exploit Traffic

The exploit fingerprint is a POST /api/create quickly followed by POST /api/push from the same source IP with an unfamiliar registry URI.

# systemd journal (Linux)
journalctl -u ollama --since "30 days ago" | grep -E "api/(create|push|blobs)"

# Docker container logs
docker logs ollama 2>&1 | grep -E "api/(create|push|blobs)"

Any POST /api/push to a destination that isn’t registry.ollama.ai is suspicious by default.

# List pushed/created models for unfamiliar names
ollama list

Important caveat: A successful heap leak leaves no obvious on-disk artifact other than a model entry pointing at an unfamiliar registry. If you find such an entry, treat the host as compromised and assume any secret reachable by the Ollama process is now public.

Mitigation Steps

1. Upgrade Immediately

# Linux / macOS native install
curl -fsSL https://ollama.com/install.sh | sh

# Verify
ollama --version  # must be >= 0.17.1
# Docker
docker pull ollama/ollama:latest
docker stop ollama && docker rm ollama
docker run -d -p 127.0.0.1:11434:11434 -v ollama:/root/.ollama --name ollama ollama/ollama:latest

2. Stop Binding to 0.0.0.0

The single most impactful change you can make. If you only consume Ollama from the same machine — don’t expose it at all.

# Default safe binding
OLLAMA_HOST=127.0.0.1 ollama serve

# If you must expose it, bind to a specific internal interface, not 0.0.0.0
OLLAMA_HOST=10.0.0.5 ollama serve

For systemd users, edit the unit file (/etc/systemd/system/ollama.service):

[Service]
Environment="OLLAMA_HOST=127.0.0.1"

Then systemctl daemon-reload && systemctl restart ollama.

3. Put an Authenticated Proxy in Front

If remote access is genuinely needed, never expose /api/create, /api/blobs, or /api/push directly. Front Ollama with a reverse proxy that:

  • Requires an API key or mTLS for every request
  • Blocks /api/create, /api/blobs, /api/push entirely unless the caller is in an admin allowlist
  • Only forwards /api/chat, /api/generate, /api/embeddings, /api/tags
location ~ ^/api/(create|blobs|push) {
    # Block all callers except trusted admin IPs
    allow 10.0.0.0/24;
    deny all;
}

location /api/ {
    auth_request /auth;       # validate API key
    proxy_pass http://127.0.0.1:11434;
}

4. If You Were Exposed — Rotate Everything

Heap memory could contain anything the Ollama process touched. If your server was internet-reachable with a vulnerable version, assume leakage:

  1. Rotate every secret the Ollama process could see:
    • Environment variables (OPENAI_API_KEY, ANTHROPIC_API_KEY, vendor proxy keys, etc.)
    • System prompts containing proprietary instructions or embedded credentials
    • Any token mounted into the container or process environment
  2. Audit recent conversations for sensitive content that other users sent — that content was in the same heap
  3. Check outbound network logs for connections to unfamiliar model registries during the exposure window
  4. Rebuild the host if the same machine ran other workloads with credentials in memory

5. Block Untrusted GGUF Sources Going Forward

The attack vector is creation from a user-supplied GGUF file. If your users don’t need to upload arbitrary models:

# Front-end policy: only allow `ollama pull` from registry.ollama.ai
# Reject any /api/create call from unauthenticated callers (see #3)

For multi-tenant deployments, treat every uploaded GGUF as untrusted input — the same way you’d treat a user-uploaded ZIP file or executable.

Key Takeaways

  1. unsafe in Go bypasses memory safety — and the GGUF parser used it without bounds checks. Memory-safe languages are not memory-safe when you opt out. Any code path that uses unsafe, cgo, or hand-rolled pointer arithmetic deserves the same scrutiny as a C codebase.

  2. The vulnerable endpoints (/api/create, /api/blobs, /api/push) ship unauthenticated and rich in privilege. This is the AI-infrastructure equivalent of leaving kubectl proxy open on the public internet. Powerful local-admin endpoints have no business being exposed by default.

  3. OLLAMA_HOST=0.0.0.0 is the new 0.0.0.0:6379 (the old Redis-without-auth meme). Every “self-host a local LLM” tutorial that ships this as a copy-paste line has been actively misleading people into a 300,000-server attack surface.

  4. F16 → F32 is the unintended exfiltration channel. A lossless numeric conversion meant the attacker could round-trip leaked heap bytes through Ollama’s own quantization pipeline without corruption. Any “harmless” data transformation that preserves bit patterns is also a viable smuggling primitive.

  5. The disclosure worked, and that’s worth saying out loud. Reported Feb 2, fixed before public disclosure on May 5. The 3-month embargo is exactly how this should go — but it also means the patch has been public for less than a week, and most self-hosted Ollama instances do not auto-update.

Future Discussion

Model Files Are Untrusted Code Now

A GGUF file is no longer “just weights.” It’s a structured binary that hits a parser written in unsafe Go, then a quantization pipeline, then a serializer, then a network push endpoint. That’s a complete attack surface — exactly the kind we used to associate with image decoders and ZIP libraries. The “model file” abstraction needs to be treated with the same scepticism we apply to any user-uploaded binary blob.

AI Infrastructure Is Repeating Every Mistake the Web Made

Public-by-default services, unauthenticated admin endpoints, “just bind to 0.0.0.0” tutorials, unsafe parsers — this is the 2005 LAMP-stack security era playing out again, fifteen years later, on AI servers. Memcached, MongoDB, Elasticsearch, Redis, Kubernetes dashboards — every one of those had its “300,000 exposed instances” moment. Ollama just got its turn.

Memory-Safe Languages Are Not Memory-Safe

This vulnerability is in Go code. Go has a GC, has bounds-checked slices, has a runtime that catches most memory bugs. None of that helped, because the parser used unsafe. Rust has the same escape hatch, Python has ctypes. The takeaway is not “use a better language” — it’s that every unsafe block needs the same review intensity as raw C, and most projects do not give it that.

Local LLM Deployments Need Security Hardening Defaults

Ollama, llama.cpp, vLLM, LM Studio, Text Generation WebUI — most of these tools default to either “127.0.0.1 only, but the docs immediately tell you to change that to 0.0.0.0” or “0.0.0.0 with no auth.” A meaningful step forward would be: bind to localhost by default, require an explicit --listen-all-interfaces-i-understand-the-risk flag, and ship a built-in API key mechanism. Until that’s standard, every new LLM-server project will reinvent this CVE.

References