diff --git a/static/js/markdown.js b/static/js/markdown.js
index dd97979..622a166 100644
--- a/static/js/markdown.js
+++ b/static/js/markdown.js
@@ -34,6 +34,83 @@ function linkHtml(text, url) {
return `${safeText}`;
}
+/**
+ * Sanitize the raw-HTML fragments that mdToHtml deliberately preserves from
+ * the source text — blocks (collapsible agent output) and tags
+ * (emitted by the markdown link pass). Those fragments are later restored
+ * verbatim into innerHTML, so without scrubbing them a model — or any content
+ * routed through here — could smuggle in an `
`, an
+ * ``, an `onmouseover=` handler, etc. and execute
+ * script in the authenticated page (DOM XSS).
+ *
+ * Parsing into a is inert: assigning to template.innerHTML neither
+ * fetches resources nor runs scripts, so we can walk the resulting tree,
+ * drop script-capable elements, and strip event-handler attributes and
+ * dangerous URL schemes before the (now safe) fragment is handed back.
+ */
+const _ALLOWED_HTML_BAD_TAGS = new Set([
+ 'SCRIPT', 'IFRAME', 'OBJECT', 'EMBED', 'LINK', 'META',
+ 'STYLE', 'BASE', 'FORM', 'NOSCRIPT', 'TEMPLATE',
+ // Foreign-content roots. SVG/MathML have their own parser rules and are a
+ // classic mutation-XSS vehicle — e.g. an SVG-namespaced