Skip to content

fix(security): prevent XSS via dangerouslySetInnerHTML in MCP description and search results#13893

Merged
kangfenmao merged 2 commits intoCherryHQ:mainfrom
xr843:fix/security-xss-dangerouslysetinnerhtml
Mar 31, 2026
Merged

fix(security): prevent XSS via dangerouslySetInnerHTML in MCP description and search results#13893
kangfenmao merged 2 commits intoCherryHQ:mainfrom
xr843:fix/security-xss-dangerouslysetinnerhtml

Conversation

@xr843
Copy link
Copy Markdown
Contributor

@xr843 xr843 commented Mar 30, 2026

Summary

This PR fixes two XSS vulnerabilities where untrusted content is injected via dangerouslySetInnerHTML without sanitization.

1. NPM README XSS in MCP Description — CWE-79

File: src/renderer/src/pages/settings/MCPSettings/McpDescription.tsx

NPM package README content (fetched from the npm registry) is rendered through markdown-it and injected directly into the DOM. A malicious NPM package could include XSS payloads in its README:

# Innocent Package
<img src=x onerror="require('child_process').exec('...')">

Fix: Sanitize the rendered HTML with DOMPurify (already a project dependency) before injection:

setMcpInfo(DOMPurify.sanitize(result))

2. Stored XSS in Search Result Highlighting — CWE-79

File: src/renderer/src/pages/history/components/SearchResults.tsx

LLM response text is injected via dangerouslySetInnerHTML without HTML escaping. If an LLM response contains HTML (via prompt injection or adversarial input), it will execute when the user searches chat history:

// Before: raw text with potential HTML injected directly
return <span dangerouslySetInnerHTML={{ __html: text }} />

Fix: Escape HTML entities before applying highlight markup:

const escapeHtml = (s: string) =>
  s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;')
const safeText = escapeHtml(text)

Impact

Both vulnerabilities allow arbitrary JavaScript execution in the Electron renderer process. Combined with sandbox: false in the current BrowserWindow configuration, this could escalate to full system access.

Copy link
Copy Markdown
Contributor

@cherry-ai-bot cherry-ai-bot bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. This patch closes two clear XSS paths around dangerouslySetInnerHTML with minimal, targeted changes: sanitizing rendered README HTML and escaping search-result text before applying highlight markup. I don't see any blocking issue in the current implementation.

@kangfenmao kangfenmao force-pushed the fix/security-xss-dangerouslysetinnerhtml branch from ab7341f to 4a4e2eb Compare March 31, 2026 05:18
xr843 added 2 commits March 31, 2026 13:29
NPM package README content is rendered via markdown-it and injected with
dangerouslySetInnerHTML without sanitization. A malicious NPM package could
include XSS payloads (<script>, <img onerror=...>) in its README that
execute in the Electron renderer context.

Fix: sanitize the rendered HTML with DOMPurify (already a project dependency)
before injecting it into the DOM.

CWE-79: Cross-Site Scripting (XSS)
…tored XSS

Message text from LLM responses is injected via dangerouslySetInnerHTML
without escaping. If an LLM response contains HTML like <img onerror=...>,
it executes in the renderer context when the user searches chat history.

Fix: escape HTML entities in the text before applying highlight markup.

CWE-79: Stored Cross-Site Scripting
@kangfenmao kangfenmao force-pushed the fix/security-xss-dangerouslysetinnerhtml branch from 4a4e2eb to ce31ffb Compare March 31, 2026 05:29
@kangfenmao kangfenmao merged commit 1926992 into CherryHQ:main Mar 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants