Skip to content

Commit 4018692

Browse files
authored
Fix: Message input XSS (#383)
Sanitize that special characters of HTML tags cause XSS issue
1 parent 4f5b10c commit 4018692

File tree

2 files changed

+12
-7
lines changed

2 files changed

+12
-7
lines changed

src/ui/MessageInput/index.jsx

+7-7
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import MentionUserLabel from '../MentionUserLabel';
1919
import Icon, { IconTypes, IconColors } from '../Icon';
2020
import Label, { LabelTypography, LabelColors } from '../Label';
2121
import { LocalizationContext } from '../../lib/LocalizationContext';
22+
import { sanitizeString } from './utils';
2223
import {
2324
arrayEqual,
2425
getClassName,
@@ -114,6 +115,7 @@ const MessageInput = React.forwardRef((props, ref) => {
114115
}
115116
), []);
116117

118+
// #Edit mode
117119
// for easilly initialize input value from outside, but
118120
// useEffect(_, [channelUrl]) erase it
119121
const initialValue = props?.value;
@@ -136,7 +138,7 @@ const MessageInput = React.forwardRef((props, ref) => {
136138
}
137139
}, [channelUrl]);
138140

139-
// #Mention | Fill message input values
141+
// #Mention & #Edit | Fill message input values
140142
useEffect(() => {
141143
if (isEdit && message?.messageId) {
142144
// const textField = document.getElementById(textFieldId);
@@ -150,9 +152,7 @@ const MessageInput = React.forwardRef((props, ref) => {
150152
textField.innerHTML = message?.mentionedMessageTemplate?.split(' ').map((word) => (
151153
convertWordToStringObj(word, mentionedUsers).map((stringObj) => {
152154
const { type, value, userId } = stringObj;
153-
if (type === StringObjType.mention
154-
&& mentionedUsers.some((user) => user?.userId === userId)
155-
) {
155+
if (type === StringObjType.mention && mentionedUsers.some((user) => user?.userId === userId)) {
156156
return renderToString(
157157
<MentionUserLabel userId={userId}>
158158
{
@@ -164,13 +164,13 @@ const MessageInput = React.forwardRef((props, ref) => {
164164
</MentionUserLabel>,
165165
);
166166
}
167-
return value;
167+
return sanitizeString(value);
168168
}).join('')
169169
)).join(' ');
170170
} else {
171171
/* mention disabled */
172172
try {
173-
textField.innerHTML = message?.message;
173+
textField.innerHTML = sanitizeString(message?.message);
174174
} catch { }
175175
setMentionedUserIds([]);
176176
}
@@ -428,7 +428,7 @@ const MessageInput = React.forwardRef((props, ref) => {
428428
}}
429429
onPaste={(e) => {
430430
e.preventDefault();
431-
document.execCommand("insertHTML", false, e?.clipboardData.getData('text'));
431+
document.execCommand("insertHTML", false, sanitizeString(e?.clipboardData.getData('text')));
432432
}}
433433
/>
434434
{/* placeholder */}

src/ui/MessageInput/utils.js

+5
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,9 @@ export function debounce(func, wait, immediate) {
2020
};
2121
}
2222

23+
// Sanitize that special characters of HTML tags cause XSS issue
24+
export const sanitizeString = (str) => (
25+
str?.replace(/[\u00A0-\u9999<>]/gim, (i) => ''.concat('&#', i.charCodeAt(0), ';'))
26+
);
27+
2328
export default debounce;

0 commit comments

Comments
 (0)