PF5: Copy response text as both plain text and rich HTML#1879
PF5: Copy response text as both plain text and rich HTML#1879kyoto wants to merge 1 commit intoopenshift:pattern-fly-5from
Conversation
When an OLS response is copied to the clipboard, write both text/plain (raw Markdown) and text/html (rendered HTML via marked) so that pasting into rich text editors preserves formatting, while plain text editors still receive the raw Markdown. Made-with: Cursor
📝 WalkthroughWalkthroughThe Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
|
[APPROVALNOTIFIER] This PR is APPROVED Approval requirements bypassed by manually added approval. This pull-request has been approved by: The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
1 similar comment
|
[APPROVALNOTIFIER] This PR is APPROVED Approval requirements bypassed by manually added approval. This pull-request has been approved by: The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/clipboard.ts`:
- Around line 5-10: marked.parse(value) currently emits unsanitized HTML and you
unconditionally use ClipboardItem/navigator.clipboard.write which will fail in
older browsers; fix by sanitizing the HTML output (e.g., call
DOMPurify.sanitize(html) on the result of marked.parse(value)) and then use
ClipboardItem and navigator.clipboard.write only when both ClipboardItem and
navigator.clipboard.write are available, otherwise fall back to
navigator.clipboard.writeText(value); update references inside this block
(marked.parse, the html variable, ClipboardItem, navigator.clipboard.write,
navigator.clipboard.writeText) to use the sanitized HTML and the fallback
branch.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: e32c2bd6-2b3b-4384-ab7c-f6b902fc1e89
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (2)
package.jsonsrc/clipboard.ts
| const html = marked.parse(value) as string; | ||
| const clipboardItem = new ClipboardItem({ | ||
| 'text/plain': new Blob([value], { type: 'text/plain' }), | ||
| 'text/html': new Blob([html], { type: 'text/html' }), | ||
| }); | ||
| await navigator.clipboard.write([clipboardItem]); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
find . -type f -name "clipboard.ts" | head -20Repository: openshift/lightspeed-console
Length of output: 91
🏁 Script executed:
cat -n ./src/clipboard.tsRepository: openshift/lightspeed-console
Length of output: 696
🏁 Script executed:
# Check for marked configuration and sanitization
rg "marked\." --type ts --type js | head -20Repository: openshift/lightspeed-console
Length of output: 137
🏁 Script executed:
# Check package.json for marked version and dependencies
cat -n package.json | grep -A 20 "marked"Repository: openshift/lightspeed-console
Length of output: 826
🏁 Script executed:
# Check if DOMPurify or other sanitization libraries are used
rg "DOMPurify|sanitize" --type ts --type jsRepository: openshift/lightspeed-console
Length of output: 54
🏁 Script executed:
# Check if there are other clipboard-related utilities or tests that might show the expected behavior
rg "copyToClipboard\|clipboard" --type ts --type js -lRepository: openshift/lightspeed-console
Length of output: 54
🌐 Web query:
marked 14.0.0 sanitization HTML security
💡 Result:
In marked version 14.0.0, there is no built-in HTML sanitization feature. The legacy 'sanitize' and 'sanitizer' options were removed in version 8.0.0. Marked explicitly warns that it does not sanitize output HTML and users must apply a separate sanitization library to prevent XSS attacks when processing untrusted input. Key security guidance from official documentation: - Marked converts Markdown (including raw HTML blocks) to HTML without filtering dangerous content like script tags or malicious attributes. - Recommended approach: Parse with marked first, then sanitize the resulting HTML. - Primary recommendation: Use DOMPurify.sanitize(marked.parse(markdown)). - Alternatives: sanitize-html, insane, or js-xss. Example for secure usage: import { marked } from 'marked'; import DOMPurify from 'dompurify'; const safeHtml = DOMPurify.sanitize(marked.parse(userMarkdown)); Using extensions with hooks.postprocess: marked.use({ hooks: { postprocess(html) { return DOMPurify.sanitize(html); } } }); No XSS vulnerabilities are reported specifically for marked 14.0.0 in security databases like Snyk or GitHub Advisories. Past issues (pre-v4) involved ReDoS, fixed long ago. Version 14.0.0 (released Aug 2024) focuses on renderer changes, with no sanitization-related updates. For untrusted user input, always sanitize post-parsing to mitigate risks from raw HTML in Markdown.
Citations:
- 1: https://github.com/markedjs/marked/releases/tag/v14.0.0
- 2: Sanitize and sanitizer markedjs/marked#1232
- 3: Sanitize hardening markedjs/marked#1504
- 4: https://www.npmjs.com/package/marked?activeTab=versions
- 5: Add optional
sanitizeroption for easier secure rendering with DOMPurify markedjs/marked#3943 - 6: https://github.com/markedjs/marked/blob/v18.0.0/docs/INDEX.md
- 7: https://github.com/markedjs/marked/blob/master/docs/USING_ADVANCED.md
- 8: http://marked.js.org/
- 9: https://marked.js.org/using_advanced
- 10: https://marked.js.org/using_pro
- 11: https://security.snyk.io/package/npm/marked/14.0.0
- 12: https://github.com/markedjs/marked/security
🏁 Script executed:
# Check if marked has a sanitizer option or if there's any config
rg "new marked\|marked\.setOptions\|marked\.defaults" --type ts --type jsRepository: openshift/lightspeed-console
Length of output: 54
Sanitize the HTML and add a fallback for older browsers.
marked.parse(value) preserves raw HTML from the markdown source, and marked 14.0.0 has no built-in sanitization. The text/html clipboard payload can carry untrusted markup into downstream paste targets without external sanitization. Additionally, this implementation unconditionally depends on ClipboardItem/navigator.clipboard.write(), so browsers without support for the richer clipboard API will silently fail instead of falling back to navigator.clipboard.writeText(value).
Recommendations:
- Sanitize the generated HTML before placing it on the clipboard (use DOMPurify or similar)
- Add a fallback branch for browsers without
ClipboardItemsupport
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/clipboard.ts` around lines 5 - 10, marked.parse(value) currently emits
unsanitized HTML and you unconditionally use
ClipboardItem/navigator.clipboard.write which will fail in older browsers; fix
by sanitizing the HTML output (e.g., call DOMPurify.sanitize(html) on the result
of marked.parse(value)) and then use ClipboardItem and navigator.clipboard.write
only when both ClipboardItem and navigator.clipboard.write are available,
otherwise fall back to navigator.clipboard.writeText(value); update references
inside this block (marked.parse, the html variable, ClipboardItem,
navigator.clipboard.write, navigator.clipboard.writeText) to use the sanitized
HTML and the fallback branch.
When an OLS response is copied to the clipboard, write both text/plain (raw Markdown) and text/html (rendered HTML via marked) so that pasting into rich text editors preserves formatting, while plain text editors still receive the raw Markdown.
Made-with: Cursor
Summary by CodeRabbit