← Blog

Bleeding Llama (CVE-2026-7482): Your Local LLM Is an Unauthenticated Memory Leak

· 7 min read · ES

On May 1, 2026, CVE-2026-7482 — nicknamed Bleeding Llama — was published. It is a heap out-of-bounds read in Ollama’s GGUF model loader, discovered by researchers at Cyera. CVSS 9.1 Critical.

Ollama is the most widely deployed way to run large language models locally: ~170,000 GitHub stars, 100M+ Docker Hub pulls. It listens on 0.0.0.0 by default, with no authentication. Cyera cites roughly 300,000 instances exposed on the public internet at time of disclosure — up from ~175,000 estimated in January 2026.

Here is the part that should worry you: an unauthenticated attacker can dump the server’s process memory — user prompts, other models’ system prompts, and environment variables including cloud provider credentials — in three API calls, leaving no meaningful trace.

Almost every write-up so far says the same thing: “upgrade to 0.17.1.” That is correct and insufficient. This post covers the attack chain, and then the part nobody is writing: how a defender actually detects this in their own environment.


The Bug: Declared Size vs. Real Size

GGUF is the binary format Ollama uses to store model weights. Like many binary formats, it declares the shape of each tensor in a header — how many elements it contains — separately from the actual data bytes that follow.

The vulnerability is that nothing validates that the declared element count matches the real data size.

When Ollama quantizes or converts a model, it walks the tensors and trusts the declared count. The conversion path — WriteToggml.ConvertToF32 — passes q.from.Elements() (the attacker-declared count) straight into low-level conversion routines like ggml_fp16_to_fp32_row. That code uses Go’s unsafe package, which bypasses Go’s memory-safety guarantees.

So if you declare a tensor of, say, one million elements but supply only a few bytes of real data, the conversion loop reads a million elements’ worth of memory — running far past the end of the allocated buffer and straight into adjacent heap memory. That neighboring memory is whatever the process was holding: prompts, system prompts from other loaded models, environment variables, secrets.

Declared:  tensor shape = 1,000,000 elements
Supplied:  a handful of real bytes
Conversion loop reads 1,000,000 elements → runs off the buffer
         → captures adjacent heap memory into the output

Classic out-of-bounds read (CWE-125). The twist is what comes next — the attacker gets to keep the leaked bytes and ship them off the box.


The Attack Chain: Three Calls

Cyera’s research lays out the full chain. It abuses three unauthenticated endpoints:

1. Upload the malicious model. The attacker uploads a crafted GGUF blob via POST /api/blobs/sha256:<digest>, with the file content in the HTTP body.

2. Trigger the out-of-bounds read. The attacker calls POST /api/create requesting quantization. The crafted GGUF declares a huge tensor shape (the demo used one million elements) over tiny real data. The conversion loop over-reads the heap. Crucially, the attacker sets the source type to F16 and the target to F32 — that conversion is lossless, and the follow-on F32→F32 step is a no-op, so the leaked heap bytes land on disk intact, not mangled by quantization math.

3. Exfiltrate. Ollama’s model names double as push destinations. The attacker names the model after a URI they control — e.g. attacker-server.com/leak. Calling POST /api/push makes PushModel treat that name as an HTTP target and upload the model — leaked heap and all — to the attacker’s server. Nothing validates that a model name is not an arbitrary URI.

Three calls. No credentials. In Cyera’s demonstration, the leaked memory included AWS credentials and cloud model-provider environment variables sitting in the process.


Why This Is Worse Than a Normal Memory Leak

Two properties turn this from “bad” into “operationally dangerous”:

  • The default posture is exposure. Ollama binds 0.0.0.0 with no auth out of the box. The vulnerable state is not something you have to misconfigure into — it is the shipping default the moment the port is reachable.
  • Exfiltration is built-in. Most OOB reads leak memory somewhere you then have to find a way to read back. Here the same product feature (/api/push to a named destination) hands the attacker a clean exfiltration channel. The read and the exfil are the same workflow.

And it is quiet. There is no failed-auth log, no crash, no obvious anomaly in a naive setup. Which is exactly why detection matters more than the patch note.


Detection: What Nobody Else Is Writing

Patching to Ollama 0.17.1 (the fixed release; see the upstream fix PR #14406 / commit 88d57d0) closes the bug. But in any real organization you have two problems the patch does not solve:

  1. You do not know how many Ollama instances exist on your network — shadow AI is real; engineers run these on workstations and dev boxes.
  2. You want to know if anyone already tried this before you patched.

1. Find your exposed instances first

The vulnerable surface is “Ollama reachable from somewhere it should not be.” Find it before an attacker does.

# Internal sweep: default Ollama port, unauthenticated API root
# (run only against networks you own / are authorized to test)
nmap -p 11434 --open -oG - 10.0.0.0/8 | awk '/11434\/open/{print $2}'

# Confirm it is Ollama and reachable without auth:
curl -s http://<host>:11434/api/tags | head

Externally, the same fingerprint that researchers use on Shodan (product:"Ollama", default port 11434) is what an attacker uses. If your ASN shows up there, that is your incident, not a hypothetical.

The single most important check is the bind address. 0.0.0.0 means “every interface, including the ones facing your users”:

# On each host running Ollama:
ss -tlnp | grep 11434
# 0.0.0.0:11434  → exposed to the network
# 127.0.0.1:11434 → local only (good)

2. Hunt the attack in your logs

The attack has a distinctive three-endpoint sequence from a single source in a short window: a blob upload, a create/quantize, then a push to an external destination. Any one of those is normal in isolation. The sequence — especially a /api/push to a host outside your registry — is not.

If you have a reverse proxy or access logs in front of Ollama, the detection logic is:

ALERT when, from one source IP within N minutes:
  POST /api/blobs/sha256:*         (model upload)
  AND POST /api/create             (quantization requested)
  AND POST /api/push               (push out)
  AND the push target host  ∉  {your known model registries}

Pseudo-rule (adapt to your SIEM’s query language):

source.ip                      = <single value>
http.request.method            = POST
url.path IN ("/api/blobs/*", "/api/create", "/api/push")
| sequence by source.ip within 10m
  [ url.path : "/api/blobs/*" ]
  [ url.path : "/api/create" ]
  [ url.path : "/api/push" and NOT destination.host in (allowed_registries) ]

Two cheaper signals worth alerting on even without full sequence logic:

  • Any /api/push to a destination outside your allowlist. In most orgs, models get pulled far more than pushed, and pushes go to a known registry. An outbound push to an arbitrary host is anomalous on its own.
  • /api/create with quantization from an unexpected source. Model creation is an admin/CI action, not something random clients do. A create call from a user subnet is worth a look.

3. Egress is your backstop

Bleeding Llama exfiltrates over an outbound HTTP push. If your Ollama hosts have no business making arbitrary outbound connections, default-deny egress turns a critical unauthenticated leak into a contained failed attempt — even on an unpatched box. This is the control that saves you when patching lags reality.


The Broader Lesson

Local LLM tooling grew up optimizing for “works in five minutes on my laptop.” That default — bind everything, authenticate nothing — is fine on a laptop and catastrophic the moment it lands on a reachable network. The dangerous configuration rarely looks dangerous; it looks like a convenience feature (“access my model from another device”).

The detection-engineering takeaway is not Ollama-specific. As AI infrastructure spreads into every org through the back door, the blue-team job is the same as it has always been: know what is listening, know what normal traffic looks like, and constrain egress so a leak has nowhere to go. A CVE with a patch is the easy half. Finding the shadow instance running it on 0.0.0.0 is the half that actually protects you.

Patch to 0.17.1. Bind to 127.0.0.1. Then go hunt for the copies you did not know you had.


If you found this useful, you might also like Harness Engineering: 6 Defense Layers I Built Around Claude Code — the same “constrain what the agent can reach” thinking, applied to autonomous AI systems.