GHSA-JMR7-XGP7-CMFJ

Vulnerability from github – Published: 2026-02-17 21:30 – Updated: 2026-02-19 21:56
VLAI?
Summary
fast-xml-parser affected by DoS through entity expansion in DOCTYPE (no expansion limit)
Details

Summary

The XML parser can be forced to do an unlimited amount of entity expansion. With a very small XML input, it’s possible to make the parser spend seconds or even minutes processing a single request, effectively freezing the application.

Details

There is a check in DocTypeReader.js that tries to prevent entity expansion attacks by rejecting entities that reference other entities (it looks for & inside entity values). This does stop classic “Billion Laughs” payloads.

However, it doesn’t stop a much simpler variant.

If you define one large entity that contains only raw text (no & characters) and then reference it many times, the parser will happily expand it every time. There is no limit on how large the expanded result can become, or how many replacements are allowed.

The problem is in replaceEntitiesValue() inside OrderedObjParser.js. It repeatedly runs val.replace() in a loop, without any checks on total output size or execution cost. As the entity grows or the number of references increases, parsing time explodes.

Relevant code:

DocTypeReader.js (lines 28–33): entity registration only checks for &

OrderedObjParser.js (lines 439–458): entity replacement loop with no limits

PoC

const { XMLParser } = require('fast-xml-parser');

const entity = 'A'.repeat(1000);
const refs = '&big;'.repeat(100);
const xml = `<!DOCTYPE foo [<!ENTITY big "${entity}">]><root>${refs}</root>`;

console.time('parse');
new XMLParser().parse(xml); // ~4–8 seconds for ~1.3 KB of XML
console.timeEnd('parse');

// 5,000 chars × 100 refs takes 200+ seconds
// 50,000 chars × 1,000 refs will hang indefinitely

Impact

This is a straightforward denial-of-service issue.

Any service that parses user-supplied XML using the default configuration is vulnerable. Since Node.js runs on a single thread, the moment the parser starts expanding entities, the event loop is blocked. While this is happening, the server can’t handle any other requests.

In testing, a payload of only a few kilobytes was enough to make a simple HTTP server completely unresponsive for several minutes, with all other requests timing out.

Workaround

Avoid using DOCTYPE parsing by processEntities: false option.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "fast-xml-parser"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "4.1.3"
            },
            {
              "fixed": "5.3.6"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-26278"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-776"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-02-17T21:30:10Z",
    "nvd_published_at": "2026-02-19T20:25:43Z",
    "severity": "HIGH"
  },
  "details": "### Summary\nThe XML parser can be forced to do an unlimited amount of entity expansion. With a very small XML input, it\u2019s possible to make the parser spend seconds or even minutes processing a single request, effectively freezing the application.\n\n### Details\nThere is a check in `DocTypeReader.js` that tries to prevent entity expansion attacks by rejecting entities that reference other entities (it looks for \u0026 inside entity values). This does stop classic \u201cBillion Laughs\u201d payloads.\n\nHowever, it doesn\u2019t stop a much simpler variant.\n\nIf you define one large entity that contains only raw text (no \u0026 characters) and then reference it many times, the parser will happily expand it every time. There is no limit on how large the expanded result can become, or how many replacements are allowed.\n\nThe problem is in `replaceEntitiesValue()` inside `OrderedObjParser.js`. It repeatedly runs `val.replace()` in a loop, without any checks on total output size or execution cost. As the entity grows or the number of references increases, parsing time explodes.\n\nRelevant code:\n\n`DocTypeReader.js` (lines 28\u201333): entity registration only checks for \u0026\n\n`OrderedObjParser.js` (lines 439\u2013458): entity replacement loop with no limits\n\n### PoC\n\n```js\nconst { XMLParser } = require(\u0027fast-xml-parser\u0027);\n\nconst entity = \u0027A\u0027.repeat(1000);\nconst refs = \u0027\u0026big;\u0027.repeat(100);\nconst xml = `\u003c!DOCTYPE foo [\u003c!ENTITY big \"${entity}\"\u003e]\u003e\u003croot\u003e${refs}\u003c/root\u003e`;\n\nconsole.time(\u0027parse\u0027);\nnew XMLParser().parse(xml); // ~4\u20138 seconds for ~1.3 KB of XML\nconsole.timeEnd(\u0027parse\u0027);\n\n// 5,000 chars \u00d7 100 refs takes 200+ seconds\n// 50,000 chars \u00d7 1,000 refs will hang indefinitely\n```\n\n### Impact\nThis is a straightforward denial-of-service issue.\n\nAny service that parses user-supplied XML using the default configuration is vulnerable. Since Node.js runs on a single thread, the moment the parser starts expanding entities, the event loop is blocked. While this is happening, the server can\u2019t handle any other requests.\n\nIn testing, a payload of only a few kilobytes was enough to make a simple HTTP server completely unresponsive for several minutes, with all other requests timing out.\n\n### Workaround\n\nAvoid using DOCTYPE parsing by `processEntities: false` option.",
  "id": "GHSA-jmr7-xgp7-cmfj",
  "modified": "2026-02-19T21:56:54Z",
  "published": "2026-02-17T21:30:10Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/NaturalIntelligence/fast-xml-parser/security/advisories/GHSA-jmr7-xgp7-cmfj"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-26278"
    },
    {
      "type": "WEB",
      "url": "https://github.com/NaturalIntelligence/fast-xml-parser/commit/910dae5be2de2955e968558fadf6e8f74f117a77"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/NaturalIntelligence/fast-xml-parser"
    },
    {
      "type": "WEB",
      "url": "https://github.com/NaturalIntelligence/fast-xml-parser/releases/tag/v5.3.6"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "fast-xml-parser affected by DoS through entity expansion in DOCTYPE (no expansion limit)"
}


Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Sightings

Author Source Type Date

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.


Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…