# REPRO-2026-00283: Nuclio cron trigger shell command injection leading to RCE ## Summary Status: published Severity: critical Type: security Confidence: high ## Identifiers REPRO ID: REPRO-2026-00283 GHSA: GHSA-v5px-423j-pf7p CVE: CVE-2026-52831 ## Package Name: github.com/nuclio/nuclio Ecosystem: go Affected: <= 1.15.27 (all versions before 0.0.0-20260601075854-3356b86a8bfa) Fixed: Unknown ## Root Cause # Root Cause Analysis: CVE-2026-52831 Nuclio Cron Trigger Shell Command Injection ## Summary Nuclio's Kubernetes controller generated Kubernetes CronJob containers for cron triggers by concatenating attacker-controlled cron event data into a single shell command and storing it as `Args: ["/bin/sh", "-c", curlCommand]`. A malicious `event.headers` key containing an unescaped double quote and shell separators breaks out of the intended `curl --header "key: value"` quoting and appends arbitrary shell commands. In this run, a real Nuclio controller binary processed a real `NuclioFunction` Kubernetes custom resource, generated a real Kubernetes CronJob, and a CronJob-derived pod executed attacker-controlled `echo` and `id` commands. ## Impact - **Package/component affected:** Nuclio Kubernetes controller, specifically Kubernetes CronJob-based cron trigger generation in `pkg/platform/kube/functionres/lazy.go`. - **Affected versions:** Nuclio versions at or before the vulnerable parent of fixed commit `3356b86a8bfab3f960aa420310ebff765df9dede`; the ticket states Nuclio 1.15.27 and earlier are affected. - **Risk level and consequences:** Critical. A user who can create or update a Nuclio function with a malicious cron trigger can cause the cluster to create a CronJob whose pod runs arbitrary shell commands in the CronJob container context. This is product-path remote/API-triggered command execution via the Kubernetes/Nuclio API boundary. ## Impact Parity - **Disclosed/claimed maximum impact:** Code execution / RCE through Nuclio cron trigger event headers or body in Kubernetes CronJob-based cron trigger processing. - **Reproduced impact from this run:** Code execution in real Kubernetes CronJob pods generated by the Nuclio controller. The vulnerable pod logs include the attacker marker `CVE_PRODUCT_RCE` and `id` output (`uid=100(curl_user) ...`). - **Parity:** `full` - **Not demonstrated:** No attempt was made to chain from CronJob-container command execution to broader cluster privilege escalation. The reproduced impact matches the claimed command execution at the affected product boundary. ## Root Cause In the vulnerable code path, Nuclio decoded cron trigger attributes from a `NuclioFunction` resource and built a shell command string for invoking the function: - User-controlled headers were formatted as `--header ": "` and appended into one string. - The final curl invocation was embedded in `Args: []string{"/bin/sh", "-c", curlCommand}` for the CronJob container. - Because header keys were not escaped for shell context, a key such as `X-Exploit"; echo CVE_PRODUCT_RCE; id; echo "` terminates the intended quoted header and injects shell commands. - The vulnerable parent commit used `/bin/sh -c`; the fixed commit switches to exec-form invocation, `Command: []string{"curl"}`, passes each curl argument as a separate argv entry, and uses `--data-raw` for the body so no shell interprets attacker data. The fixed commit used for negative control is `3356b86a8bfab3f960aa420310ebff765df9dede` (`[Security] Fix cron trigger shell injection`). The reproduction script checks out and builds `3356b86a8bfa^` for the vulnerable path and `3356b86a8bfa` for the fixed path, and verifies the relevant patch hunk before running. ## Reproduction Steps 1. Use `bundle/repro/reproduction_steps.sh`. 2. The script: - Reuses the prepared Nuclio repository cache when available. - Resolves the vulnerable commit as `3356b86a8bfa^` and the fixed commit as `3356b86a8bfa`. - Builds the real Nuclio `cmd/controller` binary for both commits. - Creates fresh kind Kubernetes clusters for two vulnerable attempts and two fixed attempts. - Starts the real Nuclio controller binary inside each kind control-plane container. - Applies real `NuclioFunction` and `NuclioProject` custom resources. - Waits for the controller to generate a Kubernetes CronJob from the malicious cron trigger. - Creates a manual Job from that CronJob and captures the real pod logs. 3. Expected evidence: - Vulnerable attempts: CronJob JSON contains `args[0] == "/bin/sh"` and `args[1] == "-c"`, and pod logs contain `CVE_PRODUCT_RCE` and `uid=`. - Fixed attempts: CronJob JSON contains `command: ["curl"]`, does not contain `/bin/sh` or `-c`, and pod logs contain only the stub HTTP response `ok` with no attacker marker. ## Evidence - `bundle/logs/reproduction_steps.log` — top-level run log for the final successful run. - `bundle/repro/runtime_manifest.json` — structured runtime manifest showing `entrypoint_kind="endpoint"`, `service_started=true`, `healthcheck_passed=true`, and `target_path_reached=true`. - `bundle/logs/vulnerable_attempt1/cronjob_pretty.json` and `bundle/logs/vulnerable_attempt2/cronjob_pretty.json` — vulnerable controller-generated CronJobs. They show the generated container args include `/bin/sh`, `-c`, and an injected shell command string containing `echo CVE_PRODUCT_RCE; id`. - `bundle/logs/vulnerable_attempt1/pod.log` and `bundle/logs/vulnerable_attempt2/pod.log` — real CronJob-derived pod logs. Key excerpt: ```text CVE_PRODUCT_RCE uid=100(curl_user) gid=101(curl_group) groups=101(curl_group) ``` - `bundle/logs/fixed_attempt1/cronjob_pretty.json` and `bundle/logs/fixed_attempt2/cronjob_pretty.json` — fixed controller-generated CronJobs. They show `command: ["curl"]` and discrete args containing the malicious strings as data, not shell syntax. - `bundle/logs/fixed_attempt1/pod.log` and `bundle/logs/fixed_attempt2/pod.log` — fixed negative control pod logs. They contain `ok` and do not contain `CVE_FIXED_SHOULD_NOT_RUN`. - Environment details captured in `bundle/logs/reproduction_steps.log` include Go, Docker, kind, resolved commits, and built controller binary metadata. ## Recommendations / Next Steps - Keep the fixed exec-form approach: never pass user-controlled cron trigger header keys, header values, or body through `/bin/sh -c`. - Pass curl and all arguments as a command/argv vector, not a shell command string. - Use `--data-raw` or an equivalent safe body handling mechanism to avoid file expansion or shell substitution primitives. - Add regression tests that exercise malicious header keys, header values, and bodies through the controller/CronJob generation path and assert no shell is present in the resulting pod spec. - Upgrade Nuclio deployments to a version containing fixed commit `3356b86a8bfab3f960aa420310ebff765df9dede` or later. ## Additional Notes - Idempotency confirmation: `bundle/repro/reproduction_steps.sh` was run successfully twice consecutively after the final fixes. - The script uses real Kubernetes objects and a real Nuclio controller binary, but it starts the controller directly in the kind control-plane container rather than installing the full Helm chart. This preserves the relevant production boundary: Kubernetes API/CRD watch -> Nuclio controller reconciliation -> generated Kubernetes CronJob -> real CronJob pod execution. - A small busybox HTTP stub is deployed only so fixed exec-form curl has a reachable function service target and can complete without retry timeout. It is not used to simulate the vulnerable controller or CronJob generation behavior. ## Reproduction Details Reproduced: 2026-07-11T13:13:12.877Z Duration: 5340 seconds Tool calls: 384 Turns: Unknown Handoffs: 3 ## Quick Verification Run one of these commands to verify locally: pruva-verify REPRO-2026-00283 pruva-verify GHSA-v5px-423j-pf7p pruva-verify CVE-2026-52831 Or open in GitHub Codespaces (zero-friction, auto-runs): https://github.com/codespaces/new?ref=repro/REPRO-2026-00283&repo=N3mes1s/pruva-sandbox Or download and run the script manually: curl -O https://api.pruva.dev/v1/reproductions/REPRO-2026-00283/artifacts/bundle/repro/reproduction_steps.sh chmod +x reproduction_steps.sh ./reproduction_steps.sh WARNING: Run in a sandboxed environment. This exploits a real vulnerability. ## References - GitHub Advisory: https://github.com/advisories/GHSA-v5px-423j-pf7p - NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-52831 - Source: https://github.com/nuclio/nuclio ## Artifacts - bundle/repro/reproduction_steps.sh (reproduction_script, 20808 bytes) - bundle/repro/rca_report.md (analysis, 7239 bytes) - bundle/vuln_variant/reproduction_steps.sh (reproduction_script, 9267 bytes) - bundle/vuln_variant/rca_report.md (analysis, 8712 bytes) - bundle/artifact_promotion_manifest.json (other, 10914 bytes) - bundle/artifact_promotion_report.json (other, 10932 bytes) - bundle/vuln_variant/source_identity.json (other, 934 bytes) - bundle/vuln_variant/root_cause_equivalence.json (other, 1308 bytes) - bundle/logs/vulnerable_test.log (log, 4060 bytes) - bundle/logs/fixed_test.log (log, 23341 bytes) - bundle/repro/validation_verdict.json (other, 752 bytes) - bundle/logs/reproduction_steps.log (log, 9692 bytes) - bundle/logs/vulnerable_attempt1/pod.log (log, 458 bytes) - bundle/logs/fixed_attempt1/cronjob_pretty.json (other, 3457 bytes) - bundle/repro/runtime_manifest.json (other, 1099 bytes) - bundle/logs/vulnerable_attempt2/pod.log (log, 458 bytes) - bundle/logs/vulnerable_attempt1/cronjob_pretty.json (other, 3087 bytes) - bundle/logs/fixed_attempt1/pod.log (log, 2 bytes) - bundle/logs/fixed_attempt2/pod.log (log, 2 bytes) - bundle/vuln_variant/patch_analysis.md (documentation, 5674 bytes) - bundle/vuln_variant/variant_manifest.json (other, 3544 bytes) - bundle/vuln_variant/validation_verdict.json (other, 2793 bytes) - bundle/logs/vuln_variant/reproduction_steps.log (log, 4343 bytes) - bundle/vuln_variant/runtime_manifest.json (other, 1376 bytes) - bundle/logs/vuln_variant/source_identity.txt (other, 402 bytes) - bundle/logs/vuln_variant/patch_diff.stat (other, 258 bytes) - bundle/logs/vuln_variant/lazy_vulnerable_excerpt.txt (other, 3347 bytes) - bundle/logs/vuln_variant/lazy_fixed_excerpt.txt (other, 3533 bytes) - bundle/logs/vuln_variant/security_policy_scan.txt (other, 766 bytes) - bundle/logs/vuln_variant/candidate_matrix.log (log, 1697 bytes) - bundle/logs/vuln_variant/curl_header_at_probe.log (log, 482 bytes) ## API Access - JSON: https://api.pruva.dev/v1/reproductions/REPRO-2026-00283 - Script: https://api.pruva.dev/v1/reproductions/REPRO-2026-00283/artifacts/bundle/repro/reproduction_steps.sh - Web: https://pruva.dev/r/REPRO-2026-00283 ## For AI Assistants To help users with this reproduction: 1. The `pruva-verify` command is the simplest way to run the reproduction 2. The script downloads and runs automatically in an isolated temp directory 3. Always recommend running in a VM, container, or disposable environment 4. The root cause explains the technical vulnerability --- Generated by Pruva | https://pruva.dev