Common Weakness Enumeration

CWE-116

Allowed-with-Review

Improper 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:31
VLAI
Details

Dell 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.

Show details on source website

{
  "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:31
VLAI
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.

Show details on source website

{
  "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:08
VLAI
Summary
Orval: Import-time RCE via header parameter name -> computed-property-key injection in the zod client
Details

Summary

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.

Show details on source website

{
  "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:18
VLAI
Summary
Orval: Import-time RCE via query parameter name -> computed-property-key injection in the zod cli
Details

Summary

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

Show details on source website

{
  "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:01
VLAI
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

Show details on source website

{
  "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:30
VLAI
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.

Show details on source website

{
  "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:10
VLAI
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.

Show details on source website

{
  "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:30
VLAI
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.

Show details on source website

{
  "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:51
VLAI
Summary
comm: lossy UTF-8 conversion silently corrupts non-UTF-8 output
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.


Zellic finding 3.34. Reported in the Zellic uutils coreutils Program Security Assessment (for Canonical, Jan 2026), audited commit 3a07ffc5a9bd4c283e75afa548ba1f1957bad242.

Show details on source website

{
  "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:18
VLAI
Summary
xmldom: XML fragment injection via invalid EntityReference.nodeName during requireWellFormed serialization
Details

Summary

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:

  1. The parser does not create EntityReference nodes from ordinary XML entity references.
  2. Appending an EntityReference node as an element child is rejected with a HierarchyRequestError.

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 all serializeToString() 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 }.

Show details on source website

{
  "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
Architecture and Design

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
Architecture and Design

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
Architecture and Design Implementation

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
Architecture and Design

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
Architecture and Design

Use input validation as a defense-in-depth measure to reduce the likelihood of output encoding errors (see CWE-20).

Mitigation
Requirements

Fully specify which encodings are required by components that will be communicating with each other.

Mitigation
Implementation

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.