News Analysis 9 min read

Kaniko ACR Helper Turns A Base Image Into An Azure Token Leak

Kaniko before 1.25.20 can send Azure management tokens to lookalike registries. Rebuild trusted images, isolate build identity and hunt token use.

By Protocol Report Editorial | Updated November 6, 2026
A container build sends an amber workload token through a deceptive registry route while a blue anchored hostname gate rejects the same path before token issuance
Short Version

CVE-2026-105769 affects Chainguard's kaniko before version 1.25.20. A Dockerfile or build argument that points `FROM` or `COPY --from` at a hostname such as `x.azurecr.io.attacker.com` can make kaniko's built-in Azure Container Registry credential helper obtain a Microsoft Entra access token for Azure Resource Manager and send it to the attacker-controlled host. The build needs no `RUN` instruction, push operation or authentication challenge from the remote registry.

Exposure requires an affected kaniko build to process an untrusted image reference while a service principal, federated workload identity or managed identity is available. Operators should rebuild the executor, warmer and standalone helper from 1.25.20 or later, verify the deployed artifact rather than a mutable tag, and remove ambient Azure identity from untrusted builds. If the conditions overlapped, preserve Dockerfiles, build arguments, DNS and egress records; review service-principal or managed-identity sign-ins, Azure Activity Logs and ACR changes; and rotate downstream secrets the leaked Azure authority could retrieve.

Key Takeaways

  • check_circle The vulnerable boundary is kaniko before 1.25.20 processing an attacker-influenced registry reference while an Azure identity is available.
  • check_circle A `FROM` or `COPY --from` reference is enough because the helper asks for credentials before contacting the registry; no shell command or image push is required.
  • check_circle The hostname check accepted an ACR suffix anywhere in a longer domain, so a valid-looking substring could route a live Azure management token to another origin.
  • check_circle Teams can be affected even if they do not use ACR or explicitly configure the helper because kaniko consults its built-in keychain for many registries without configured credentials.
  • check_circle Version 1.25.20 carries a patched helper, but the project publishes no ready-made images or binaries from that repository, so operators must rebuild and verify their own artifacts.
  • check_circle No source in the published advisory record reports in-the-wild exploitation; response should follow overlapping build input, identity, version and network evidence.

Four Conditions Define The Exposure

The advisory gives a narrower boundary than the 9.3 severity score alone. First, the executor, warmer, standalone helper or imported Go module must contain the affected kaniko path from before 1.25.20. Second, an attacker or untrusted contributor must influence a base-image or stage-image reference, directly in a Dockerfile or through build arguments. Third, the build environment must expose an Azure service principal, federated workload token, managed identity through the Instance Metadata Service, or MSI endpoint. Fourth, the build must be able to reach the attacker's HTTPS host.

A trusted, reviewed Dockerfile built without Azure identity is not the same case as a public pull request built by an Azure-hosted runner with a broad managed identity. Inventory must capture the runtime artifact, the source of Dockerfiles and arguments, identity injection, metadata-service reachability and outbound DNS or HTTPS policy. A dependency scanner finding is useful, but it does not answer whether the conditions met in a specific pipeline.

The published advisory record does not report in-the-wild exploitation. That does not make the issue theoretical, because the trigger is a normal image reference and the token transfer is deterministic. It does mean teams should avoid declaring compromise from version presence alone. Prioritize pipelines that build forks, merge requests, customer projects or generated Dockerfiles while inheriting cloud authority.

The Credential Helper Trusted A Substring As An Origin

The flaw originated in `docker-credential-acr-env`. Its regular expression recognized `.azurecr.io`, `.azurecr.cn`, `.azurecr.de` or `.azurecr.us` without anchoring the match to the end of the hostname. A domain such as `evil.azurecr.io.attacker.com` therefore passed as an Azure Container Registry even though the registrable destination was controlled under `attacker.com`.

Kaniko linked that helper into the executor and warmer and also built it as a standalone `docker-credential-acr-env` binary. For a registry without matching Docker credentials that was not Google Container Registry or Amazon ECR, kaniko could consult the built-in helper. The advisory says this happens before contacting the registry, so the attacker does not need to present an authentication challenge. A base image in `FROM` or a stage image in `COPY --from=<image>` can reach the path.

After accepting the host, the helper obtains an Entra access token intended for Azure Resource Manager. It then posts to `https://<host>/oauth2/exchange`, placing the same live token in an Authorization header and an `access_token` form field. TLS protects the connection to the chosen host; it cannot help when origin validation has already selected an attacker-controlled endpoint.

The Leaked Object Is Broader Than A Registry Password

The exposed value is an Azure Resource Manager access token, not only a refresh token scoped to one container repository. Until expiry, an attacker can use it with the identity's Azure role assignments. The kaniko advisory also says the token can be exchanged at a real ACR registry the identity may access. If the identity has `AcrPush` or greater data-plane authority, the attacker can obtain registry credentials and push images.

Impact therefore follows the workload identity, not kaniko's own filesystem privileges. A narrowly scoped pull-only identity creates a different ceiling from a subscription-level contributor or an automation identity that can list storage account keys, read secrets, change deployments or assign roles. Microsoft documents `AcrPush` as authority to push and pull artifacts and manage tags. Azure Activity Logs record control-plane changes such as role assignments, while workload-specific logs are needed for data-plane operations.

The CVSS score reflects high confidentiality and integrity impact across a changed scope, but it is not proof that every affected build can alter a subscription. Record each pipeline identity and effective role assignment at the time of the build. Check inherited roles and custom definitions, not only the label attached at the nearest resource, and identify any credentials or keys the identity could retrieve for use outside Azure.

Upgrading Requires A Trusted Rebuild

Chainguard fixed the issue in kaniko 1.25.20 by carrying a patched copy of the unmaintained helper inside the kaniko module. The replacement validates an exact host and optional port, requires a well-formed registry name ending in an allowed Azure suffix or the exact Microsoft Container Registry host, and returns `credentials not found` for other hosts before asking for a token.

The patch covers both helper uses: the package linked into the executor and warmer, and the standalone binary built by the deployment Dockerfile. The old upstream module is removed from module metadata and build information, which lets Go and image scanners stop reporting GO-2026-6225 when they inspect the corrected artifacts. Updating only a source dependency while continuing to run an older executor image does not close the runtime path.

The security advisory states that the repository publishes no binaries or images. Rebuild every executor, warmer and standalone helper from 1.25.20 or later through a trusted pipeline. Pin the resulting digest, record source revision and dependency evidence, replace cached tools and runner templates, and verify the live pod or job image. A tag that now points to a safe image does not prove which digest ran during an earlier untrusted build.

Containment Removes Identity Before Filtering Input

Where an immediate rebuild is impossible, the advisory's strongest workaround is to stop untrusted builds from reaching an Azure identity. Remove client secrets and federated-token files from the job, remove MSI endpoint variables, and block access from build pods to the Instance Metadata Service at `169.254.169.254`. Run pull-request and customer-controlled builds in a separate pool without production cloud authority.

If the pipeline does not need kaniko's built-in ACR authentication, setting `AZURE_ENVIRONMENT=none` makes the helper fail before requesting a token. Treat that as a tested, temporary control with an owner because it intentionally disables that authentication route. Replacing a global `credsStore: acr-env` setting with per-host `credHelpers` entries closes the standalone Docker-configuration path, but the advisory warns that this alone does not remove kaniko's built-in helper path.

Validate registry destinations before starting the build. Permit exact registries and approved namespaces in `FROM` and external `COPY --from` references, including values produced after build-argument expansion. Egress controls should independently permit only required registries and cloud endpoints. Input policy lowers the chance of a malicious reference; identity isolation and network policy limit the result if validation is bypassed.

Investigation Starts With Builds, Then Follows The Token

Preserve the exact Dockerfile, included files, resolved build arguments, kaniko command line, executor digest, build queue metadata and runner or pod specification for every overlapping job. Search registry references for Azure suffixes followed by more hostname labels, but also retain DNS, proxy, firewall and packet metadata because generated inputs or rewritten build files may not remain in source control. The expected attacker endpoint is HTTPS on the lookalike host with an `/oauth2/exchange` request.

Then identify the credential source. Microsoft separates service-principal sign-ins from managed-identity sign-ins, so query the log that matches the pipeline. Review token issuance and resource access around each build, unfamiliar source addresses, Azure Activity Log changes, ACR pushes and tag changes, role-assignment activity, deployments, storage-key listings and secret access permitted by the identity. Correlate with downstream registry pulls and deployments before assuming an unusual image reached production.

The advisory cautions that rotating a service principal's credential does not revoke an access token already issued; the token remains usable until expiry. If suspicious activity is ongoing, disable the workload identity or remove its assignments while preserving evidence. Rotate any storage keys, application secrets or other reusable credentials the identity could retrieve, because expiry of the leaked Azure token does not invalidate a downstream secret copied with it.

Checklist

  • Inventory kaniko executor, warmer, standalone helper and imported-module versions, including deployed image digests.
  • Identify untrusted Dockerfiles and build arguments processed while service-principal, federated or managed identity was available.
  • Rebuild kaniko from 1.25.20 or later in a trusted pipeline and replace cached runner templates and tools.
  • Remove Azure identity from untrusted builds, block metadata-service access and restrict outbound registry destinations.
  • Preserve resolved image references, build metadata, DNS and egress records before logs or ephemeral jobs disappear.
  • Review matching Entra sign-in logs, Azure Activity Logs, ACR changes, role assignments and secret or key access.
  • Rotate downstream reusable secrets the identity could retrieve, and verify that unexpected images were not deployed.

Sources

Related Articles

Continue Reading