Found by design-dev's impeccable run and confirmed at source. Python-Markdown
passes raw HTML through, and doc.html and booth.html render the result |safe.
A <script> in any session's .md ran on the Booth's origin, and a contract that
quoted <pre> opened a real one and swallowed the rest of the doc.
Operator ruling: escape raw HTML (not an allowlist).
- render_doc deregisters Python-Markdown's block and inline HTML processors,
so raw HTML reaches the serializer as text and is escaped there. Fenced and
inline code are unchanged.
- Every link href in a doc goes through links.is_safe_href after
browser-style decoding. Python-Markdown keeps character references in
attributes, so `javascript:` reached the browser as `javascript:`.
- is_safe_href reads a backslash as a slash, as a browser does in an http(s)
URL: `/\evil.test` is `//evil.test`. This also closes the hole on the
link board.
- A render that raises falls back to raw text, which the template escapes.
Two of 19 live .md files render differently. One is a contract losing the
quoted <pre> that swallowed it. The other is links.md, which renders as a
board, not through render_doc.
heid bug-hunt panel (4/4): the core claim held. Its two concrete edges (the
backslash twin, the unbounded render) are fixed here. Table
tests/mutations/doc_html.toml: 9/9 proved. Suite 951 -> 975.