🐛 Sanitize comment content on rendering (#9605)

Add escape-html function that escapes HTML special characters and apply
it in the comment editor at four dom/set-html! call sites where
user-provided text is inserted as innerHTML, preventing stored XSS.

Signed-off-by: Andrey Antukh <niwi@niwi.nz>
This commit is contained in:
Andrey Antukh 2026-05-14 11:20:11 +02:00 committed by GitHub
parent 55dd6d2b00
commit 29f940fb7a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 16 additions and 4 deletions

View File

@ -81,7 +81,7 @@
([text]
(-> (dom/create-element "span")
(dom/set-data! "type" "text")
(dom/set-html! (if (empty? text) zero-width-space text)))))
(dom/set-html! (if (empty? text) zero-width-space (dom/escape-html text))))))
(defn- create-mention-node
"Creates a mention node"
@ -313,7 +313,7 @@
after-span (create-text-node (dm/str " " suffix))
sel (wapi/get-selection)]
(dom/set-html! span-node (if (empty? prefix) zero-width-space prefix))
(dom/set-html! span-node (if (empty? prefix) zero-width-space (dom/escape-html prefix)))
(dom/insert-after! node span-node mention-span)
(dom/insert-after! node mention-span after-span)
(wapi/set-cursor-after! after-span)
@ -330,7 +330,7 @@
(let [node-text (dom/get-text span-node)
at-symbol (if (blank-content? node-text) "@" " @")]
(dom/set-html! span-node (str/concat node-text at-symbol))
(dom/set-html! span-node (str/concat (dom/escape-html node-text) at-symbol))
(wapi/set-cursor-after! span-node))))))
handle-key-down
@ -378,7 +378,7 @@
(when span-node
(let [txt (.-textContent span-node)]
(dom/set-html! span-node (dm/str (subs txt 0 offset) "\n" zero-width-space (subs txt offset)))
(dom/set-html! span-node (dm/str (dom/escape-html (subs txt 0 offset)) "\n" zero-width-space (dom/escape-html (subs txt offset))))
(wapi/set-cursor! span-node (inc offset))
(handle-input)))))

View File

@ -319,6 +319,18 @@
([document ^js text]
(.createTextNode document text)))
(defn escape-html
"Escapes special HTML characters in a string so that it can be safely used
as innerHTML without risk of XSS."
[^js text]
(when (some? text)
(-> text
(str/replace "&" "&amp;")
(str/replace "<" "&lt;")
(str/replace ">" "&gt;")
(str/replace "\"" "&quot;")
(str/replace "'" "&#39;"))))
(defn set-html!
[^js el html]
(when (some? el)