Summary
A follow-up bypass of the round-4 PodSpec hardening (GHSA-gx55-f84r-v3r7, GHSA-wmgg-3p4h-48x7, GHSA-v455-mv2v-5g92). Those advisories validate and sanitize the PodSpec (spec.runtime.podSpec / spec.builder.podSpec /
function.spec.podSpec), but the Environment CRD also exposes spec.runtime.container and spec.builder.container — a standalone Container merged into the runtime/builder pod whose SecurityContext bypassed both layers.
Details
Admission-layer gap. Environment.Validate() calls ValidatePodSpecSafety() on Runtime.PodSpec and Builder.PodSpec only. That function takes a *PodSpec, so it never inspects the standalone Runtime.Container.SecurityContext
or Builder.Container.SecurityContext.
Merge-layer gap. sanitizeContainerSecurityContext() ran only inside MergePodSpec(). The container field is merged via MergeContainer(), which did not sanitize. With only Runtime.Container set and Runtime.PodSpec nil,
MergePodSpec is never invoked, so the sanitizer never ran.
Affected merge sites: poolmgr (gp_deployment.go), newdeploy (newdeploy.go), and buildermgr (envwatcher.go).
Proof of concept
apiVersion: fission.io/v1
kind: Environment
metadata:
name: priv-escape-test
namespace: default
spec:
version: 3
runtime:
image: "ghcr.io/fission/python-env:latest"
container:
name: priv-escape-test
securityContext:
privileged: true
poolsize: 1
The admission webhook accepts this Environment and the resulting pool pod runs with privileged: true. Equivalent bypasses: allowPrivilegeEscalation: true, capabilities.add: ["SYS_ADMIN"], capabilities.add: ["NET_ADMIN","SYS_PTRACE"]. The same attack applies to Builder.Container.
Impact
A tenant with environments.fission.io create/update RBAC can run privileged / allowPrivilegeEscalation / dangerous-capability containers in the Fission function or builder namespace, scheduled under the executor's high-privilege
service account — enabling container-sandbox escape, host filesystem and network access, and potential node- and cluster-level compromise. Identical blast radius to GHSA-gx55-f84r-v3r7.
Fix
Fixed in #3406 and released in v1.24.0.
- Admission layer (primary defence): a new
ValidateContainerSafety in pkg/apis/core/v1/podspec_safety.go applies the per-container SecurityContext denylist (privileged, allowPrivilegeEscalation, dangerous capabilities) to a
standalone container, and is called from Environment.Validate() for Runtime.Container and Builder.Container.
- Merge layer (defence in depth):
sanitizeContainerSecurityContext() is now invoked inside MergeContainer() itself, covering all three executor/builder call sites.
Workarounds
- Restrict Environment create/update RBAC to trusted administrators.
- Deploy a Kyverno / OPA Gatekeeper policy rejecting dangerous Container SecurityContext on Environment CRDs.
- Label the function/builder namespaces with
pod-security.kubernetes.io/enforce: restricted.
References
References
Summary
A follow-up bypass of the round-4 PodSpec hardening (GHSA-gx55-f84r-v3r7, GHSA-wmgg-3p4h-48x7, GHSA-v455-mv2v-5g92). Those advisories validate and sanitize the
PodSpec(spec.runtime.podSpec/spec.builder.podSpec/function.spec.podSpec), but the Environment CRD also exposesspec.runtime.containerandspec.builder.container— a standaloneContainermerged into the runtime/builder pod whoseSecurityContextbypassed both layers.Details
Admission-layer gap.
Environment.Validate()callsValidatePodSpecSafety()onRuntime.PodSpecandBuilder.PodSpeconly. That function takes a*PodSpec, so it never inspects the standaloneRuntime.Container.SecurityContextor
Builder.Container.SecurityContext.Merge-layer gap.
sanitizeContainerSecurityContext()ran only insideMergePodSpec(). The container field is merged viaMergeContainer(), which did not sanitize. With onlyRuntime.Containerset andRuntime.PodSpecnil,MergePodSpecis never invoked, so the sanitizer never ran.Affected merge sites: poolmgr (
gp_deployment.go), newdeploy (newdeploy.go), and buildermgr (envwatcher.go).Proof of concept
The admission webhook accepts this Environment and the resulting pool pod runs with
privileged: true. Equivalent bypasses:allowPrivilegeEscalation: true,capabilities.add: ["SYS_ADMIN"],capabilities.add: ["NET_ADMIN","SYS_PTRACE"]. The same attack applies toBuilder.Container.Impact
A tenant with
environments.fission.iocreate/update RBAC can runprivileged/allowPrivilegeEscalation/ dangerous-capability containers in the Fission function or builder namespace, scheduled under the executor's high-privilegeservice account — enabling container-sandbox escape, host filesystem and network access, and potential node- and cluster-level compromise. Identical blast radius to GHSA-gx55-f84r-v3r7.
Fix
Fixed in #3406 and released in v1.24.0.
ValidateContainerSafetyinpkg/apis/core/v1/podspec_safety.goapplies the per-container SecurityContext denylist (privileged,allowPrivilegeEscalation, dangerous capabilities) to astandalone container, and is called from
Environment.Validate()forRuntime.ContainerandBuilder.Container.sanitizeContainerSecurityContext()is now invoked insideMergeContainer()itself, covering all three executor/builder call sites.Workarounds
pod-security.kubernetes.io/enforce: restricted.References
e484df84).References