Vulnerabilities in pkg:npm/locize

PACKAGE
Advisory Identifier: GHSA-w937-fg2h-xhq2
Advisory Summary

CVE-2026-41886 is a HIGH (CVSS 7.5) cross-site scripting vulnerability (CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')) affecting locize Client SDK libraries in the npm ecosystem. The issue involves cross-origin dom xss & handler hijack through missing e.origin validation in incontext editor. Remediation is available by upgrading affected packages to version 4.0.21.

1 Known Advisory Record(s)
Package Vulnerability Intelligence

pkg:npm/locize

1 Known Advisory Record(s)

Vulnerability advisories affecting package pkg:npm/locize. Select an advisory below to view technical details or fixes.

Advisory ID CVE / NVD Severity Summary
GHSA-w937-fg2h-xhq2 CVE-2026-41886 HIGH locize Client SDK: Cross-origin DOM XSS & Handler Hijack Through Missing e.origin Validation in InContext Editor

CVE-2026-41886 at a Glance

CVE Identifier CVE-2026-41886
GHSA Identifier GHSA-w937-fg2h-xhq2
Severity HIGH
CVSS v3.1 Base Score 7.5
CWE Classification CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
Affected Product locize Client SDK
Package Ecosystem npm
Published Date
Last Updated

Security Impact

CVSS: 7.5

The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:L/I:H/A:L).

Attack Vector Network (AV:N)
Attack Complexity High (AC:H)
Privileges Required None (PR:N)
User Interaction Required (UI:R)
Scope Changed (S:C)
Confidentiality Low (C:L)
Integrity High (I:H)
Availability Low (A:L)

How to Fix CVE-2026-41886

To remediate this vulnerability, upgrade all affected locize Client SDK dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

locize fixed: 4.0.21
npm install locize@4.0.21
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

npm ls locize

How to Check if You Are Affected

To determine whether your Node.js application is affected by CVE-2026-41886, inspect your project dependencies using npm:

npm ls locize

Analyze the terminal output to locate any version of locize Client SDK in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 4.0.21), your application is affected.

Note: The npm ls locize command inspects dependencies declared in your package.json and lockfile; it does not perform automated runtime dynamic scanning.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting'), where the product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users. In locize Client SDK, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

### Summary Versions of the `locize` client SDK (the browser module that wires up the locize InContext translation editor) prior to 4.0.21 register a `window.addEventListener("message", …)` handler that dispatches to registered internal handlers (`editKey`, `commitKey`, `commitKeys`, `isLocizeEnabled`, `requestInitialize`, …) **without validating `event.origin`**. The pre-patch listener in `src/api/postMessage.js` gates dispatch on `event.data.sender === "i18next-editor-frame"` — that value sits inside the attacker-controlled message payload, not the browser-enforced origin. Any web page that could embed or be embedded by a locize-enabled host — an iframe on a third-party page, a `window.open`-ed victim, a parent frame reaching down — could send a crafted `postMessage` and trigger the internal handlers. ### Impact Depending on which handler the attacker invokes, distinct consequences follow. All of them share the same root cause: the handlers implicitly assumed the payload came from the real editor iframe. - **Cross-origin DOM XSS** via `editKey` / `commitKeys`: the pre-patch `handleEditKey` assigned attacker-controlled payload values to `item.node.innerHTML` and to `item.node.setAttribute(attr, value)`. That allowed planting `<script>`, `<img onerror>`, or `onclick`/`onload`/`onfocus` event handlers; and on attribute writes, `href="javascript:…"` / `src="data:text/html,<script>…"` / `style="…"` / etc. - **`api.source` / `api.origin` hijack** via `isLocizeEnabled`: the handler set `api.source = e.source; api.origin = e.origin` — attacker-controlled values. All subsequent `sendMessage` calls (which post translations, callbacks, etc., back toward `api.source`) would go to the attacker window rather than the real editor, leaking translation content and any metadata the SDK forwards. - **CSS-injection / layout-escape** via `requestPopupChanges`: `containerStyle.height` / `.width` were interpolated into `calc()` expressions and `popup.style.setProperty()` without validation, allowing attackers to inject additional CSS declarations (semicolons, `behavior:url()` on legacy IE, CSS-exfil patterns) into the popup inline style. Exploitation requires the attacker-owned page to share a window reference with the locize-enabled host: typical vectors are an `iframe` on an attacker-controlled page, a `window.opener`/`window.open` relationship, or a parent frame that can `postMessage` into an embedded locize host. The SDK intended model is that only the editor iframe at `https://incontext.locize.app` (or the configured staging/development origin) can reach these handlers. ### Affected versions All versions of `locize` prior to **4.0.21**. ### Patch Fixed in **4.0.21**. Two layers: 1. **Primary** — validate `event.origin` at the top of `window.addEventListener("message", …)` in `src/api/postMessage.js`. The expected origin is the configured iframe origin (`getIframeUrl()`), so custom environments continue to work. Messages from any other origin are silently dropped before any handler runs. 2. **Defence-in-depth** — `handleEditKey` now rejects dangerous attribute-name writes (`on*`, `style`) and `javascript:` / `data:` / `vbscript:` / `file:` URLs on `href` / `src` / `action` / `formaction` / `xlink:href`; `innerHTML` assignments are sanitised through a throwaway DOMParser document (stripping `<script>`, `<iframe>`, `<object>`, `<embed>`, `<link>`, `<meta>`, `<base>`, `<style>` plus event handlers and dangerous URL schemes). Legitimate translation formatting (`<b>`, `<em>`, `<strong>`, `<a href="https://…">`, etc.) passes through. 3. **CSS-injection** — `handleRequestPopupChanges` now requires `containerStyle.height` / `.width` to match a strict CSS length pattern; malformed values are dropped silently. ### Workarounds No workaround short of upgrading. ### Credits Discovered via an internal security audit of the locize ecosystem.

CVE-2026-41886 Affected locize Client SDK Versions

1 component(s)
Fixed Versions:
4.0.21
Product / Package Ecosystem Affected Versions Fixed Version
locize
npm
< 4.0.21
4.0.21

References

Frequently Asked Questions

What is CVE-2026-41886?
CVE-2026-41886 is a security vulnerability in locize Client SDK involving Cross-origin DOM XSS & Handler Hijack Through Missing e.origin Validation in InContext Editor under CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting').
Which locize Client SDK versions are affected?
Affected versions include releases prior to 4.0.21 across affected packages: locize.
What version fixes CVE-2026-41886?
Upgrading to 4.0.21 (or the latest patched release for your respective branch) resolves the vulnerability.
Is locize affected?
Yes, locize is affected in releases prior to 4.0.21. Upgrade your dependency to 4.0.21 or later.
What is the CVSS score of CVE-2026-41886?
CVE-2026-41886 has a CVSS v3.1 base score of 7.5 (HIGH) with vector string CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:L/I:H/A:L.
What CWE is associated with CVE-2026-41886?
CVE-2026-41886 is classified under CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.).
How can I check npm dependencies for CVE-2026-41886?
Run the dependency tree command: 'npm ls locize'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-w937-fg2h-xhq2",
  "modified" : "2026-05-13T13:30:12Z",
  "published" : "2026-04-22T20:32:11Z",
  "aliases" : [ "CVE-2026-41886" ],
  "summary" : "locize Client SDK: Cross-origin DOM XSS & Handler Hijack Through Missing e.origin Validation in InContext Editor ",
  "details" : "### Summary\n\nVersions of the `locize` client SDK (the browser module that wires up the locize InContext translation editor) prior to 4.0.21 register a `window.addEventListener(\"message\", …)` handler that dispatches to registered internal handlers (`editKey`, `commitKey`, `commitKeys`, `isLocizeEnabled`, `requestInitialize`, …) **without validating `event.origin`**.\n\nThe pre-patch listener in `src/api/postMessage.js` gates dispatch on `event.data.sender === \"i18next-editor-frame\"` — that value sits inside the attacker-controlled message payload, not the browser-enforced origin. Any web page that could embed or be embedded by a locize-enabled host — an iframe on a third-party page, a `window.open`-ed victim, a parent frame reaching down — could send a crafted `postMessage` and trigger the internal handlers.\n\n### Impact\n\nDepending on which handler the attacker invokes, distinct consequences follow. All of them share the same root cause: the handlers implicitly assumed the payload came from the real editor iframe.\n\n- **Cross-origin DOM XSS** via `editKey` / `commitKeys`: the pre-patch `handleEditKey` assigned attacker-controlled payload values to `item.node.innerHTML` and to `item.node.setAttribute(attr, value)`. That allowed planting `<script>`, `<img onerror>`, or `onclick`/`onload`/`onfocus` event handlers; and on attribute writes, `href=\"javascript:…\"` / `src=\"data:text/html,<script>…\"` / `style=\"…\"` / etc.\n\n- **`api.source` / `api.origin` hijack** via `isLocizeEnabled`: the handler set `api.source = e.source; api.origin = e.origin` — attacker-controlled values. All subsequent `sendMessage` calls (which post translations, callbacks, etc., back toward `api.source`) would go to the attacker window rather than the real editor, leaking translation content and any metadata the SDK forwards.\n\n- **CSS-injection / layout-escape** via `requestPopupChanges`: `containerStyle.height` / `.width` were interpolated into `calc()` expressions and `popup.style.setProperty()` without validation, allowing attackers to inject additional CSS declarations (semicolons, `behavior:url()` on legacy IE, CSS-exfil patterns) into the popup inline style.\n\nExploitation requires the attacker-owned page to share a window reference with the locize-enabled host: typical vectors are an `iframe` on an attacker-controlled page, a `window.opener`/`window.open` relationship, or a parent frame that can `postMessage` into an embedded locize host. The SDK intended model is that only the editor iframe at `https://incontext.locize.app` (or the configured staging/development origin) can reach these handlers.\n\n### Affected versions\n\nAll versions of `locize` prior to **4.0.21**.\n\n### Patch\n\nFixed in **4.0.21**. Two layers:\n\n1. **Primary** — validate `event.origin` at the top of `window.addEventListener(\"message\", …)` in `src/api/postMessage.js`. The expected origin is the configured iframe origin (`getIframeUrl()`), so custom environments continue to work. Messages from any other origin are silently dropped before any handler runs.\n\n2. **Defence-in-depth** — `handleEditKey` now rejects dangerous attribute-name writes (`on*`, `style`) and `javascript:` / `data:` / `vbscript:` / `file:` URLs on `href` / `src` / `action` / `formaction` / `xlink:href`; `innerHTML` assignments are sanitised through a throwaway DOMParser document (stripping `<script>`, `<iframe>`, `<object>`, `<embed>`, `<link>`, `<meta>`, `<base>`, `<style>` plus event handlers and dangerous URL schemes). Legitimate translation formatting (`<b>`, `<em>`, `<strong>`, `<a href=\"https://…\">`, etc.) passes through.\n\n3. **CSS-injection** — `handleRequestPopupChanges` now requires `containerStyle.height` / `.width` to match a strict CSS length pattern; malformed values are dropped silently.\n\n### Workarounds\n\nNo workaround short of upgrading.\n\n### Credits\n\nDiscovered via an internal security audit of the locize ecosystem.",
  "severity" : [ {
    "type" : "CVSS_V3",
    "score" : "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:L/I:H/A:L"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "npm",
      "name" : "locize"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0"
      }, {
        "fixed" : "4.0.21"
      } ]
    } ]
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/locize/locize/security/advisories/GHSA-w937-fg2h-xhq2"
  }, {
    "type" : "ADVISORY",
    "url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-41886"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/locize/locize/commit/d006b75fadb8e8ab77b023e462850fc6e9170735"
  }, {
    "type" : "WEB",
    "url" : "https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage#security_concerns"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/locize/locize"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/locize/locize/releases/tag/v4.0.21"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-346", "CWE-79" ],
    "severity" : "HIGH",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-04-22T20:32:11Z",
    "nvd_published_at" : "2026-05-08T16:16:12Z"
  }
}