GitHub Security Advisory: GHSA-324q-cwx9-7crr
Package: github.com/kubeai-project/kubeai (GO)
Severity: HIGH (CVSS 8.7)
CWE: CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')
Vulnerable versions: <= 0.23.1
Patched in: 0.23.2

Summary: KubeAI: OS Command Injection via Model URL in Ollama Engine startup probe allows arbitrary command execution in model pods

Details:
## 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](https://github.com/kubeai-project/kubeai/blob/ba1824e8c1d70c9092b6c0a48199bba3b8973fee/internal/modelcontroller/engine_ollama.go#L185-L196)):

```go
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](https://github.com/kubeai-project/kubeai/blob/ba1824e8c1d70c9092b6c0a48199bba3b8973fee/internal/modelcontroller/engine_ollama.go#L108-L112)):

```go
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):

```go
// engine_vllm.go - safe: args are passed directly, no shell involved
args := []string{
    "--model=" + vllmModelFlag,
    "--served-model-name=" + m.Name,
}
```

**URL parsing** ([permalink](https://github.com/kubeai-project/kubeai/blob/ba1824e8c1d70c9092b6c0a48199bba3b8973fee/internal/modelcontroller/model_source.go#L229-L270)):

```go
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**

```yaml
apiVersion: kubeai.org/v1
kind: