Home/ Blog/ Security news/ Article
Blog · Security news

bank-vaults Kubernetes webhook flaw lets a low-privilege user steal HashiCorp Vault secrets (CVE-2026-54725)

CVE-2026-54725 is a critical SSRF in bank-vaults vault-secrets-webhook (CVSS 9.6). A user who can create a ConfigMap can steal ServiceAccount tokens. Fix: 1.23.

Isometric relay node with one conduit bent away from a cluster of nodes

An admission webhook is one of the more privileged things running in a Kubernetes cluster. It sits in the path of every object that gets created, and the secret-injection webhook from the bank-vaults project holds a cluster-wide right to mint ServiceAccount tokens. CVE-2026-54725, published on July 31, turns that privilege against the people who deployed it: a user who can do nothing more than create a ConfigMap or a Secret in a watched namespace can make the webhook fetch a ServiceAccount token and mail it to an attacker.

The flaw carries a CVSS score of 9.6 and is fixed in version 1.23.1. Everything up to and including 1.22.2 is affected. No public exploit is reported at the time of writing, which is the good news and the reason to move now: the window before someone weaponizes a one-annotation trick is short.

What the webhook was tricked into doing

vault-secrets-webhook is a mutating admission webhook that injects secrets from HashiCorp Vault straight into pods, so applications never read a secret off disk. To do that it reads annotations off the objects it admits, including one that names the Vault server address (vault.security.banzaicloud.io/vault-addr).

According to the project's security advisory, versions through 1.22.2 trust that annotation off any admitted ConfigMap or Secret without validating it: no scheme check, no hostname allowlist, no filter for private or link-local addresses. When the object also carries a value prefixed with vault:, the webhook makes a synchronous call to the annotated address as it admits the object. That is a textbook server-side request forgery: the attacker decides where a privileged process reaches out.

The credential theft is what makes it a 9.6 rather than a nuisance. A second annotation, vault-serviceaccount, selects which ServiceAccount the webhook authenticates as, and the webhook holds serviceaccounts/token:create across the whole cluster. So the attacker names a ServiceAccount, the webhook mints that account's JSON Web Token through the Kubernetes TokenRequest API, and sends it to the attacker's address. That token can then be replayed against the real Vault to read whatever secrets the account's role can reach. The MITRE record is CVE-2026-54725, classified as CWE-918.

StageWhat happensWhere you catch it
BaitAttacker creates a ConfigMap or Secret in a watched namespace, adding a vault-addr annotation pointing at their own server plus one vault: valueKubernetes audit log: create or update on configmaps and secrets carrying an off-cluster vault-addr annotation
Call-outThe webhook reads the annotation and calls that address during admission, with no allowlist checkUnexpected egress from the webhook pod to a host that is not your Vault
Token mintThe vault-serviceaccount annotation selects a ServiceAccount; the webhook uses its cluster-wide token:create right to mint that account's JWTKubernetes audit: a TokenRequest for serviceaccounts/token driven by the webhook identity
Steal and replayThe JWT is sent to the attacker, who replays it against the real Vault to read that role's secretsVault audit log: a login from a source you do not recognise
How the vault-secrets-webhook flaw (CVE-2026-54725) turns a low-privilege namespace user into stolen Vault credentials, and where a defender can catch each step. Source: GitHub Security Advisory GHSA-r2v3-8gwf-7ghm.

Why 'low privilege' undersells this

The CVSS vector marks privileges required as low, and on paper that reads as reassuring. In a real multi-tenant cluster it is close to no barrier at all. The right to create a ConfigMap or a Secret in a namespace is one of the most commonly granted permissions there is: continuous-integration runners hold it, application operators hold it, and plenty of developer roles hold it by default. None of those actors is supposed to be able to reach into your secret store. This flaw lets any of them try.

This is the confused deputy pattern in a Kubernetes costume. The webhook is powerful and trusted; the attacker is neither, but the webhook acts on data the attacker fully controls, so its power becomes the attacker's. We have seen the same shape when a single secret hands over a cluster and when a service integration is steered into calling an attacker. The common thread is trusting input that crosses a privilege boundary.

How you would know

Patching closes the hole. It does not tell you whether someone already walked through it. Because the theft is an outbound call from the webhook pod itself, not from the attacker's workload, ordinary endpoint tooling on your application pods will not see it. The evidence lives in three places, and they are worth checking whether or not you have patched yet:

  • Kubernetes audit logs. Look for create or update events on ConfigMaps and Secrets that carry a vault-addr annotation pointing at a host that is not your Vault, and for TokenRequest calls (serviceaccounts/token) attributed to the webhook that do not line up with a normal pod launch.
  • Egress from the webhook pod. The webhook should only ever talk to your Vault. Any other outbound destination from that pod is a strong signal.
  • Vault audit logs. A stolen token still has to be used. Authentication events from a source address you do not recognise, against a role tied to an injected ServiceAccount, are the tell that a token was replayed.

These are the log sources a managed detection setup watches for this class of Kubernetes credential abuse, mapped to techniques like stealing an application access token and using alternate authentication material.

Patch to 1.23.1, then check who can create secrets

Upgrade vault-secrets-webhook to 1.23.1 or later. The fix validates the object-supplied Vault address against an allowlist the operator controls, so an annotation can no longer redirect the webhook to an arbitrary host. Confirm your running version first; anything at or below 1.22.2 is exposed.

Patching is step one, not the finish line. Two hardening moves outlast this specific CVE:

  • Scope down who can create ConfigMaps and Secrets in namespaces the webhook watches. If a role does not need that permission, remove it. The precondition for this attack is exactly that grant.
  • Constrain the webhook's egress with a network policy so it can reach your Vault and nothing else. An allowlist on the annotation and an allowlist on the network are two locks on the same door.

Admission webhooks are becoming the quiet privilege surface of Kubernetes. They run early, they run trusted, and they increasingly act on attacker-reachable input. This one held a path to a secret store; the next will hold something else. Treat every webhook that reads object annotations as code that runs on untrusted input, because that is what it is.

Topics

Frequently asked questions

What is CVE-2026-54725?

CVE-2026-54725 is a critical server-side request forgery flaw in bank-vaults vault-secrets-webhook, a Kubernetes secret-injection tool. It scores 9.6 on the CVSS scale. An attacker who can create a ConfigMap or Secret in a watched namespace can force the webhook to send a ServiceAccount token to an attacker-controlled address.

Which versions are affected and what is the fix?

All versions up to and including 1.22.2 are affected. The fix is version 1.23.1, which validates the object-supplied Vault address against an allowlist the operator controls. Upgrade to 1.23.1 or later, then confirm no workloads still run an older build.

How much access does an attacker need?

The attacker only needs permission to create or update a ConfigMap or Secret in a namespace the webhook watches. That permission is commonly granted to CI runners, operators, and developer roles, so the practical barrier is low even though the flaw requires some cluster access.

Is CVE-2026-54725 being exploited?

No public exploit or in-the-wild exploitation was reported at the time of writing. That is the reason to patch now rather than later. The attack turns on a single annotation, so a working exploit would not be hard to build once the details spread.

How would I detect an attempt?

Detection relies on three log sources. Kubernetes audit logs for ConfigMaps or Secrets carrying an off-cluster vault-addr annotation and for TokenRequest calls from the webhook, unexpected egress from the webhook pod, and Vault authentication events from unfamiliar source addresses that show a stolen token was replayed.

Ready to meet the Guardians?

Deploys fast - agentless for monitoring and cloud, a lightweight agent for deep endpoint security. Just Suriq, standing watch.