PR Summary: Harden markdown rendering in Reflection widget #5395
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
fixes - #5391
What this PR does
This PR makes markdown rendering in the Reflection widget safer by ensuring that ** untrusted text cannot execute HTML or JavaScript at runtime.**
The change is limited to mdToHTML() in reflection.js and does not alter the widget’s overall flow or user-facing behavior.
Changes made
1. Escape HTML before applying markdown formatting
Previous behavior -
mdToHTML() converted markdown directly into HTML without escaping input first.
As a result, raw HTML coming from reply.response could be executed when inserted using innerHTML.
New behavior -
The input is first normalized to a string
All HTML characters are escaped:
& → &
< → <
Markdown formatting (headings, bold, italics, line breaks) is applied after escaping
Result
Raw HTML is rendered as plain text instead of being executed, closing the XSS vector while preserving markdown support.
2. Safer handling of markdown links
Previous behavior -
Markdown links like label were converted directly into , allowing unsafe URLs such as javascript: or data:.
New behavior
Markdown links are extracted into placeholders before escaping
After escaping and formatting, links are re-inserted only if the URL is safe
Allowed URLs
http: / https: / mailto:
Relative URLs starting with #, /, or .
Rejected
Any other schemes (e.g. javascript:, data:)
URLs containing whitespace or ASCII control characters .
Result
Prevents script or attribute injection through links and adds protection against tab-nabbing.
Why this change is safe and minimal
1] No refactor of the widget logic
2] botReplyDiv() still uses innerHTML only for markdown messages
3] Non-markdown paths continue to use innerText
4] Existing markdown features continue to work as before
5] The fix is fully contained within mdToHTML()
Outcome
1] Prevents runtime HTML / script execution in the Reflection widget
2] Keeps markdown functionality intact
3] Avoids future security regressions
4] Passes lint cleanly.