Skip to content

Commit b18ea6f

Browse files
committed
Sanitize raw HTML content and fix replies
While we usually can trust chat messages to originate from 'save' Markdown, it's still best practice to never inject user provided HTML directly into the DOM. This patch also fixes visible HTML code in relies.
1 parent 488a8a4 commit b18ea6f

File tree

5 files changed

+24
-11
lines changed

5 files changed

+24
-11
lines changed

package-lock.json

Lines changed: 13 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"bowser": "^2.11.0",
88
"classnames": "^2.3.1",
99
"darkreader": "^4.9.46",
10+
"dompurify": "^3.3.0",
1011
"linkify-react": "^3.0.4",
1112
"linkifyjs": "^3.0.5",
1213
"prop-types": "^15.8.1",
@@ -15,13 +16,13 @@
1516
"react-intl": "^6.2.5",
1617
"react-router-dom": "^6.4.3",
1718
"react-sizeme": "^3.0.2",
19+
"recharts": "^2.12.7",
1820
"sass": "^1.52.1",
1921
"semver": "^7.5.2",
22+
"styled-components": "^6.1.13",
2023
"tldraw-v1": "npm:@tldraw/tldraw@^1.2.7",
2124
"video.js": "^7.21.1",
22-
"videojs-seek-buttons": "^3.0.1",
23-
"recharts": "^2.12.7",
24-
"styled-components": "^6.1.13"
25+
"videojs-seek-buttons": "^3.0.1"
2526
},
2627
"devDependencies": {
2728
"react-scripts": "^5.0.1"

src/components/chat/messages/reply/index.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React from 'react';
22
import PropTypes from 'prop-types';
33
import cx from 'classnames';
44
import '../index.scss';
5+
import DOMPurify from 'dompurify';
56

67
const propTypes = {
78
active: PropTypes.bool,
@@ -34,9 +35,9 @@ const Reply = ({
3435
return (
3536
<span
3637
onClick={handleClickReply}
37-
className={cx('reply-tag', {inactive: !active})}
38+
className={cx('reply-tag', 'text-vanilla', {inactive: !active})}
39+
dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(text) }}
3840
>
39-
{text}
4041
</span>
4142
);
4243
};

src/components/chat/messages/user/text.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from 'react';
22
import PropTypes from 'prop-types';
3+
import DOMPurify from 'dompurify';
34

45
const propTypes = {
56
active: PropTypes.bool,
@@ -21,7 +22,7 @@ const Text = ({
2122
return (
2223
<div
2324
className='text-vanilla'
24-
dangerouslySetInnerHTML={{ __html: text }}
25+
dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(text) }}
2526
/>
2627
);
2728
};

src/components/notes/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
import { ID } from 'utils/constants';
77
import storage from 'utils/data/storage';
88
import './index.scss';
9+
import DOMPurify from 'dompurify';
910

1011
const intlMessages = defineMessages({
1112
aria: {
@@ -26,7 +27,7 @@ const Notes = () => {
2627
>
2728
<div className="notes">
2829
<div
29-
dangerouslySetInnerHTML={{ __html: storage.notes }}
30+
dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(storage.notes) }}
3031
style={{ width: '100%' }}
3132
/>
3233
</div>

0 commit comments

Comments
 (0)