Skip to content

✅ TEST(#143): add categorical XSS guard across plugin renderers#151

Open
KyleKing wants to merge 5 commits into
executablebooks:claude/practical-goldberg-xaa9j6from
KyleKing:kyle/xss-and-attrs-fixes-143
Open

✅ TEST(#143): add categorical XSS guard across plugin renderers#151
KyleKing wants to merge 5 commits into
executablebooks:claude/practical-goldberg-xaa9j6from
KyleKing:kyle/xss-and-attrs-fixes-143

Conversation

@KyleKing

Copy link
Copy Markdown
Contributor

I started working on a fix locally, but it is the same net result with one addition a of categorical check to complement the per-plugin regression tests. The implementation follows the same pattern for test_redos in my other PR to proactively surface these types of security issues to PR authors rather than in code review

KyleKing and others added 2 commits July 21, 2026 09:02
…blebooks#143)

Resolve the XSS advisories from executablebooks#143 where plugins interpolated
attacker-controlled markdown into their default HTML render rules without
escaping:

- texmath: escape the math source in the default render() stub and the
  math_block_eqno equation number, across every delimiter flavor
- dollarmath: escape the equation label in the id/href attributes (the
  content was already escaped)
- myst_block: escape the target label in the <a> body and href

Harden attrs/attrs_block: with no explicit allowed list, divert event-handler
(on*) and style attributes to token.meta["insecure_attrs"] instead of emitting
them, so the default configuration cannot inject script. The inline span path
previously set token.attrs directly and bypassed the filter; route it through
_add_attrs with the allowed set threaded in. Other attribute names are
unchanged.

Update the texmath/myst fixtures that encoded the old unescaped output, and add
a categorical guard (tests/test_xss.py) that renders injection probes through
each plugin to catch the next unescaped interpolation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L4mwfRr7ZkjiwPATm6Q4ue
@KyleKing

Copy link
Copy Markdown
Contributor Author

FYI: @chrisjsewell, feel free to consider merging this change into the base PR (#150) to fully address all five findings and proactively catch them going forward

@KyleKing
KyleKing force-pushed the kyle/xss-and-attrs-fixes-143 branch from e1e501a to c977b60 Compare July 21, 2026 16:56

def render(tex: str, displayMode: bool, macros: Any) -> str:
return tex
return escapeHtml(tex)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the rendering logic below is implemented, we want the escaping to be owned here because doing so around render would break the valid HTML and reasonable to be owned by render

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