Package Instance
Lookup for vulnerable packages by Package URL.
GET /api/packages/1039992?format=api
{ "url": "http://public2.vulnerablecode.io/api/packages/1039992?format=api", "purl": "pkg:npm/locize@2.2.1", "type": "npm", "namespace": "", "name": "locize", "version": "2.2.1", "qualifiers": {}, "subpath": "", "is_vulnerable": true, "next_non_vulnerable_version": "4.0.21", "latest_non_vulnerable_version": "4.0.21", "affected_by_vulnerabilities": [ { "url": "http://public2.vulnerablecode.io/api/vulnerabilities/90266?format=api", "vulnerability_id": "VCID-12fk-8y8g-bffe", "summary": "locize Client SDK: Cross-origin DOM XSS & Handler Hijack Through Missing e.origin Validation in InContext Editor\n### 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.", "references": [ { "reference_url": "https://api.first.org/data/v1/epss?cve=CVE-2026-41886", "reference_id": "", "reference_type": "", "scores": [ { "value": "0.00016", "scoring_system": "epss", "scoring_elements": "0.03982", "published_at": "2026-06-05T12:55:00Z" }, { "value": "0.00016", "scoring_system": "epss", "scoring_elements": "0.03939", "published_at": "2026-06-08T12:55:00Z" }, { "value": "0.00016", "scoring_system": "epss", "scoring_elements": "0.03967", "published_at": "2026-06-07T12:55:00Z" }, { "value": "0.00016", "scoring_system": "epss", "scoring_elements": "0.03979", "published_at": "2026-06-06T12:55:00Z" }, { "value": "0.00018", "scoring_system": "epss", "scoring_elements": "0.04764", "published_at": "2026-06-09T12:55:00Z" } ], "url": "https://api.first.org/data/v1/epss?cve=CVE-2026-41886" }, { "reference_url": "https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage#security_concerns", "reference_id": "", "reference_type": "", "scores": [ { "value": "7.5", "scoring_system": "cvssv3.1", "scoring_elements": "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:L/I:H/A:L" }, { "value": "HIGH", "scoring_system": "generic_textual", "scoring_elements": "" } ], "url": "https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage#security_concerns" }, { "reference_url": "https://github.com/locize/locize", "reference_id": "", "reference_type": "", "scores": [ { "value": "7.5", "scoring_system": "cvssv3.1", "scoring_elements": "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:L/I:H/A:L" }, { "value": "HIGH", "scoring_system": "generic_textual", "scoring_elements": "" } ], "url": "https://github.com/locize/locize" }, { "reference_url": "https://github.com/locize/locize/commit/d006b75fadb8e8ab77b023e462850fc6e9170735", "reference_id": "", "reference_type": "", "scores": [ { "value": "7.5", "scoring_system": "cvssv3.1", "scoring_elements": "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:L/I:H/A:L" }, { "value": "HIGH", "scoring_system": "generic_textual", "scoring_elements": "" } ], "url": "https://github.com/locize/locize/commit/d006b75fadb8e8ab77b023e462850fc6e9170735" }, { "reference_url": "https://github.com/locize/locize/releases/tag/v4.0.21", "reference_id": "", "reference_type": "", "scores": [ { "value": "7.5", "scoring_system": "cvssv3.1", "scoring_elements": "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:L/I:H/A:L" }, { "value": "HIGH", "scoring_system": "generic_textual", "scoring_elements": "" }, { "value": "Track", "scoring_system": "ssvc", "scoring_elements": "SSVCv2/E:N/A:N/T:P/P:M/B:A/M:M/D:T/2026-05-08T17:09:37Z/" } ], "url": "https://github.com/locize/locize/releases/tag/v4.0.21" }, { "reference_url": "https://github.com/locize/locize/security/advisories/GHSA-w937-fg2h-xhq2", "reference_id": "", "reference_type": "", "scores": [ { "value": "7.5", "scoring_system": "cvssv3.1", "scoring_elements": "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:L/I:H/A:L" }, { "value": "HIGH", "scoring_system": "cvssv3.1_qr", "scoring_elements": "" }, { "value": "HIGH", "scoring_system": "generic_textual", "scoring_elements": "" }, { "value": "Track", "scoring_system": "ssvc", "scoring_elements": "SSVCv2/E:N/A:N/T:P/P:M/B:A/M:M/D:T/2026-05-08T17:09:37Z/" } ], "url": "https://github.com/locize/locize/security/advisories/GHSA-w937-fg2h-xhq2" }, { "reference_url": "https://nvd.nist.gov/vuln/detail/CVE-2026-41886", "reference_id": "", "reference_type": "", "scores": [ { "value": "7.5", "scoring_system": "cvssv3.1", "scoring_elements": "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:L/I:H/A:L" }, { "value": "HIGH", "scoring_system": "generic_textual", "scoring_elements": "" } ], "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-41886" }, { "reference_url": "https://github.com/advisories/GHSA-w937-fg2h-xhq2", "reference_id": "GHSA-w937-fg2h-xhq2", "reference_type": "", "scores": [ { "value": "HIGH", "scoring_system": "cvssv3.1_qr", "scoring_elements": "" } ], "url": "https://github.com/advisories/GHSA-w937-fg2h-xhq2" } ], "fixed_packages": [ { "url": "http://public2.vulnerablecode.io/api/packages/111557?format=api", "purl": "pkg:npm/locize@4.0.21", "is_vulnerable": false, "affected_by_vulnerabilities": [], "resource_url": "http://public2.vulnerablecode.io/packages/pkg:npm/locize@4.0.21" } ], "aliases": [ "CVE-2026-41886", "GHSA-w937-fg2h-xhq2" ], "risk_score": 4.0, "exploitability": "0.5", "weighted_severity": "8.0", "resource_url": "http://public2.vulnerablecode.io/vulnerabilities/VCID-12fk-8y8g-bffe" } ], "fixing_vulnerabilities": [], "risk_score": "4.0", "resource_url": "http://public2.vulnerablecode.io/packages/pkg:npm/locize@2.2.1" }