---
id: "GHSA-2rqm-h6hv-g79v"
kind: "vulnerability"
aliases: ["GHSA-2rqm-h6hv-g79v"]
title: "odf-kit has HTML injection leading to XSS in odsToHtml() via unescaped style attribute values"
severity: "medium"
cvss: 6.1
epss: null
exploited: false
status: "open"
category: "package"
products: [{"name": "odf-kit", "fixed": ["0.14.2"], "affected": ">= 0.9.8, < 0.14.2", "ecosystem": "npm"}]
ecosystems: ["npm"]
tags: ["cwe-79", "javascript", "npm", "odf-kit", "package", "web-apps"]
not_affected_if: ["no-odstohtml-usage", "output-never-rendered-as-html", "trusted-files-only", "version-0.14.2-or-later"]
published_at: "2026-10-23T20:55:31+00:00"
first_seen_at: "2026-10-23T20:59:05+00:00"
updated_at: "2026-10-23T21:00:22+00:00"
sources: [{"source": "ghsa", "url": "https://github.com/advisories/GHSA-2rqm-h6hv-g79v", "first_seen_at": "2026-10-23T20:59:05+00:00"}]
---

# odf-kit has HTML injection leading to XSS in odsToHtml() via unescaped style attribute values

odf-kit's odsToHtml() writes spreadsheet style values into an HTML style attribute without escaping, so a double quote in a crafted .ods file breaks out of the attribute. If the rendered HTML is inserted into a page, an attacker can inject tags and attributes and run script in that page's origin.

_Summary, check and fix written by a model from the sources; labelled as such._

## Affected

- npm:odf-kit affected >= 0.9.8, < 0.14.2 fixed 0.14.2

## How to check

Run `npm ls odf-kit` to find the installed version; affected versions are >= 0.9.8 and < 0.14.2.
Find code that calls odsToHtml( and check whether its output is inserted into a web page as HTML.
Check whether those .ods files can come from untrusted users.

## Fix

Upgrade odf-kit to 0.14.2 or later.
If you cannot upgrade right away, do not insert odsToHtml() output into pages unescaped, or sanitize it before rendering.

## Timeline

- 2026-10-23T20:59:05+00:00 ghsa https://github.com/advisories/GHSA-2rqm-h6hv-g79v

## From the sources

### Summary

ODF style values are interpolated into `style="..."` attributes without HTML-escaping in odf-kit's ODS to-HTML renderer (`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 `.ods` file wherever the rendered output is inserted as HTML, which is the documented purpose of the function.

### Details

Two emission sites in `src/ods/to-html/html-renderer.ts` (before 0.14.0, `src/ods-reader/html-renderer.ts`) write document-controlled values into a `style` attribute without escaping:

- **Cell style.** `buildInlineStyle()` assembles a CSS string from the cell's formatting properties (`fo:color`, `fo:font-size`, `fo:font-family`, `fo:background-color`, `fo:text-align`, etc.) with no escaping, and `renderCell` emits it raw as the cell's `style` attribute.
- **Row height.** `row.height` (from `style:row-height`) is emitted raw into the row element's `style` attribute.

The same defect in the ODT renderer (`odtToHtml()`) is tracked as GHSA-3cgg-c5pp-57h6 (CVE-2026-113787).

### Impact

Any consumer that renders `odsToHtml()` output as HTML gets XSS from a crafted `.ods` file they convert: untrusted file → arbitrary tags and attributes → script execution in the host page with the page's origin.

### Patches

Fixed in 0.14.2. Both sites now route document-controlled values through a shared attribute-escaping helper:

- [`1424227`](https://github.com/GitHubNewbie0/odf-kit/commit/1424227d1ca2716a249b623d1456575ff0331dcc): escape style attribute values in the ODS HTML renderer
- [`aa64c73`](https://github.com/GitHubNewbie0/odf-kit/commit/aa64c734ebd7e7be40e35fcda83b1144193c3da2): the shared `escapeAttr` helper

Users should upgrade to 0.14.2 or later.

### Credit

Reported by @PethuKannan.

---

_Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai_
