Skip to content

[high] harden: graph tooltip renders contributor-supplied names as innerHTML - #1278

Open
elhoim wants to merge 1 commit into
MISP:mainfrom
elhoim:fix/graphjs-innerhtml
Open

elhoim wants to merge 1 commit into
MISP:mainfrom
elhoim:fix/graphjs-innerhtml

Conversation

@elhoim

@elhoim elhoim commented Aug 30, 2026

Copy link
Copy Markdown
Member

BLUF — The misp-galaxy.org graph tooltip renders contributor-supplied names as innerHTML

  • Problemtools/mkdocs/site/docs/01_attachements/javascripts/graph.js passes contributor-supplied strings to d3's .html(), which assigns innerHTML: line 120 renders a cluster value and line 250 a galaxy name, both taken straight from clusters/*.json and galaxies/*.json, which anyone can change via a pull request.
  • Fix — Switch both call sites to .text(), so the tooltip sets textContent.
  • Effect — Markup landing in those files can no longer be parsed and executed as HTML for site visitors, and PR review stops being the only barrier to script execution.

Problem

The graph tooltip renders contributor-supplied strings through d3's .html(), which assigns innerHTML:

tooltip.html(d.id)     // line 120 -- d.id is a cluster `value`
tooltip.html(d.name)   // line 250 -- d.name is a galaxy `name`

Both come straight from clusters/*.json and galaxies/*.json, which anyone can change by opening a pull request. Any markup in a cluster value would be parsed and executed as HTML by every visitor to misp-galaxy.org.

Honest scope: this is hardening, not a live bug

I checked, and there is nothing to clean up in the data today:

cluster values: 56131
  values that look like they contain an HTML tag (<[a-zA-Z/!]): 0
  values containing an HTML entity sequence (&foo; / &#N;):     0

The 1,720 values containing < or > are all things like Other (Action > Environmental > Variety), and the 414 containing & are ATT&CK-style names — none of which forms a tag or a decodable entity, so nothing renders wrongly right now.

The point is that the only thing standing between a malicious cluster value and script execution on the published site is PR review. .text() removes that dependency, and it is a two-character change.

Fix

Use .text() (sets textContent) instead of .html() at both tooltip sites. The tooltip displays a plain name; it has never needed markup.

node --check passes.

🤖 Generated with Claude Code

tooltip.html(d.id) and tooltip.html(d.name) assign innerHTML, and both
values come straight from clusters/*.json and galaxies/*.json -- data any
contributor can change via a pull request. Markup in a cluster value would
be parsed and executed for every visitor to misp-galaxy.org.

To be clear this is hardening, not a live bug: of 56,131 cluster values,
0 look like they contain an HTML tag and 0 contain a decodable entity. The
1,720 values with "<" or ">" are "Other (Action > Environmental > Variety)"
style names and the 414 with "&" are "ATT&CK" style names; none renders
wrongly today. The point is that PR review is currently the only thing
preventing script execution on the published site.

The tooltip shows a plain name and never needed markup.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HZGwPoa8MMfkhCw47rDLA4
@elhoim elhoim changed the title harden: graph tooltip renders contributor-supplied names as innerHTML [high] harden: graph tooltip renders contributor-supplied names as innerHTML Sep 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant