Skip to content

[Bug] Unescaped advisory HTML disables report sorting, pagination, and modals #98

Description

@ktkhang

Current behavior

The report is generated without a CLI error and initially appears valid: summary cards and advisory rows are rendered. However, the interactive parts of the report are broken:

  • search and severity sorting are unavailable
  • the page-size selector and pagination are missing
  • advisory modal links do not open
  • some advisory details later in the document may be absent

The generated file is not truncated. The Bootstrap and DataTables scripts are present in the HTML source, but the browser does not include them in the active document, so they never initialize.

Real-world input that exposes the bug

This occurs when npm audit returns the DOMPurify advisory GHSA-rp9w-3fw7-7cwq. The advisory is for the npm package dompurify (affected: <= 3.4.6, patched: 3.4.7). Its timeline shows that it was published in the DOMPurify repository on May 27, 2026, then published to the GitHub Advisory Database and reviewed on June 16, 2026.

The advisory overview returned by npm audit contains a raw, unclosed <template> token in the text describing HTML passed to DOMPurify.

To avoid ambiguity: this is not a bug in DOMPurify itself. npm-audit-html does not load or execute DOMPurify. This advisory is valid third-party input that exposes an HTML-rendering bug in the report generator. For a lockfile already containing an affected version, rerunning the audit after the advisory becomes available in the registry response is enough to expose the problem.

Traced root cause

The markdown helper passes advisory text to marked without sanitizing raw HTML. The rendered value is then inserted using triple-stash Handlebars output.

The browser interprets <template> as a real, unclosed element and parses the remaining markup into template.content. This includes the Bootstrap and DataTables scripts at the end of the template, leaving them outside the active document.

Suggested solution

Treat all advisory fields as untrusted input. Sanitize the rendered Markdown with a maintained allowlist-based sanitizer, or escape raw HTML before Markdown rendering, so advisory text cannot alter the document structure.

A regression test based on this advisory should verify that raw <template> and <script> content is rendered safely and that the report scripts remain in the active document.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions