fast-xml-parser has RangeError DoS Numeric Entities Bug
Description
fast-xml-parser allows users to validate XML, parse XML to JS object, or build XML from JS object without C/C++ based libraries and no callback. In versions 5.0.9 through 5.3.3, a RangeError vulnerability exists in the numeric entity processing of fast-xml-parser when parsing XML with out-of-range entity code points (e.g., � or �). This causes the parser to throw an uncaught exception, crashing any application that processes untrusted XML input. Version 5.3.4 fixes the issue.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
fast-xml-parsernpm | >= 5.0.9, < 5.3.4 | 5.3.4 |
Affected products
1- Range: v5.0.9, v5.1.0, v5.2.0, …
Patches
14e387f61c4a5handle html entities when out of range
3 files changed · +39 −97
spec/entities_spec.js+22 −0 modified@@ -433,6 +433,28 @@ describe("XMLParser Entities", function() { expect(result).toEqual(expected); }); + it("should skip HTML numeric or hex entities when htmlEntities:true but entity is out of range", function() { + const xmlData = `<root attr="�">�</root>`; + + const expected = { + "root": { + "#text": "�", + "attr": "�" + } + }; + + const options = { + attributeNamePrefix: "", + ignoreAttributes: false, + processEntities: true, + htmlEntities: true, + }; + const parser = new XMLParser(options); + let result = parser.parse(xmlData); + + expect(result).toEqual(expected); + }); + it("should throw error if an entity name contains special char", function() { const xmlData = ` <?xml version="1.0" encoding="UTF-8"?>
spec/temp.js+5 −95 modified@@ -4,104 +4,14 @@ import { format } from "path"; import {XMLParser, XMLValidator, XMLBuilder} from "../src/fxp.js"; describe("unpaired and empty tags", function() { - xit("bug test", function() { + fit("bug test", function() { - const xmlData = `<?xml version="1.0"?> -<!DOCTYPE softwarelists [ -<!ELEMENT softwarelists (softwarelist*)> - <!ELEMENT softwarelist (notes?, software+)> - <!ATTLIST softwarelist name CDATA #REQUIRED> - <!ATTLIST softwarelist description CDATA #IMPLIED> - <!ELEMENT notes (#PCDATA)> - <!ELEMENT software (description, year, publisher, notes?, info*, sharedfeat*, part*)> - <!ATTLIST software name CDATA #REQUIRED> - <!ATTLIST software cloneof CDATA #IMPLIED> - <!ATTLIST software supported (yes|partial|no) "yes"> - <!ELEMENT description (#PCDATA)> - <!ELEMENT year (#PCDATA)> - <!ELEMENT publisher (#PCDATA)> - <!ELEMENT notes (#PCDATA)> - <!ELEMENT info EMPTY> - <!ATTLIST info name CDATA #REQUIRED> - <!ATTLIST info value CDATA #IMPLIED> - <!ELEMENT sharedfeat EMPTY> - <!ATTLIST sharedfeat name CDATA #REQUIRED> - <!ATTLIST sharedfeat value CDATA #IMPLIED> - <!ELEMENT part (feature*, dataarea*, diskarea*, dipswitch*)> - <!ATTLIST part name CDATA #REQUIRED> - <!ATTLIST part interface CDATA #REQUIRED> - <!ELEMENT feature EMPTY> - <!ATTLIST feature name CDATA #REQUIRED> - <!ATTLIST feature value CDATA #IMPLIED> - <!ELEMENT dataarea (rom*)> - <!ATTLIST dataarea name CDATA #REQUIRED> - <!ATTLIST dataarea size CDATA #REQUIRED> - <!ATTLIST dataarea databits (8|16|32|64) "8"> - <!ATTLIST dataarea endian (big|little) "little"> - <!ELEMENT rom EMPTY> - <!ATTLIST rom name CDATA #IMPLIED> - <!ATTLIST rom size CDATA #IMPLIED> - <!ATTLIST rom length CDATA #IMPLIED> - <!ATTLIST rom crc CDATA #IMPLIED> - <!ATTLIST rom sha1 CDATA #IMPLIED> - <!ATTLIST rom offset CDATA #IMPLIED> - <!ATTLIST rom value CDATA #IMPLIED> - <!ATTLIST rom status (baddump|nodump|good) "good"> - <!ATTLIST rom loadflag (load16_byte|load16_word|load16_word_swap|load32_byte|load32_word|load32_word_swap|load32_dword|load64_word|load64_word_swap|reload|fill|continue|reload_plain) #IMPLIED> - <!ELEMENT diskarea (disk*)> - <!ATTLIST diskarea name CDATA #REQUIRED> - <!ELEMENT disk EMPTY> - <!ATTLIST disk name CDATA #REQUIRED> - <!ATTLIST disk sha1 CDATA #IMPLIED> - <!ATTLIST disk status (baddump|nodump|good) "good"> - <!ATTLIST disk writeable (yes|no) "no"> - <!ELEMENT dipswitch (dipvalue*)> - <!ATTLIST dipswitch name CDATA #REQUIRED> - <!ATTLIST dipswitch tag CDATA #REQUIRED> - <!ATTLIST dipswitch mask CDATA #REQUIRED> - <!ELEMENT dipvalue EMPTY> - <!ATTLIST dipvalue name CDATA #REQUIRED> - <!ATTLIST dipvalue value CDATA #REQUIRED> - <!ATTLIST dipvalue default (yes|no) "no"> -]> - -<softwarelists> - <softwarelist name="snes" description="Nintendo SNES cartridges"> - <software name="aokidenp" cloneof="aokiden"> - <description>Aoki Densetsu Shoot! (Japan, prototype)</description> - <year>1994</year> - <publisher>KSS</publisher> - <info name="alt_title" value="蒼き伝説シュート!"/> - <part name="cart" interface="snes_cart"> - <feature name="battery" value="BATT CR2032" /> - <feature name="cart_model" value="no shell" /> - <feature name="lockout" value="" /> - <feature name="pcb" value="SHVC-4PV5B-01" /> - <feature name="slot" value="lorom" /> - <feature name="u1" value="U1 EPROM" /> - <feature name="u2" value="U2 EPROM" /> - <feature name="u3" value="U3 EPROM" /> - <feature name="u4" value="U4 EPROM" /> - <feature name="u5" value="U5 SRAM" /> - <feature name="u6" value="U6 PLD" /> - <feature name="u7" value="U7 74LS157" /> - <feature name="u8" value="U8 CIC" /> - <dataarea name="rom" size="1572864"> - <rom name="shoot 1 kss.u1" size="524288" crc="71306e06" sha1="253ec028d68a85209dc3e5846a2a2f5b582fed7b"/> - <rom name="shoot 2 kss.u2" size="524288" crc="d07e1be3" sha1="7a58acb027ca15c1054e58f43156c2d99f62d16c"/> - <rom name="shoot 3 kss.u3" size="524288" crc="380ed94f" sha1="8607ce31748ae73b9aa7aacda80c843622c61a79"/> - </dataarea> - <dataarea name="nvram" size="131072"> - </dataarea> - </part> - </software> - </softwarelist> -</softwarelists> - -`; + const xmlData = `<root attr="�"/>`; const options = { ignoreAttributes: false, attributeNamePrefix: '', + //processEntities: true, + htmlEntities: true }; const parser = new XMLParser(options); // console.log(JSON.stringify(parser.parse(xml))); @@ -112,7 +22,7 @@ describe("unpaired and empty tags", function() { // expect(result).toEqual(expected); }); - fit("bug test", function() { + xit("bug test", function() { const xmlData = `<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE dmodule [
src/xmlparser/OrderedObjParser.js+12 −2 modified@@ -41,8 +41,8 @@ export default class OrderedObjParser{ "copyright" : { regex: /&(copy|#169);/g, val: "©" }, "reg" : { regex: /&(reg|#174);/g, val: "®" }, "inr" : { regex: /&(inr|#8377);/g, val: "₹" }, - "num_dec": { regex: /&#([0-9]{1,7});/g, val : (_, str) => String.fromCodePoint(Number.parseInt(str, 10)) }, - "num_hex": { regex: /&#x([0-9a-fA-F]{1,6});/g, val : (_, str) => String.fromCodePoint(Number.parseInt(str, 16)) }, + "num_dec": { regex: /&#([0-9]{1,7});/g, val : (_, str) => fromCodePoint(str, 10, "&#") }, + "num_hex": { regex: /&#x([0-9a-fA-F]{1,6});/g, val : (_, str) => fromCodePoint(str, 16, "&#x") }, }; this.addExternalEntities = addExternalEntities; this.parseXml = parseXml; @@ -627,3 +627,13 @@ function parseValue(val, shouldParse, options) { } } } + +function fromCodePoint(str, base, prefix){ + const codePoint = Number.parseInt(str, base); + + if (codePoint >= 0 && codePoint <= 0x10FFFF) { + return String.fromCodePoint(codePoint); + } else { + return prefix +str + ";"; + } +} \ No newline at end of file
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- github.com/advisories/GHSA-37qj-frw5-hhjhghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2026-25128ghsaADVISORY
- github.com/NaturalIntelligence/fast-xml-parser/commit/4e387f61c4a5cef792f6a2f42467013290bf95dcghsax_refsource_MISCWEB
- github.com/NaturalIntelligence/fast-xml-parser/releases/tag/v5.3.4ghsax_refsource_MISCWEB
- github.com/NaturalIntelligence/fast-xml-parser/security/advisories/GHSA-37qj-frw5-hhjhghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.