Skip to content

CVE-2026-52831: Verified Repro With Script Download

CVE-2026-52831: Nuclio cron trigger shell command injection leading to RCE

CVE-2026-52831 is verified against github.com/nuclio/nuclio · go. Affected versions: <= 1.15.27 (all versions before 0.0.0-20260601075854-3356b86a8bfa). Vulnerability class: RCE. This critical reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00283.

REPRO-2026-00283 github.com/nuclio/nuclio · go RCE Variant found Jul 11, 2026 CVE entry ↗ .txt
Severity
CRITICAL
Confidence
HIGH
Reproduced in
89m 0s
Tool calls
384
Spend
$19.48
01 · Overview

What Is CVE-2026-52831?

CVE-2026-52831 is a critical OS command injection vulnerability (CWE-78) in the Nuclio Kubernetes controller's cron trigger generation, allowing arbitrary shell command execution in the cluster. Pruva reproduced it (reproduction REPRO-2026-00283).

02 · Severity & CVSS

CVE-2026-52831 Severity

CVE-2026-52831 is rated critical severity.

CRITICAL threat level
03 · Affected Versions

Affected github.com/nuclio/nuclio Versions

github.com/nuclio/nuclio · go versions <= 1.15.27 (all versions before 0.0.0-20260601075854-3356b86a8bfa) are affected.

How to Reproduce CVE-2026-52831

$ pruva-verify REPRO-2026-00283
or curl -O https://pruva.dev/api/v1/reproductions/REPRO-2026-00283/artifacts/bundle/repro/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh
Run in a VM or disposable container. This exploits a real vulnerability.
06 · Proof of Reproduction

Proof of Reproduction for CVE-2026-52831

Remote code execution — reproduced
  • reached the target end-to-end
  • full exploit chain demonstrated
  • on the real production code path
  • high confidence
  • the upstream fix blocks the same trigger
Trigger

NuclioFunction cron trigger event.headers key containing shell metacharacters

Attack chain
  1. NuclioFunction CR
  2. controller reconciliation
  3. Kubernetes CronJob pod /bin/sh -c curl args
Runnable proof: reproduction_steps.sh
Captured evidence: vulnerable testfixed test
Variants tested

No fixed-version bypass or materially distinct same-root-cause variant was confirmed for Nuclio cron-trigger shell command injection. The fixed commit removes the shell sink from the centralized Kubernetes CronJob generation path and uses exec-form curl with --data-raw.

How the agent worked 1,037 events · 384 tool calls · 1h 29m
1h 29mDuration
384Tool calls
335Reasoning steps
1,037Events
4Dead-ends
Agent activity over 1h 29m
Support
36
Hypothesis
2
Repro
835
Judge
61
Variant
98
0:0089:00

Root Cause and Exploit Chain for CVE-2026-52831

Versions: Nuclio versions at or before the vulnerable parent of fixed commit 3356b86a8bfab3f960aa420310ebff765df9dede; the ticket states Nuclio 1.15.27 and earlier are affected.

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.

  • 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 "<headerKey>: <headerValue>" 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:
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.

Variant Analysis & Alternative Triggers for CVE-2026-52831

Versions: versions as tested: vulnerable parent 82b9b64ee9bc0c7d99447b5890ef85973fee4e36; ticket states Nuclio 1.15.27 and earlier are affected.Fixed: version as tested: 3356b86a8bfab3f960aa420310ebff765df9dede.

No distinct fixed-version bypass or materially different same-root-cause variant was confirmed. The parent vulnerability was reachable because Nuclio's Kubernetes controller converted untrusted cron trigger event.headers and event.body into a single /bin/sh -c string for a generated Kubernetes CronJob. The fixed commit 3356b86a8bfab3f960aa420310ebff765df9dede removes that shell sink in the centralized CronJob generation path by invoking curl directly with discrete argv entries and using --data-raw for body content. Bounded variant analysis tested header-key, header-value/body, body-@, and header-@ candidates; all were covered or did not produce command execution on the fixed target.

Fix Coverage / Assumptions

The original fix relies on this invariant: no attacker-controlled cron trigger header key, header value, or body may be interpreted by a shell while constructing or running the generated Kubernetes CronJob invocator container.

The fix explicitly covers:

  • pkg/platform/kube/functionres/lazy.go, (*lazyClient).generateCronTriggerCronJobSpec.
  • The Kubernetes cron-trigger path: NuclioFunction.spec.triggers[*].kind == "cron" -> controller reconciliation -> generated Kubernetes CronJob -> invocator container.
  • Header keys and values, now appended as literal curl argv pairs: "--header", fmt.Sprintf("%s: %s", headerKey, value).
  • Body values, now appended as "--data-raw", eventBody instead of shell-writing to a temp file and using --data '@/tmp/eventbody.out'.

The fixed code does not attempt to sanitize or reject metacharacters. Instead, it removes the interpreter that made metacharacters dangerous. That is sufficient for the parent command-injection root cause. One non-shell curl behavior remains in theory (--header @file), but the tested Nuclio formatting makes the entire header argument @/path: value; curl errors while trying to open that exact string and no OS command executes.

Variant / Alternate Trigger

Tested candidates and entry points:

  1. Header key with quote/semicolon shell metacharacters

    • Entry point: Kubernetes/Nuclio API creation or update of a NuclioFunction custom resource with a cron trigger.
    • Path: pkg/platform/kube/functionres/lazy.go:generateCronTriggerCronJobSpec.
    • Result: parent trigger on vulnerable parent, not a fixed-version bypass. The fixed commit treats the complete header as one argv value after --header.
  2. Body with command substitution or shell separators

    • Entry point: same NuclioFunction cron trigger attributes, event.body.
    • Path: same function.
    • Result: not a fixed-version bypass. The fixed commit passes the body literally via --data-raw; no shell sees $(id) or separators.
  3. Body beginning with @/path to use curl file-load semantics

    • Entry point: same cron trigger event.body.
    • Path: same function.
    • Result: not a fixed-version bypass. The fixed commit explicitly uses --data-raw, covered by the regression test.
  4. Header key beginning with @/path to use curl --header @file semantics

    • Entry point: same cron trigger event.headers map key.
    • Path: same function and curl argv semantics.
    • Result: not a command-execution bypass. The local probe showed curl fails with curl_exit=26 while trying to open /etc/passwd: marker; no request reaches the server and no marker command executes.
  • Package/component affected by the parent bug: Nuclio Kubernetes controller, cron-trigger CronJob generation in pkg/platform/kube/functionres/lazy.go.
  • Affected versions as tested: vulnerable parent 82b9b64ee9bc0c7d99447b5890ef85973fee4e36; ticket states Nuclio 1.15.27 and earlier are affected.
  • Fixed version as tested: 3356b86a8bfab3f960aa420310ebff765df9dede.
  • Risk level and consequences for the parent: critical RCE in the CronJob container context when an actor can create/update a malicious cron-trigger NuclioFunction.
  • Variant-stage consequence: no additional fixed-version RCE was reproduced.

Impact Parity

  • Disclosed/claimed maximum impact for the parent: arbitrary OS command execution / RCE from malicious cron trigger headers or body.
  • Reproduced impact from this variant run: no fixed-version command execution; the variant script confirmed the vulnerable parent still contains the shell sink and the fixed commit does not, then executed bounded candidate probes.
  • Parity: none for a new variant/bypass.
  • Not demonstrated: no code execution on the fixed commit; no alternate production entry point outside Kubernetes cron-trigger CronJob generation was found.

Root Cause

The parent root cause was unsafe composition of attacker-controlled cron trigger data into a shell command string stored as Args: []string{"/bin/sh", "-c", curlCommand}. The fixed commit is 3356b86a8bfab3f960aa420310ebff765df9dede ([Security] Fix cron trigger shell injection (#4139)). It changes the sink from shell-form execution to exec-form curl:

  • Vulnerable parent: headersAsCurlArg and body shell fragments are concatenated into curlCommand, then run through /bin/sh -c.
  • Fixed commit: Command: []string{"curl"} and Args: curlArgs ensure untrusted strings are data argv entries.

Because the same underlying bug depends on shell interpretation, and the fixed centralized path removes that interpreter for all cron event headers/body, the same root cause could not be reached by the tested alternate inputs.

Reproduction Steps

  1. Use bundle/vuln_variant/reproduction_steps.sh.
  2. The script:
    • Resolves the vulnerable parent and fixed commit in the prepared Nuclio repository.
    • Saves patch stats, source excerpts, and a security-policy scan under bundle/logs/vuln_variant/.
    • Checks the vulnerable parent for /bin/sh -c cron-trigger generation.
    • Checks the fixed commit for Command: ["curl"], no shell-form args, and --data-raw body handling.
    • Records a bounded candidate matrix and runs a local curl --header '@/etc/passwd: marker' semantics probe.
  3. Expected result: exit 1, meaning no variant reproduced on the fixed version. This is the intended negative result for this run. The script is idempotent and was run twice successfully.

Evidence

  • bundle/logs/vuln_variant/reproduction_steps.log — final variant-stage execution log.
  • bundle/logs/vuln_variant/source_identity.txt — exact resolved commits:
    • vulnerable parent 82b9b64ee9bc0c7d99447b5890ef85973fee4e36
    • fixed commit 3356b86a8bfab3f960aa420310ebff765df9dede
  • bundle/logs/vuln_variant/patch_diff.full — fixed diff showing removal of shell-form curlCommand and addition of exec-form curlArgs.
  • bundle/logs/vuln_variant/lazy_vulnerable_excerpt.txt and bundle/logs/vuln_variant/lazy_fixed_excerpt.txt — side-by-side relevant source excerpts.
  • bundle/logs/vuln_variant/candidate_matrix.log — evaluated candidates and rule-out rationale.
  • bundle/logs/vuln_variant/curl_header_at_probe.log — curl @ header probe; key excerpt: curl_exit=26, no server request, and no command-execution marker.
  • bundle/vuln_variant/runtime_manifest.json — structured runtime/inspection manifest for the negative validation.

Environment details captured include the repository path, current repository HEAD, fixed commit subject/date, and local curl version.

Recommendations / Next Steps

  • Keep the exec-form curl implementation and do not reintroduce /bin/sh -c for generated cron-trigger CronJobs.
  • Add or keep regression tests covering header values in addition to header keys, body command substitution, and body leading @ values.
  • Consider adding a regression case for header keys beginning with @ to document curl behavior and prevent future changes from accidentally creating a file-read primitive.
  • If future features add new cron-trigger invocation modes, require the same invariant: no shell command string may be built from event.headers, event.body, trigger names, or function names.

Additional Notes

  • Idempotency confirmation: bundle/vuln_variant/reproduction_steps.sh was run twice; both runs completed and exited 1 without crashing, consistently indicating no fixed-version bypass.
  • The target repository did not contain a top-level SECURITY.md or explicit threat model in the bounded scan. The security boundary used here is the one demonstrated by the parent repro: untrusted function spec data crossing the Kubernetes/Nuclio API boundary into controller-generated Kubernetes workload commands.
  • This stage produced a negative verdict, not a claimed new vulnerability.

CVE-2026-52831 Reproduction Transcript

The agent's step-by-step process — every tool call, every handoff, the moment the exploit fired.

Full session Replay every step — scrub the timeline or play it back.

Event 1/40
0:003:43
0:00
session startedaccounts/fireworks/models/kimi-k2p7-code · CVE-2026-52831 · REPRO-20
0:03
0:04
web search
0:07
0:08
0:12
0:14
web search
0:17
0:18
web search
0:24
0:25
web search
0:28
0:29
web search
0:32
0:34
web search
0:45
0:46
0:59
0:59
1:13
1:14
web search
2:05
2:05
extract_facts
no facts extracted
2:11
2:11
2:11
supportrepro
3:43

Artifacts and Evidence for CVE-2026-52831

Scripts, logs, diffs, and output captured during the reproduction.

08 · How to Fix

How to Fix CVE-2026-52831

Coming soon

Step-by-step mitigation and hardening guidance for CVE-2026-52831 — configuration checks, workarounds where no patch exists, and how to verify you're protected — is on the way.

10 · FAQ

FAQ: CVE-2026-52831

How does the CVE-2026-52831 exploit work?

An attacker who can create or update a NuclioFunction resource with a malicious cron trigger sets an event.headers key containing an unescaped double quote and shell separators, breaking out of the intended curl --header "key: value" quoting (event.body command substitution is also viable). When Kubernetes runs the generated CronJob, the resulting pod executes the injected shell commands in the CronJob container context — demonstrated in the reproduction with attacker-controlled echo and id commands.

Which Nuclio versions are affected by CVE-2026-52831, and where is it fixed?

Nuclio versions at or before 1.15.27 (all builds before commit 3356b86a8bfab3f960aa420310ebff765df9dede) are affected; the fix lands at that commit.

How severe is CVE-2026-52831?

It is rated critical: a user able to create or update a Nuclio function with a cron trigger can cause arbitrary command execution in the cluster via the Kubernetes/Nuclio API boundary. No CVSS score is recorded for this reproduction.

How can I reproduce CVE-2026-52831?

Download the verified script from this page and run it in an isolated environment against a Nuclio controller at or before 1.15.27. It creates a NuclioFunction with a cron trigger whose event.headers/body contain shell metacharacters, then shows the resulting Kubernetes CronJob pod executing the injected echo and id commands.
11 · References

References for CVE-2026-52831

Authoritative sources for CVE-2026-52831 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.