GHSA-3cgg-c5pp-57h6: odf-kit: HTML injection leading to XSS in odtToHtml() and odsToHtml() via unescaped style attribute values

  • Severity: MEDIUM
  • CVE: CVE-2026-113787
  • Ecosystems: npm
  • Packages: odf-kit

### Summary

ODF style attribute values are interpolated into `style=”…”` attributes without HTML-escaping in **both** of odf-kit’s to-HTML renderers (`odtToHtml` and `odsToHtml`). A double-quote character inside an attacker-controlled style value breaks out of the attribute, allowing arbitrary HTML/attribute injection — and therefore script execution (XSS) — from a crafted `.odt` or `.ods` file wherever the rendered output is inserted as HTML, which is the documented purpose of both functions.

### Details

#### ODT renderer (`src/odt/to-html/html-renderer.ts`)

The renderer has an `escapeHtml()` helper and applies it consistently to text content and to attribute values — `href`, `src`, `alt`, `id`, `data-author`, `data-date`, citation text all go through it. The inline CSS strings do not.

In `renderTextSpan` (dist/odt/to-html/html-renderer.js:195):

“`js
const css = spanStyleToCss(span.style);
if (css)
html = `${html}`;
“`

The value of e.g. `fo:color` is copied from the document into `style.fontColor` verbatim by the parser (`extractSpanStyle`, read/parser.js:348), then concatenated raw into the attribute. A `”` in the value terminates the attribute early.

The same unescaped `style=”${…}”` pattern appears at roughly ten other emission sites: paragraph and heading (`paragraphStyleToCss`), table cells and rows (`cellStyleToCss`, `rowStyleToCss`), “, and the image style attribute. The affected source attributes include `fo:color`, `fo:background-color`, `fo:text-sha…

Source: GitHub Security Advisories · 2026-11-04