CWE-116
Allowed-with-ReviewImproper Encoding or Escaping of Output
Abstraction: Class · Status: Draft
The product prepares a structured message for communication with another component, but encoding or escaping of the data is either missing or done incorrectly. As a result, the intended structure of the message is not preserved.
805 vulnerabilities reference this CWE, most recent first.
GHSA-63FR-HQMM-7X7R
Vulnerability from github – Published: 2024-01-24 18:31 – Updated: 2024-01-24 18:31Dell Unity, versions prior to 5.4, contain a vulnerability whereby log messages can be spoofed by an authenticated attacker. An attacker could exploit this vulnerability to forge log entries, create false alarms, and inject malicious content into logs that compromise logs integrity. A malicious attacker could also prevent the product from logging information while malicious actions are performed or implicate an arbitrary user for malicious activities.
{
"affected": [],
"aliases": [
"CVE-2024-22229"
],
"database_specific": {
"cwe_ids": [
"CWE-116",
"CWE-117"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-01-24T17:15:08Z",
"severity": "LOW"
},
"details": "\nDell Unity, versions prior to 5.4, contain a vulnerability whereby log messages can be spoofed by an authenticated attacker. An attacker could exploit this vulnerability to forge log entries, create false alarms, and inject malicious content into logs that compromise logs integrity. A malicious attacker could also prevent the product from logging information while malicious actions are performed or implicate an arbitrary user for malicious activities.\n\n",
"id": "GHSA-63fr-hqmm-7x7r",
"modified": "2024-01-24T18:31:01Z",
"published": "2024-01-24T18:31:01Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-22229"
},
{
"type": "WEB",
"url": "https://www.dell.com/support/kbdoc/en-us/000213152/dsa-2023-141-dell-unity-unity-vsa-and-unity-xt-security-update-for-multiple-vulnerabilities"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-63XF-X242-85MQ
Vulnerability from github – Published: 2022-05-24 17:31 – Updated: 2022-05-24 17:31BigBlueButton before 2.3 does not implement LibreOffice sandboxing. This might make it easier for remote authenticated users to read the API shared secret in the bigbluebutton.properties file. With the API shared secret, an attacker can (for example) use api/join to join an arbitrary meeting regardless of its guestPolicy setting.
{
"affected": [],
"aliases": [
"CVE-2020-27604"
],
"database_specific": {
"cwe_ids": [
"CWE-116"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2020-10-21T15:15:00Z",
"severity": "MODERATE"
},
"details": "BigBlueButton before 2.3 does not implement LibreOffice sandboxing. This might make it easier for remote authenticated users to read the API shared secret in the bigbluebutton.properties file. With the API shared secret, an attacker can (for example) use api/join to join an arbitrary meeting regardless of its guestPolicy setting.",
"id": "GHSA-63xf-x242-85mq",
"modified": "2022-05-24T17:31:44Z",
"published": "2022-05-24T17:31:44Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2020-27604"
},
{
"type": "WEB",
"url": "https://docs.bigbluebutton.org/dev/api.html"
},
{
"type": "WEB",
"url": "https://www.golem.de/news/big-blue-button-das-grosse-blaue-sicherheitsrisiko-2010-151610.html"
}
],
"schema_version": "1.4.0",
"severity": []
}
GHSA-6437-GXHQ-PQV8
Vulnerability from github – Published: 2026-09-03 18:08 – Updated: 2026-09-03 18:08Summary
orval's zod client emits each header parameter name as a double-quoted key in the generated zod.object({...}) request-validation schema WITHOUT escaping the double quote. A " in the header parameter name closes the key and lands in object-literal context, where an injected computed property key [expr] is evaluated when zod.object({...}) runs -- at MODULE IMPORT (export const OpHeader = zod.object({...}) executes on load) -> import-time RCE. The header parameter name is a pure data field. Verified on orval 8.19.0 / Node.
Details
export const OpHeader = zod.object({ "a":zod.string(),[require("fs").writeFileSync("PWNED","")]:zod.string(),"b": ... })
Also affects the hono client (reuses zod generation). orval escapes values in zod arrays but not keys in zod.object. Sibling fields: schema property name, query parameter name (CVE-96) (separate reports). Distinct from orval's $ref / route-path / server-url / zod-default findings.
PoC
reproduce.sh (+ make_spec.py) attached: a header parameter name that breaks the zod.object key and injects a computed key; evaluating it (= importing the module) writes the marker. Verified on 8.19.0.
Impact
JavaScript / OS command execution at import time for anyone who generates an orval zod client from an attacker-controlled spec and imports it.
Suggested fix
Escape the header parameter name for the JS string key (JSON.stringify) in the zod.object key generation; never interpolate a raw name adjacent to [ ] in object-literal position.
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "orval"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "8.21.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-71864"
],
"database_specific": {
"cwe_ids": [
"CWE-116",
"CWE-94",
"CWE-95"
],
"github_reviewed": true,
"github_reviewed_at": "2026-09-03T18:08:31Z",
"nvd_published_at": "2026-08-19T18:17:23Z",
"severity": "CRITICAL"
},
"details": "### Summary\n\norval\u0027s zod client emits each header parameter name as a double-quoted key in the generated zod.object({...}) request-validation schema WITHOUT escaping the double quote. A \" in the header parameter name closes the key and lands in object-literal context, where an injected computed property key [expr] is evaluated when zod.object({...}) runs -- at MODULE IMPORT (export const OpHeader = zod.object({...}) executes on load) -\u003e import-time RCE. The header parameter name is a pure data field. Verified on orval 8.19.0 / Node.\n\n### Details\n\nexport const OpHeader = zod.object({ \"a\":zod.string(),[require(\"fs\").writeFileSync(\"PWNED\",\"\")]:zod.string(),\"b\": ... })\n\nAlso affects the hono client (reuses zod generation). orval escapes values in zod arrays but not keys in zod.object. Sibling fields: schema property name, query parameter name (CVE-96) (separate reports). Distinct from orval\u0027s $ref / route-path / server-url / zod-default findings.\n\n### PoC\n\nreproduce.sh (+ make_spec.py) attached: a header parameter name that breaks the zod.object key and injects a computed key; evaluating it (= importing the module) writes the marker. Verified on 8.19.0.\n\n### Impact\n\nJavaScript / OS command execution at import time for anyone who generates an orval zod client from an attacker-controlled spec and imports it. \n\n### Suggested fix\n\nEscape the header parameter name for the JS string key (JSON.stringify) in the zod.object key generation; never interpolate a raw name adjacent to [ ] in object-literal position.",
"id": "GHSA-6437-gxhq-pqv8",
"modified": "2026-09-03T18:08:31Z",
"published": "2026-09-03T18:08:31Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/orval-labs/orval/security/advisories/GHSA-6437-gxhq-pqv8"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-71864"
},
{
"type": "WEB",
"url": "https://github.com/orval-labs/orval/pull/3692"
},
{
"type": "WEB",
"url": "https://github.com/orval-labs/orval/commit/8ef1bfdf3f9bcaf9dabfbe2e42887f1c0e159ab6"
},
{
"type": "PACKAGE",
"url": "https://github.com/orval-labs/orval"
},
{
"type": "WEB",
"url": "https://github.com/orval-labs/orval/releases/tag/v8.21.0"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "Orval: Import-time RCE via header parameter name -\u003e computed-property-key injection in the zod client"
}
GHSA-653Q-5476-X79G
Vulnerability from github – Published: 2026-09-03 18:18 – Updated: 2026-09-03 18:18Summary
orval's zod client emits each query parameter name as a double-quoted key in the generated zod.object({...}) request-validation schema WITHOUT escaping the double quote. A " in the query parameter name closes the key and lands in object-literal context, where an injected computed property key [expr] is evaluated when zod.object({...}) runs -- at MODULE IMPORT (export const OpQueryParams = zod.object({...}) executes on load) -> import-time RCE. The query parameter name is a pure data field. Verified on orval 8.19.0 / Node.
Details
export const OpQueryParams = zod.object({ "a":zod.string(),[require("fs").writeFileSync("PWNED","")]:zod.string(),"b": ... })
Also affects the hono client (reuses zod generation). orval escapes values in zod arrays but not keys in zod.object. Sibling fields: schema property name, header parameter name (CVE-97) (separate reports). Distinct from orval's $ref / route-path / server-url / zod-default findings.
PoC
reproduce.sh (+ make_spec.py) attached: a query parameter name that breaks the zod.object key and injects a computed key; evaluating it (= importing the module) writes the marker. Verified on 8.19.0.
Impact
JavaScript / OS command execution at import time for anyone who generates an orval zod client from an attacker-controlled spec and imports it.
Suggested fix
Escape the query parameter name for the JS string key (JSON.stringify) in the zod.object key generation; never interpolate a raw name adjacent to [ ] in object-literal position. maintainer-report.txt make_spec.py reproduce.sh
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "orval"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "8.21.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-71865"
],
"database_specific": {
"cwe_ids": [
"CWE-116",
"CWE-94",
"CWE-95"
],
"github_reviewed": true,
"github_reviewed_at": "2026-09-03T18:18:09Z",
"nvd_published_at": "2026-08-19T18:17:23Z",
"severity": "CRITICAL"
},
"details": "### Summary\n\norval\u0027s zod client emits each query parameter name as a double-quoted key in the generated zod.object({...}) request-validation schema WITHOUT escaping the double quote. A \" in the query parameter name closes the key and lands in object-literal context, where an injected computed property key [expr] is evaluated when zod.object({...}) runs -- at MODULE IMPORT (export const OpQueryParams = zod.object({...}) executes on load) -\u003e import-time RCE. The query parameter name is a pure data field. Verified on orval 8.19.0 / Node.\n\n### Details\n\nexport const OpQueryParams = zod.object({ \"a\":zod.string(),[require(\"fs\").writeFileSync(\"PWNED\",\"\")]:zod.string(),\"b\": ... })\n\nAlso affects the hono client (reuses zod generation). orval escapes values in zod arrays but not keys in zod.object. Sibling fields: schema property name, header parameter name (CVE-97) (separate reports). Distinct from orval\u0027s $ref / route-path / server-url / zod-default findings.\n\n### PoC\n\nreproduce.sh (+ make_spec.py) attached: a query parameter name that breaks the zod.object key and injects a computed key; evaluating it (= importing the module) writes the marker. Verified on 8.19.0.\n\n### Impact\n\nJavaScript / OS command execution at import time for anyone who generates an orval zod client from an attacker-controlled spec and imports it.\n\n### Suggested fix\n\nEscape the query parameter name for the JS string key (JSON.stringify) in the zod.object key generation; never interpolate a raw name adjacent to [ ] in object-literal position. [maintainer-report.txt](https://github.com/user-attachments/files/29426090/maintainer-report.txt) [make_spec.py](https://github.com/user-attachments/files/29426091/make_spec.py) [reproduce.sh](https://github.com/user-attachments/files/29426092/reproduce.sh)",
"id": "GHSA-653q-5476-x79g",
"modified": "2026-09-03T18:18:09Z",
"published": "2026-09-03T18:18:09Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/orval-labs/orval/security/advisories/GHSA-653q-5476-x79g"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-71865"
},
{
"type": "WEB",
"url": "https://github.com/orval-labs/orval/pull/3692"
},
{
"type": "WEB",
"url": "https://github.com/orval-labs/orval/commit/8ef1bfdf3f9bcaf9dabfbe2e42887f1c0e159ab6"
},
{
"type": "PACKAGE",
"url": "https://github.com/orval-labs/orval"
},
{
"type": "WEB",
"url": "https://github.com/orval-labs/orval/releases/tag/v8.21.0"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "Orval: Import-time RCE via query parameter name -\u003e computed-property-key injection in the zod cli"
}
GHSA-675Q-G72P-GC3C
Vulnerability from github – Published: 2021-12-10 00:00 – Updated: 2021-12-15 00:01Apache Airavata Django Portal allows CRLF log injection because of lack of escaping log statements. In particular, some HTTP request parameters are logged without first being escaped. Versions affected: master branch before commit 3c5d8c7 [1] of airavata-django-portal [1] https://github.com/apache/airavata-django-portal/commit/3c5d8c72bfc3eb0af8693a655a5d60f9273f8170
{
"affected": [],
"aliases": [
"CVE-2021-43410"
],
"database_specific": {
"cwe_ids": [
"CWE-116"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2021-12-09T09:15:00Z",
"severity": "MODERATE"
},
"details": "Apache Airavata Django Portal allows CRLF log injection because of lack of escaping log statements. In particular, some HTTP request parameters are logged without first being escaped. Versions affected: master branch before commit 3c5d8c7 [1] of airavata-django-portal [1] https://github.com/apache/airavata-django-portal/commit/3c5d8c72bfc3eb0af8693a655a5d60f9273f8170",
"id": "GHSA-675q-g72p-gc3c",
"modified": "2021-12-15T00:01:44Z",
"published": "2021-12-10T00:00:47Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-43410"
},
{
"type": "WEB",
"url": "https://lists.apache.org/thread/q64h16ofdxk29soz3jj561nysnzcrl31"
}
],
"schema_version": "1.4.0",
"severity": []
}
GHSA-67P3-VGWG-JFJF
Vulnerability from github – Published: 2023-10-30 00:30 – Updated: 2023-11-08 21:30HTML and SMTP injections on the registration page of LiquidFiles versions 3.7.13 and below, allow an attacker to perform more advanced phishing attacks against an organization.
{
"affected": [],
"aliases": [
"CVE-2023-4393"
],
"database_specific": {
"cwe_ids": [
"CWE-116",
"CWE-20",
"CWE-74"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2023-10-30T00:15:39Z",
"severity": "MODERATE"
},
"details": "HTML and SMTP injections on the registration page of LiquidFiles versions 3.7.13 and below, allow an attacker to perform more advanced phishing attacks against an organization.",
"id": "GHSA-67p3-vgwg-jfjf",
"modified": "2023-11-08T21:30:33Z",
"published": "2023-10-30T00:30:17Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2023-4393"
},
{
"type": "WEB",
"url": "https://www.themissinglink.com.au/security-advisories/cve-2023-4393"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-6972-2GCX-5QWG
Vulnerability from github – Published: 2022-05-13 01:10 – Updated: 2022-05-13 01:10Improper neutralization of escape vulnerability in Log Exporter in Synology DiskStation Manager (DSM) before 6.1.6-15266 allows remote attackers to inject arbitrary content to have an unspecified impact by exporting an archive in CSV format.
{
"affected": [],
"aliases": [
"CVE-2018-8920"
],
"database_specific": {
"cwe_ids": [
"CWE-116"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2018-12-24T15:29:00Z",
"severity": "HIGH"
},
"details": "Improper neutralization of escape vulnerability in Log Exporter in Synology DiskStation Manager (DSM) before 6.1.6-15266 allows remote attackers to inject arbitrary content to have an unspecified impact by exporting an archive in CSV format.",
"id": "GHSA-6972-2gcx-5qwg",
"modified": "2022-05-13T01:10:20Z",
"published": "2022-05-13T01:10:20Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2018-8920"
},
{
"type": "WEB",
"url": "https://www.synology.com/security/advisory/Synology_SA_18_14"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-6CCH-F4WH-7HXC
Vulnerability from github – Published: 2023-02-16 21:30 – Updated: 2023-02-28 21:30Improper handling of Unicode encoding in source code to be compiled by the Intel(R) C++ Compiler Classic before version 2021.6 for Intel(R) oneAPI Toolkits before version 2022.2 may allow an unauthenticated user to potentially enable escalation of privilege via network access.
{
"affected": [],
"aliases": [
"CVE-2022-25987"
],
"database_specific": {
"cwe_ids": [
"CWE-116"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2023-02-16T20:15:00Z",
"severity": "CRITICAL"
},
"details": "Improper handling of Unicode encoding in source code to be compiled by the Intel(R) C++ Compiler Classic before version 2021.6 for Intel(R) oneAPI Toolkits before version 2022.2 may allow an unauthenticated user to potentially enable escalation of privilege via network access.",
"id": "GHSA-6cch-f4wh-7hxc",
"modified": "2023-02-28T21:30:18Z",
"published": "2023-02-16T21:30:27Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-25987"
},
{
"type": "WEB",
"url": "http://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00674.html"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-6GCW-W7CP-94G9
Vulnerability from github – Published: 2026-07-06 19:51 – Updated: 2026-07-06 19:51The comm utility in uutils coreutils silently corrupts data by performing lossy UTF-8 conversion on all output lines. The implementation uses String::from_utf8_lossy(), which replaces invalid UTF-8 byte sequences with the Unicode replacement character (U+FFFD). This behavior differs from GNU comm, which processes raw bytes and preserves the original input. This results in corrupted output when the utility is used to compare binary files or files using non-UTF-8 legacy encodings.
Zellic finding 3.34. Reported in the Zellic uutils coreutils Program Security Assessment (for Canonical, Jan 2026), audited commit 3a07ffc5a9bd4c283e75afa548ba1f1957bad242.
{
"affected": [
{
"package": {
"ecosystem": "crates.io",
"name": "uu_comm"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.6.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-35346"
],
"database_specific": {
"cwe_ids": [
"CWE-116",
"CWE-176"
],
"github_reviewed": true,
"github_reviewed_at": "2026-07-06T19:51:22Z",
"nvd_published_at": null,
"severity": "LOW"
},
"details": "The comm utility in uutils coreutils silently corrupts data by performing lossy UTF-8 conversion on all output lines. The implementation uses String::from_utf8_lossy(), which replaces invalid UTF-8 byte sequences with the Unicode replacement character (U+FFFD). This behavior differs from GNU comm, which processes raw bytes and preserves the original input. This results in corrupted output when the utility is used to compare binary files or files using non-UTF-8 legacy encodings.\n\n---\n_Zellic finding 3.34. Reported in the Zellic *uutils coreutils Program Security Assessment* (for Canonical, Jan 2026), audited commit `3a07ffc5a9bd4c283e75afa548ba1f1957bad242`._",
"id": "GHSA-6gcw-w7cp-94g9",
"modified": "2026-07-06T19:51:22Z",
"published": "2026-07-06T19:51:22Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/uutils/coreutils/security/advisories/GHSA-6gcw-w7cp-94g9"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-35346"
},
{
"type": "WEB",
"url": "https://github.com/uutils/coreutils/issues/10192"
},
{
"type": "WEB",
"url": "https://github.com/uutils/coreutils/pull/10206"
},
{
"type": "WEB",
"url": "https://github.com/uutils/coreutils/commit/b9372e509ea9b278fe13763237067a261bb8c946"
},
{
"type": "PACKAGE",
"url": "https://github.com/uutils/coreutils"
},
{
"type": "WEB",
"url": "https://github.com/uutils/coreutils/releases/tag/0.6.0"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N",
"type": "CVSS_V3"
}
],
"summary": "comm: lossy UTF-8 conversion silently corrupts non-UTF-8 output"
}
GHSA-6GMQ-8VP8-GCM6
Vulnerability from github – Published: 2026-09-02 15:18 – Updated: 2026-09-02 15:18Summary
An EntityReference node can be created with an invalid, attacker-controlled name through Document.createEntityReference(name). When this node is serialized directly with:
serializer.serializeToString(ref, { requireWellFormed: true })
the invalid nodeName is emitted into the serialized XML fragment without validation or escaping.
This can produce real XML markup in the serialized output. In the proof of concept below, the serialized fragment contains <injected/>, and reparsing the fragment creates a real injected element.
Details
The issue appears to be in the serialization path for ENTITY_REFERENCE_NODE.
For several other node types, requireWellFormed: true performs specific validation checks before serialization. For example, comments, processing instructions, document types, and some character data cases are checked before being emitted.
However, for ENTITY_REFERENCE_NODE, the serializer appears to emit the node name directly in entity reference form:
case ENTITY_REFERENCE_NODE:
buf.push('&', n.nodeName, ';');
return null;
As a result, if nodeName contains characters that break out of the intended &name; structure, the serializer can emit additional XML markup.
For example, an entity reference created with the name:
safe; <injected/> &x
is serialized as:
&safe; <injected/> &x;
When this fragment is later parsed in an XML context, <injected/> becomes a real element.
This is especially surprising when { requireWellFormed: true } is used, because applications may reasonably treat this mode as the stricter or safer XML serialization mode.
Proof of Concept
Tested with:
@xmldom/xmldom@0.9.10
Node.js v24.18.0
Windows 10 / PowerShell
'use strict';
const { DOMImplementation, XMLSerializer, DOMParser } = require('@xmldom/xmldom');
const impl = new DOMImplementation();
const doc = impl.createDocument(null, 'root', null);
const serializer = new XMLSerializer();
function countInjected(fragment) {
try {
const parsed = new DOMParser().parseFromString(`<root>${fragment}</root>`, 'application/xml');
return parsed.getElementsByTagName('injected').length;
} catch (e) {
return `PARSE_THROW ${e.name}: ${e.message}`;
}
}
for (const name of [
'safe',
'safe; <injected/> &x',
'x<injected',
'x y'
]) {
try {
const ref = doc.createEntityReference(name);
const xml = serializer.serializeToString(ref, { requireWellFormed: true });
console.log(`[SERIALIZED] ${JSON.stringify(name)}: ${xml}`);
console.log(`[INJECTED_COUNT] ${JSON.stringify(name)}: ${countInjected(xml)}`);
} catch (e) {
console.log(`[THROW] ${JSON.stringify(name)}: ${e.name}: ${e.message}`);
}
}
Observed output:
[SERIALIZED] "safe": &safe;
[INJECTED_COUNT] "safe": 0
[SERIALIZED] "safe; <injected/> &x": &safe; <injected/> &x;
[INJECTED_COUNT] "safe; <injected/> &x": 1
[SERIALIZED] "x<injected": &x<injected;
[INJECTED_COUNT] "x<injected": 0
[SERIALIZED] "x y": &x y;
[INJECTED_COUNT] "x y": 0
Impact
An application that creates an EntityReference from attacker-controlled input and then serializes that node or XML fragment with requireWellFormed: true may produce XML containing attacker-controlled markup.
The impact is limited by two observations:
- The parser does not create
EntityReferencenodes from ordinary XML entity references. - Appending an
EntityReferencenode as an element child is rejected with aHierarchyRequestError.
The main affected scenario is applications that directly use createEntityReference(name) and then serialize the resulting node or fragment.
Fix Applied
Two complementary, non-breaking fixes.
(1) document.createEntityReference(name) rejects an invalid Name at creation, closing the reachable creation vector by default — the opt-in serializer check alone cannot, since a later nodeName mutation would bypass a creation-only guard.
(2) Under requireWellFormed, the serializer validates the EntityReference nodeName as a well-formed XML Name and throws InvalidStateError when it is not; a valid reference still serializes as &name;. Both ship on both maintained versions. The EntityReference / createEntityReference docs note that under requireWellFormed the nodeName is validated as an XML Name, and that xmldom does not expand entities. See the XML Name production.
⚠ Opt-in required. Protection is not automatic. Existing serialization calls remain vulnerable unless
{ requireWellFormed: true }is explicitly passed. Applications that serialize untrusted DOM content should audit allserializeToString()call sites and add it.
Proof of Concept - fixed path
'use strict';
const { DOMImplementation, XMLSerializer } = require('@xmldom/xmldom');
const impl = new DOMImplementation();
const doc = impl.createDocument(null, 'root', null);
const serializer = new XMLSerializer();
// Creation-time anchor (applied by default): an invalid XML Name is rejected at creation.
try {
doc.createEntityReference('safe; <injected/> &x');
} catch (e) {
console.log(`${e.name}`); // rejected at creation
}
// Default path (requireWellFormed omitted): because creation now rejects an ill-formed name,
// an ill-formed nodeName is only reachable via a post-creation mutation — and is emitted verbatim.
const ref = doc.createEntityReference('safe');
ref.nodeName = 'safe; <injected/> &x';
console.log(serializer.serializeToString(ref));
// -> &safe; <injected/> &x; (injection present on the default path)
// Opt-in path: throws on the invalid nodeName.
try {
serializer.serializeToString(ref, { requireWellFormed: true });
} catch (e) {
console.log(`${e.name}`); // InvalidStateError
}
// A valid name still serializes as &name; under requireWellFormed.
const ok = doc.createEntityReference('valid');
console.log(serializer.serializeToString(ok, { requireWellFormed: true }));
// -> &valid;
Why the default stays verbatim
The creation-time anchor is applied by default, because it is classified non-breaking. The serializer check, by contrast, stays gated behind { requireWellFormed: true }: W3C DOM Parsing's require-well-formed flag defaults to false, and the browser XMLSerializer emits the nodeName verbatim in that default mode, so unconditionally throwing for an ill-formed EntityReference.nodeName would be an unjustified breaking change — which is why the default serialization path stays verbatim.
Residual limitation
The creation vector is closed by default — the non-breaking creation-time anchor — with no further deferred work. The residual is at serialization: the default path still emits an ill-formed nodeName verbatim, because the serializer check is opt-in via { requireWellFormed: true }.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 0.8.14"
},
"package": {
"ecosystem": "npm",
"name": "@xmldom/xmldom"
},
"ranges": [
{
"events": [
{
"introduced": "0.7.0"
},
{
"fixed": "0.8.15"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 0.9.11"
},
"package": {
"ecosystem": "npm",
"name": "@xmldom/xmldom"
},
"ranges": [
{
"events": [
{
"introduced": "0.9.0"
},
{
"fixed": "0.9.12"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "npm",
"name": "xmldom"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"last_affected": "0.6.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-83610"
],
"database_specific": {
"cwe_ids": [
"CWE-116"
],
"github_reviewed": true,
"github_reviewed_at": "2026-09-02T15:18:20Z",
"nvd_published_at": "2026-09-01T15:17:39Z",
"severity": "MODERATE"
},
"details": "## Summary\n\nAn `EntityReference` node can be created with an invalid, attacker-controlled name through `Document.createEntityReference(name)`. When this node is serialized directly with:\n\n```js\nserializer.serializeToString(ref, { requireWellFormed: true })\n```\n\nthe invalid `nodeName` is emitted into the serialized XML fragment without validation or escaping.\n\nThis can produce real XML markup in the serialized output. In the proof of concept below, the serialized fragment contains `\u003cinjected/\u003e`, and reparsing the fragment creates a real `injected` element.\n\n---\n\n## Details\n\nThe issue appears to be in the serialization path for `ENTITY_REFERENCE_NODE`.\n\nFor several other node types, `requireWellFormed: true` performs specific validation checks before serialization. For example, comments, processing instructions, document types, and some character data cases are checked before being emitted.\n\nHowever, for `ENTITY_REFERENCE_NODE`, the serializer appears to emit the node name directly in entity reference form:\n\n```js\ncase ENTITY_REFERENCE_NODE:\n buf.push(\u0027\u0026\u0027, n.nodeName, \u0027;\u0027);\n return null;\n```\n\nAs a result, if `nodeName` contains characters that break out of the intended `\u0026name;` structure, the serializer can emit additional XML markup.\n\nFor example, an entity reference created with the name:\n\n```text\nsafe; \u003cinjected/\u003e \u0026x\n```\n\nis serialized as:\n\n```xml\n\u0026safe; \u003cinjected/\u003e \u0026x;\n```\n\nWhen this fragment is later parsed in an XML context, `\u003cinjected/\u003e` becomes a real element.\n\nThis is especially surprising when `{ requireWellFormed: true }` is used, because applications may reasonably treat this mode as the stricter or safer XML serialization mode.\n\n---\n\n## Proof of Concept\n\nTested with:\n\n```text\n@xmldom/xmldom@0.9.10\nNode.js v24.18.0\nWindows 10 / PowerShell\n```\n\n```js\n\u0027use strict\u0027;\n\nconst { DOMImplementation, XMLSerializer, DOMParser } = require(\u0027@xmldom/xmldom\u0027);\n\nconst impl = new DOMImplementation();\nconst doc = impl.createDocument(null, \u0027root\u0027, null);\nconst serializer = new XMLSerializer();\n\nfunction countInjected(fragment) {\n try {\n const parsed = new DOMParser().parseFromString(`\u003croot\u003e${fragment}\u003c/root\u003e`, \u0027application/xml\u0027);\n return parsed.getElementsByTagName(\u0027injected\u0027).length;\n } catch (e) {\n return `PARSE_THROW ${e.name}: ${e.message}`;\n }\n}\n\nfor (const name of [\n \u0027safe\u0027,\n \u0027safe; \u003cinjected/\u003e \u0026x\u0027,\n \u0027x\u003cinjected\u0027,\n \u0027x y\u0027\n]) {\n try {\n const ref = doc.createEntityReference(name);\n const xml = serializer.serializeToString(ref, { requireWellFormed: true });\n\n console.log(`[SERIALIZED] ${JSON.stringify(name)}: ${xml}`);\n console.log(`[INJECTED_COUNT] ${JSON.stringify(name)}: ${countInjected(xml)}`);\n } catch (e) {\n console.log(`[THROW] ${JSON.stringify(name)}: ${e.name}: ${e.message}`);\n }\n}\n```\n\nObserved output:\n\n```text\n[SERIALIZED] \"safe\": \u0026safe;\n[INJECTED_COUNT] \"safe\": 0\n\n[SERIALIZED] \"safe; \u003cinjected/\u003e \u0026x\": \u0026safe; \u003cinjected/\u003e \u0026x;\n[INJECTED_COUNT] \"safe; \u003cinjected/\u003e \u0026x\": 1\n\n[SERIALIZED] \"x\u003cinjected\": \u0026x\u003cinjected;\n[INJECTED_COUNT] \"x\u003cinjected\": 0\n\n[SERIALIZED] \"x y\": \u0026x y;\n[INJECTED_COUNT] \"x y\": 0\n```\n\n---\n\n## Impact\n\nAn application that creates an `EntityReference` from attacker-controlled input and then serializes that node or XML fragment with `requireWellFormed: true` may produce XML containing attacker-controlled markup.\n\nThe impact is limited by two observations:\n\n1. The parser does not create `EntityReference` nodes from ordinary XML entity references.\n2. Appending an `EntityReference` node as an element child is rejected with a `HierarchyRequestError`.\n\nThe main affected scenario is applications that directly use `createEntityReference(name)` and then serialize the resulting node or fragment.\n\n## Fix Applied\n\nTwo complementary, non-breaking fixes.\n(1) `document.createEntityReference(name)` rejects an invalid `Name` at creation, closing the reachable creation vector by default \u2014 the opt-in serializer check alone cannot, since a later `nodeName` mutation would bypass a creation-only guard.\n(2) Under `requireWellFormed`, the serializer validates the `EntityReference` `nodeName` as a well-formed XML `Name` and throws `InvalidStateError` when it is not; a valid reference still serializes as `\u0026name;`. Both ship on both maintained versions. The `EntityReference` / `createEntityReference` docs note that under `requireWellFormed` the `nodeName` is validated as an XML `Name`, and that xmldom does not expand entities. See the [XML `Name` production](https://www.w3.org/TR/xml/#NT-Name).\n\u003e **\u26a0 Opt-in required.** Protection is not automatic. Existing serialization calls remain\n\u003e vulnerable unless `{ requireWellFormed: true }` is explicitly passed. Applications that\n\u003e serialize untrusted DOM content should audit all `serializeToString()` call sites and add it.\n\n### Proof of Concept - fixed path\n\n```js\n\u0027use strict\u0027;\n\nconst { DOMImplementation, XMLSerializer } = require(\u0027@xmldom/xmldom\u0027);\n\nconst impl = new DOMImplementation();\nconst doc = impl.createDocument(null, \u0027root\u0027, null);\nconst serializer = new XMLSerializer();\n\n// Creation-time anchor (applied by default): an invalid XML Name is rejected at creation.\ntry {\n doc.createEntityReference(\u0027safe; \u003cinjected/\u003e \u0026x\u0027);\n} catch (e) {\n console.log(`${e.name}`); // rejected at creation\n}\n\n// Default path (requireWellFormed omitted): because creation now rejects an ill-formed name,\n// an ill-formed nodeName is only reachable via a post-creation mutation \u2014 and is emitted verbatim.\nconst ref = doc.createEntityReference(\u0027safe\u0027);\nref.nodeName = \u0027safe; \u003cinjected/\u003e \u0026x\u0027;\nconsole.log(serializer.serializeToString(ref));\n// -\u003e \u0026safe; \u003cinjected/\u003e \u0026x; (injection present on the default path)\n\n// Opt-in path: throws on the invalid nodeName.\ntry {\n serializer.serializeToString(ref, { requireWellFormed: true });\n} catch (e) {\n console.log(`${e.name}`); // InvalidStateError\n}\n\n// A valid name still serializes as \u0026name; under requireWellFormed.\nconst ok = doc.createEntityReference(\u0027valid\u0027);\nconsole.log(serializer.serializeToString(ok, { requireWellFormed: true }));\n// -\u003e \u0026valid;\n```\n\n### Why the default stays verbatim\n\nThe creation-time anchor is applied by default, because it is classified non-breaking. The serializer check, by contrast, stays gated behind `{ requireWellFormed: true }`: W3C DOM Parsing\u0027s require-well-formed flag defaults to `false`, and the browser `XMLSerializer` emits the `nodeName` verbatim in that default mode, so unconditionally throwing for an ill-formed `EntityReference.nodeName` would be an unjustified breaking change \u2014 which is why the default serialization path stays verbatim.\n\n### Residual limitation\n\nThe creation vector is closed by default \u2014 the non-breaking creation-time anchor \u2014 with no further deferred work. The residual is at serialization: the default path still emits an ill-formed `nodeName` verbatim, because the serializer check is opt-in via `{ requireWellFormed: true }`.",
"id": "GHSA-6gmq-8vp8-gcm6",
"modified": "2026-09-02T15:18:20Z",
"published": "2026-09-02T15:18:20Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/xmldom/xmldom/security/advisories/GHSA-6gmq-8vp8-gcm6"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-83610"
},
{
"type": "WEB",
"url": "https://github.com/xmldom/xmldom/pull/1071"
},
{
"type": "WEB",
"url": "https://github.com/xmldom/xmldom/pull/1072"
},
{
"type": "WEB",
"url": "https://github.com/xmldom/xmldom/commit/4664386e4f4d99d17b416a151dbe8323e245284b"
},
{
"type": "WEB",
"url": "https://github.com/xmldom/xmldom/commit/6c3fb5ffeafe7901ec928ce9010988dd716c94a0"
},
{
"type": "PACKAGE",
"url": "https://github.com/xmldom/xmldom"
},
{
"type": "WEB",
"url": "https://github.com/xmldom/xmldom/releases/tag/0.8.15"
},
{
"type": "WEB",
"url": "https://github.com/xmldom/xmldom/releases/tag/0.9.12"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "xmldom: XML fragment injection via invalid EntityReference.nodeName during requireWellFormed serialization"
}
Mitigation MIT-4.3
Strategy: Libraries or Frameworks
- Use a vetted library or framework that does not allow this weakness to occur or provides constructs that make this weakness easier to avoid.
- For example, consider using the ESAPI Encoding control [REF-45] or a similar tool, library, or framework. These will help the programmer encode outputs in a manner less prone to error.
- Alternately, use built-in functions, but consider using wrappers in case those functions are discovered to have a vulnerability.
Mitigation MIT-27
Strategy: Parameterization
- If available, use structured mechanisms that automatically enforce the separation between data and code. These mechanisms may be able to provide the relevant quoting, encoding, and validation automatically, instead of relying on the developer to provide this capability at every point where output is generated.
- For example, stored procedures can enforce database query structure and reduce the likelihood of SQL injection.
Mitigation
Understand the context in which your data will be used and the encoding that will be expected. This is especially important when transmitting data between different components, or when generating outputs that can contain multiple encodings at the same time, such as web pages or multi-part mail messages. Study all expected communication protocols and data representations to determine the required encoding strategies.
Mitigation
In some cases, input validation may be an important strategy when output encoding is not a complete solution. For example, you may be providing the same output that will be processed by multiple consumers that use different encodings or representations. In other cases, you may be required to allow user-supplied input to contain control information, such as limited HTML tags that support formatting in a wiki or bulletin board. When this type of requirement must be met, use an extremely strict allowlist to limit which control sequences can be used. Verify that the resulting syntactic structure is what you expect. Use your normal encoding methods for the remainder of the input.
Mitigation
Use input validation as a defense-in-depth measure to reduce the likelihood of output encoding errors (see CWE-20).
Mitigation
Fully specify which encodings are required by components that will be communicating with each other.
Mitigation
When exchanging data between components, ensure that both components are using the same character encoding. Ensure that the proper encoding is applied at each interface. Explicitly set the encoding you are using whenever the protocol allows you to do so.
CAPEC-104: Cross Zone Scripting
An attacker is able to cause a victim to load content into their web-browser that bypasses security zone controls and gain access to increased privileges to execute scripting code or other web objects such as unsigned ActiveX controls or applets. This is a privilege elevation attack targeted at zone-based web-browser security.
CAPEC-73: User-Controlled Filename
An attack of this type involves an adversary inserting malicious characters (such as a XSS redirection) into a filename, directly or indirectly that is then used by the target software to generate HTML text or other potentially executable content. Many websites rely on user-generated content and dynamically build resources like files, filenames, and URL links directly from user supplied data. In this attack pattern, the attacker uploads code that can execute in the client browser and/or redirect the client browser to a site that the attacker owns. All XSS attack payload variants can be used to pass and exploit these vulnerabilities.
CAPEC-81: Web Server Logs Tampering
Web Logs Tampering attacks involve an attacker injecting, deleting or otherwise tampering with the contents of web logs typically for the purposes of masking other malicious behavior. Additionally, writing malicious data to log files may target jobs, filters, reports, and other agents that process the logs in an asynchronous attack pattern. This pattern of attack is similar to "Log Injection-Tampering-Forging" except that in this case, the attack is targeting the logs of the web server and not the application.
CAPEC-85: AJAX Footprinting
This attack utilizes the frequent client-server roundtrips in Ajax conversation to scan a system. While Ajax does not open up new vulnerabilities per se, it does optimize them from an attacker point of view. A common first step for an attacker is to footprint the target environment to understand what attacks will work. Since footprinting relies on enumeration, the conversational pattern of rapid, multiple requests and responses that are typical in Ajax applications enable an attacker to look for many vulnerabilities, well-known ports, network locations and so on. The knowledge gained through Ajax fingerprinting can be used to support other attacks, such as XSS.