Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
🐹 Go

GHSA-q93q-v844-jrqp

HIGH

GHSA-q93q-v844-jrqp is a high-severity (CVSS 8.1) CWE-922 vulnerability in github.com/kyverno/kyverno. O3 Security confirms whether GHSA-q93q-v844-jrqp is actually reachable in your code before you act, and blocks exploitation at runtime until you patch.

kyverno apicall servicecall implicit bearer token injection leaks kyverno serviceaccount token

Also known asBIT-kyverno-2026-40868CVE-2026-40868GO-2026-5575
Published
Apr 14, 2026
Updated
Jun 25, 2026
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed

Real-World Exposure

1 pkg affected
🐹github.com/kyverno/kyverno

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects Go packages — download data is not available via public APIs for these ecosystems.

Description

kyverno’s apiCall servicecall helper implicitly injects Authorization: Bearer ... using the kyverno controller serviceaccount token when a policy does not explicitly set an Authorization header. because context.apiCall.service.url is policy-controlled, this can send the kyverno serviceaccount token to an attacker-controlled endpoint (confused deputy).

namespaced policies are blocked from servicecall usage by the namespaced urlPath gate in pkg/engine/apicall/apiCall.go, so this report is scoped to ClusterPolicy and global context usage.

attacker model

the attacker can create or update a ClusterPolicy (or create a GlobalContextEntry) which uses context.apiCall.service.url and can choose the request URL and headers. a cross-boundary framing for real deployments is gitops: if the policy repo/controller is compromised, the ClusterPolicy/global context entry becomes untrusted input to kyverno.

relevant links

root cause

in (*executor).addHTTPHeaders, kyverno reads the serviceaccount token from /var/run/secrets/kubernetes.io/serviceaccount/token and injects it when the outgoing request has no Authorization header:

if req.Header.Get("Authorization") == "" {
  token := a.getToken()
  if token != "" {
    req.Header.Add("Authorization", "Bearer "+token)
  }
}

proof of concept

the attached poc.zip is a reproducible cluster PoC. it uses an in-cluster HTTP receiver which logs the Authorization header it receives. the PoC does not print token bytes; it only checks that the received header is non-empty and not equal to the negative control.

run (one command):

unzip poc.zip -d poc
cd poc
make test

canonical (expected: implicit token injection):

unzip poc.zip -d poc
cd poc
make canonical

expected output includes:

[CALLSITE_HIT]: executor.addHTTPHeaders Authorization=="" -> read_serviceaccount_token=true
[PROOF_MARKER]: authorization_header_injected=true token_nonempty=true

control (expected: explicit Authorization header disables auto-injection):

unzip poc.zip -d poc
cd poc
make control

expected output includes:

[CALLSITE_HIT]: executor.addHTTPHeaders Authorization!="" -> autoinject_skipped=true
[NC_MARKER]: authorization_header_injected=false

optional: the canonical run may also print an [RBAC]: ... line using kubectl auth can-i with the exfiltrated token, to show concrete privileges without exposing the token.

impact

token exfiltration: the kyverno controller serviceaccount token is sent to a policy-controlled endpoint. impact depends on the rbac bound to that serviceaccount in the target deployment.

recommended fix

do not auto-inject the kyverno serviceaccount token into policy-controlled servicecall requests. require explicit Authorization configuration, or enforce a strict allowlist of destinations where credentials may be attached and document the behavior.

workarounds

  • avoid using servicecall to arbitrary urls in policies.
  • set an explicit Authorization header in servicecall policies to prevent implicit token injection.

poc.zip PR_DESCRIPTION.md

oleh

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
🐹Gogithub.com/kyverno/kyvernoall versions1.17.0

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for github.com/kyverno/kyverno. O3's reachability analysis confirms whether the vulnerable code path is actually invoked in your application, so you act on real exposure instead of every transitive match.

  2. Fix

    Update github.com/kyverno/kyverno to 1.17.0 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-q93q-v844-jrqp is resolved across your whole dependency graph.

  3. Workarounds

    If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.

  4. How O3 protects you

    O3 pinpoints whether GHSA-q93q-v844-jrqp is reachable in your code and exactly where to fix it, then blocks exploitation in production at runtime until the patched version is deployed.

Tailored to GHSA-q93q-v844-jrqp. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.

Frequently Asked Questions

kyverno’s apiCall servicecall helper implicitly injects `Authorization: Bearer ...` using the kyverno controller serviceaccount token when a policy does not explicitly set an Authorization header. because `context.apiCall.service.url` is policy-controlled, this can send the kyverno serviceaccount token to an attacker-controlled endpoint (confused deputy). namespaced policies are blocked from servicecall usage by the namespaced `urlPath` gate in `pkg/engine/apicall/apiCall.go`, so this report is scoped to ClusterPolicy and global context usage. ## attacker model the attacker can create or up
O3 Security · Impact-Aware SCA

Is GHSA-q93q-v844-jrqp in your dependencies?

O3 detects GHSA-q93q-v844-jrqp across Go dependencies and uses function-level reachability to confirm whether the vulnerable code path is actually reachable — not just present. No false positives.