From 31f0c370be4b95ac4fa285fea3be970606735f16 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Fri, 28 Aug 2026 14:39:48 +0100 Subject: Avoid prototype pollution when reading styles --- NEWS | 6 ++++++ lib/docx/styles-reader.js | 27 +++++++++++++++++++-------- test/docx/styles-reader.tests.js | 12 ++++++++++++ 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/NEWS b/NEWS index 5f954c3..1206dac 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,9 @@ +# 1.12.2 + +* Avoid prototype pollution when reading the styles defined in a document. This + avoids an issue where a maliciously crafted document could be used to set + externalFileAccess to true. + # 1.12.1 * Fix: on Windows, when an image's content type includes a backslash in the diff --git a/lib/docx/styles-reader.js b/lib/docx/styles-reader.js index 28c809b..276a668 100644 --- a/lib/docx/styles-reader.js +++ b/lib/docx/styles-reader.js @@ -27,16 +27,27 @@ function readStylesXml(root) { var tableStyles = {}; var numberingStyles = {}; - var styles = { - "paragraph": paragraphStyles, - "character": characterStyles, - "table": tableStyles, - "numbering": numberingStyles - }; - root.getElementsByTagName("w:style").forEach(function(styleElement) { var style = readStyleElement(styleElement); - var styleSet = styles[style.type]; + var styleSet; + + switch (style.type) { + case "paragraph": + styleSet = paragraphStyles; + break; + + case "character": + styleSet = characterStyles; + break; + + case "table": + styleSet = tableStyles; + break; + + case "numbering": + styleSet = numberingStyles; + break; + } // Per 17.7.4.17 style (Style Definition) of ECMA-376 4th edition Part 1: // diff --git a/test/docx/styles-reader.tests.js b/test/docx/styles-reader.tests.js index b63bb6a..8f964c1 100644 --- a/test/docx/styles-reader.tests.js +++ b/test/docx/styles-reader.tests.js @@ -120,6 +120,18 @@ test('when multiple style elements have same style ID then only first element is assert.equal(styles.findTableStyleById("TableNormal").name, "Normal Table"); }); +test('w:type of __proto__ does not cause prototype pollution', function() { + readStylesXml( + new XmlElement("w:styles", {}, [ + new XmlElement("w:style", {"w:type": "__proto__", "w:styleId": "List1"}, [ + new XmlElement("w:name", {"w:val": "List 1"}, []) + ]) + ]) + ); + + assert.equal({}["List1"], undefined); +}); + function paragraphStyleElement(id, name) { return styleElement("paragraph", id, name); } -- cgit v1.2.3