Skip to content

fix: add XSS sanitization for chat messages#1742

Merged
ritesh-1918 merged 1 commit into
ritesh-1918:gssocfrom
jhosepm352-design:fix/xss-sanitization-chat
Jun 5, 2026
Merged

fix: add XSS sanitization for chat messages#1742
ritesh-1918 merged 1 commit into
ritesh-1918:gssocfrom
jhosepm352-design:fix/xss-sanitization-chat

Conversation

@jhosepm352-design

@jhosepm352-design jhosepm352-design commented Jun 4, 2026

Copy link
Copy Markdown

Added a defense-in-depth sanitization layer for chat messages to prevent potential XSS attacks via script tags or inline event handlers, addressing the 'XSS in AI chat markdown rendering' security concern.

Summary by CodeRabbit

  • Bug Fixes
    • Improved message security by sanitizing chat messages to prevent malicious script blocks and event handlers from being executed or displayed during message transmission and rendering.

@vercel

vercel Bot commented Jun 4, 2026

Copy link
Copy Markdown

@jhosepm352-design is attempting to deploy a commit to the ritesh Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Jun 4, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds XSS protection to the TicketChat component by introducing a sanitizeMessage helper function that strips <script> tags and inline event handlers (on* attributes), then applies this sanitization to the optimistic message send path to prevent injection of malicious content.

Changes

XSS Sanitization in TicketChat

Layer / File(s) Summary
Sanitization function definition
Frontend/src/components/shared/TicketChat.jsx
sanitizeMessage(text) uses regex patterns to remove <script> blocks and inline event handlers like onclick="..." and onerror='...' from message text.
Integration in optimistic send flow
Frontend/src/components/shared/TicketChat.jsx
handleSend now uses sanitizeMessage(content) when creating the temporary message object for optimistic rendering instead of the raw input.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • ritesh-1918/HELPDESK.AI#763: Complements this frontend XSS sanitization by adding backend sanitize_text helper to escape and sanitize stored ticket messages and summaries.

Suggested labels

gssoc, level:intermediate, type:bug

Poem

🐰 A rabbit hops to guard the chat,
Stripping scripts and attacks flat,
No more sneaky <script> schemes,
Just friendly messages and clean dreams! 🛡️

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely describes the main change: adding XSS sanitization for chat messages.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Frontend/src/components/shared/TicketChat.jsx (1)

108-109: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Use one sanitized payload for both optimistic state and persistence.

Right now only the optimistic message is sanitized (Line [189]), but DB inserts still use raw content (Line [205], Line [216]). That breaks the dedupe check at Line [108] whenever sanitization changes text, so both temp and persisted copies can remain in the list. It also reintroduces unsanitized content from realtime payloads.

Proposed fix
-        const content = inputValue.trim();
+        const content = inputValue.trim();
+        const sanitizedContent = sanitizeMessage(content)?.trim();
+        if (!sanitizedContent) return;
         const currentIsInternal = isInternal;
@@
-            message: sanitizeMessage(content),
+            message: sanitizedContent,
@@
-                        content: content
+                        content: sanitizedContent
@@
-                        message: content
+                        message: sanitizedContent

Also applies to: 179-190, 205-217

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Frontend/src/components/shared/TicketChat.jsx` around lines 108 - 109, The
dedupe bug comes from sanitizing only the optimistic message but still
persisting/forwarding the raw content, so String(m.id).startsWith('temp-') check
against newMessage.message can fail; fix by creating one sanitized payload
(e.g., const sanitizedContent or sanitizedPayload) when composing the optimistic
message (where newMessage is built) and use that same sanitized value everywhere
you persist or emit to realtime/DB (replace raw content usages in the DB insert
and realtime-send code paths that currently use content). Ensure filtered,
newMessage, and the DB insert / realtime send call sites all reference the
single sanitized variable so the in-memory dedupe and persisted record match.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Frontend/src/components/shared/TicketChat.jsx`:
- Around line 3-10: The regex-based sanitizeMessage function is insufficient for
XSS; replace it with a proven HTML sanitizer (e.g., DOMPurify or sanitize-html)
and stop ad-hoc regex stripping: update the sanitizeMessage implementation to
import and configure the chosen library (strictly allow only safe
tags/attributes, explicitly disallow event handlers, script/iframe/object, and
normalize case/multiline payloads) and apply the same sanitizer consistently at
both write and read paths; ensure sanitizeMessage (and any server-side
counterpart) uses that shared config, update imports/usages in TicketChat.jsx,
and add/adjust tests to validate common XSS payloads are rejected.

---

Outside diff comments:
In `@Frontend/src/components/shared/TicketChat.jsx`:
- Around line 108-109: The dedupe bug comes from sanitizing only the optimistic
message but still persisting/forwarding the raw content, so
String(m.id).startsWith('temp-') check against newMessage.message can fail; fix
by creating one sanitized payload (e.g., const sanitizedContent or
sanitizedPayload) when composing the optimistic message (where newMessage is
built) and use that same sanitized value everywhere you persist or emit to
realtime/DB (replace raw content usages in the DB insert and realtime-send code
paths that currently use content). Ensure filtered, newMessage, and the DB
insert / realtime send call sites all reference the single sanitized variable so
the in-memory dedupe and persisted record match.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6b1c0ea9-7e8c-45b0-b7c8-c834cfadbf57

📥 Commits

Reviewing files that changed from the base of the PR and between da8faf2 and 7b50b05.

📒 Files selected for processing (1)
  • Frontend/src/components/shared/TicketChat.jsx

Comment on lines +3 to +10
// Basic XSS sanitization: removes script tags and inline event handlers
const sanitizeMessage = (text) => {
if (!text) return text;
return text
.replace(/<script.*?>.*?<\/script>/gi, '')
.replace(/ on\w+="[^"]*"/g, '')
.replace(/ on\w+='[^']*'/g, '');
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Regex-based sanitizer is too weak to be treated as an XSS boundary.

The current patterns miss common variants (e.g., unquoted on*= handlers, case variants, multiline script payloads), so malicious markup can pass through unchanged. Please replace this with a robust sanitizer strategy (and keep it consistent across write/read paths), rather than relying on ad-hoc regex stripping.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Frontend/src/components/shared/TicketChat.jsx` around lines 3 - 10, The
regex-based sanitizeMessage function is insufficient for XSS; replace it with a
proven HTML sanitizer (e.g., DOMPurify or sanitize-html) and stop ad-hoc regex
stripping: update the sanitizeMessage implementation to import and configure the
chosen library (strictly allow only safe tags/attributes, explicitly disallow
event handlers, script/iframe/object, and normalize case/multiline payloads) and
apply the same sanitizer consistently at both write and read paths; ensure
sanitizeMessage (and any server-side counterpart) uses that shared config,
update imports/usages in TicketChat.jsx, and add/adjust tests to validate common
XSS payloads are rejected.

@ritesh-1918 ritesh-1918 changed the base branch from main to gssoc June 4, 2026 17:46
@ritesh-1918

Copy link
Copy Markdown
Owner

Hi @jhosepm352-design! 🙌

Thank you so much for your excellent contribution: "fix: add XSS sanitization for chat messages"! We really appreciate the high-quality code and effort you have put into the platform.

Just a quick, friendly heads-up as we prepare our manual merging and verification queues—please make sure to complete all the mandatory community steps listed below.

⚠️ Quick leaderboard tip: To secure the absolute highest GSSoC point tier for your contribution, please make sure you are following our project admin @ritesh-1918 manually on GitHub. Having all four onboarding steps cleared is highly preferable for manual PR approvals! ✨

Once those manual steps are verified, we'll get your PR officially merged into the gssoc branch (or keep it neatly cataloged if closed as integrated) and assign it the highest possible GSSoC S-Tier labels to maximize your leaderboard points!

Let's build something amazing together! 🚀🔥


🌟 Project Support & Developer Network (Show Some Love!)

As we prepare our manual verification and merging queues, please take a quick moment to ensure you have completed all four community steps:

  1. Star this repository: Helps our AI helpdesk get noticed! Star the repo here
  2. 🍴 Fork this repository: Keep a copy to build your own cool tools! Fork here
  3. 👤 Follow @ritesh-1918 on GitHub: Stay updated on real-time open-source projects! Follow ritesh-1918 here
  4. 💼 Connect on LinkedIn: Let's build a strong engineering connection! Connect with Ritesh on LinkedIn

Note: Having all four steps completed manually is required before your PR points are officially cleared.

@ritesh-1918 ritesh-1918 added gssoc GirlScript Summer of Code gssoc:approved GSSoC Approved PR mentor:ritesh-1918 Reviewed by Project Admin Ritesh level:intermediate Intermediate level difficulty quality:clean Clean code quality type:bug Bug fix labels Jun 5, 2026
@ritesh-1918

Copy link
Copy Markdown
Owner

Hi @jhosepm352-design! 🙌

Thank you so much for your excellent contribution: "fix: add XSS sanitization for chat messages"! We really appreciate the high-quality code and effort you have put into the platform.

Just a quick, friendly heads-up as we prepare our manual merging and verification queues—please make sure to complete all the mandatory community steps listed below.

⚠️ Quick leaderboard tip: To secure the absolute highest GSSoC point tier for your contribution, please make sure you are following our project admin @ritesh-1918 manually on GitHub. Having all four onboarding steps cleared is highly preferable for manual PR approvals! ✨

Once those manual steps are verified, we'll get your PR officially merged into the gssoc branch (or keep it neatly cataloged if closed as integrated) and assign it the highest possible GSSoC S-Tier labels to maximize your leaderboard points!

Let's build something amazing together! 🚀🔥


🌟 Project Support & Developer Network (Show Some Love!)

As we prepare our manual verification and merging queues, please take a quick moment to ensure you have completed all four community steps:

  1. Star this repository: Helps our AI helpdesk get noticed! Star the repo here
  2. 🍴 Fork this repository: Keep a copy to build your own cool tools! Fork here
  3. 👤 Follow @ritesh-1918 on GitHub: Stay updated on real-time open-source projects! Follow ritesh-1918 here
  4. 💼 Connect on LinkedIn: Let's build a strong engineering connection! Connect with Ritesh on LinkedIn

Note: Having all four steps completed manually is required before your PR points are officially cleared.

@ritesh-1918

Copy link
Copy Markdown
Owner

Merged locally into gssoc branch. Thank you for your GSSoC contribution! 🚀🔥

@ritesh-1918 ritesh-1918 merged commit 90e6bc3 into ritesh-1918:gssoc Jun 5, 2026
2 of 3 checks passed
@ritesh-1918 ritesh-1918 removed the mentor:ritesh-1918 Reviewed by Project Admin Ritesh label Jun 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gssoc:approved GSSoC Approved PR gssoc GirlScript Summer of Code level:intermediate Intermediate level difficulty quality:clean Clean code quality type:bug Bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants