GHSA-v5px-423j-pf7p: Nuclio: Unsanitized cron trigger event headers/body injected into CronJob shell command leads to persistent RCE
Summary
Nuclio controller builds a curl invocation string for each cron trigger and stores it as the args of a Kubernetes CronJob container (/bin/sh, -c, <command>). Two fields in the trigger specification flow into this string without adequate sanitization:
- event.headers keys — interpolated verbatim inside double-quoted --header arguments (lazy.go:2150); any key containing " breaks the quoting context.
- event.body — processed with strconv.Quote, which escapes " and \ but not $(), allowing command substitution (lazy.go:2188).
Both paths were dynamically verified on Nuclio 1.15.27 (latest as of 2026-05-17).
- CVSS 3.1: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H — 9.9 (Critical)
- CWE: CWE-78 (Improper Neutralization of Special Elements used in an OS Command)
- Affected versions: Nuclio <= 1.15.27 (latest, dynamically verified)
Details
Root Cause
When a NuclioFunction with a cron trigger is reconciled by the controller, it calls generateCronTriggerCronJobSpec in pkg/platform/kube/functionres/lazy.go:2113. This function builds a shell command string by concatenating user-supplied values and passes it directly to /bin/sh -c.
Path-A — Header key injection (lazy.go:2146-2151)
// lazy.go:2146-2151
headersAsCurlArg := ""
for headerKey := range attributes.Event.Headers {
headerValue := attributes.Event.GetHeaderString(headerKey)
headersAsCurlArg = fmt.Sprintf("%s --header \"%s: %s\"",
headersAsCurlArg, headerKey, headerValue)
// ↑
// headerKey is user-controlled; no escaping applied
}
headerKey is taken from event.headers in the trigger specification. Since it is interpolated directly inside a double-quoted shell argument, a key containing " terminates the quoting context. The remainder of the key is then interpreted as raw shell syntax.
Attack string for headerKey:
X-Inject"; ARBITRARY_COMMAND; echo "
Resulting shell command fragment:
--header "X-Inject"; ARBITRARY_COMMAND; echo ": value"
Path-B — Body command substitution (lazy.go:2173-2192)
// lazy.go
Details
Original advisory: https://github.com/advisories/GHSA-v5px-423j-pf7p
Referenced CVEs
| CVE | CSIRTS overview | External |
|---|---|---|
| CVE-2026-52831 | coverage & exploitation status | NVD · CVE.org |
More from GitHub Security Advisories
- criticalGHSA-g936-7jqj-mwv8: TSDProxy: Internal proxy auth token forwarded to backend services enables management API …2026-07-10
- highGHSA-fpg8-7664-jc5q: melange: Incomplete package integrity verification allows data section substitution2026-07-10
- mediumGHSA-48rx-c7pg-q66r: Excon does not redact additional sensitive/risky headers when following redirects2026-07-10
- highGHSA-h4g2-xfmw-q2c9: Clauster: Non-loopback deployments can serve the dashboard unauthenticated when auth.enab…2026-07-10
- mediumGHSA-rqq5-2gf9-4w4q: Secure Headers: CSP directive injection via sandbox, plugin_types, and report_to when giv…2026-07-10