Skip to content

Commit

Permalink
minor: sanitize activity feed editor content (#16533)
Browse files Browse the repository at this point in the history
  • Loading branch information
Sachin-chaurasiya committed Jun 5, 2024
1 parent 6af76c5 commit 14235c8
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 6 deletions.
2 changes: 2 additions & 0 deletions openmetadata-ui/src/main/resources/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
"cronstrue": "^1.122.0",
"crypto-random-string-with-promisify-polyfill": "^5.0.0",
"diff": "^5.0.0",
"dompurify": "^3.1.5",
"eventemitter3": "^5.0.1",
"fast-json-patch": "^3.1.1",
"history": "4.5.1",
Expand Down Expand Up @@ -161,6 +162,7 @@
"@types/codemirror": "^0.0.104",
"@types/dagre": "^0.7.47",
"@types/diff": "^5.0.2",
"@types/dompurify": "^3.0.5",
"@types/jest": "^26.0.23",
"@types/lodash": "^4.14.167",
"@types/luxon": "^3.0.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import {
} from '../../../utils/FeedUtils';
import { LinkBlot } from '../../../utils/QuillLink/QuillLink';
import { insertMention, insertRef } from '../../../utils/QuillUtils';
import { getSanitizeContent } from '../../../utils/sanitize.utils';
import { getEntityIcon } from '../../../utils/TableUtils';
import { editorRef } from '../../common/RichTextEditor/RichTextEditor.interface';
import './feed-editor.less';
Expand Down Expand Up @@ -72,7 +73,9 @@ export const FeedEditor = forwardRef<editorRef, FeedEditorProp>(
) => {
const { t, i18n } = useTranslation();
const editorRef = useRef<ReactQuill>(null);
const [value, setValue] = useState<string>(defaultValue ?? '');
const [value, setValue] = useState(() =>
getSanitizeContent(defaultValue ?? '')
);
const [isMentionListOpen, toggleMentionList] = useState(false);
const [isFocused, toggleFocus] = useState(false);

Expand Down Expand Up @@ -246,11 +249,14 @@ export const FeedEditor = forwardRef<editorRef, FeedEditorProp>(

/**
* Handle onChange logic and set updated value to state
* @param value - updated value
* @param updatedValue - updated value
*/
const handleOnChange = (value: string) => {
setValue(value);
onChangeHandler?.(value);
const handleOnChange = (updatedValue: string) => {
setValue(updatedValue);

// sanitize the content before sending it to the parent component
const sanitizedContent = getSanitizeContent(updatedValue);
onChangeHandler?.(sanitizedContent);
};

/**
Expand All @@ -260,7 +266,8 @@ export const FeedEditor = forwardRef<editorRef, FeedEditorProp>(
getEditorValue() {
setValue('');

return HTMLToMarkdown.turndown(value);
// sanitize the content before sending it to the parent component
return HTMLToMarkdown.turndown(getSanitizeContent(value));
},
clearEditorValue() {
setValue('');
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright 2024 Collate.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { getSanitizeContent } from './sanitize.utils';

describe('getSanitizeContent', () => {
it('should sanitize the input 1', () => {
const mockHtml = `<details/open/ontoggle=confirm('XSS')>`;
const result = getSanitizeContent(mockHtml);

expect(result).toBe(`<details open=""></details>`);
});

it('should sanitize the input 2', () => {
const mockHtml = `<img src=x onerror=alert(1)//>`;
const result = getSanitizeContent(mockHtml);

expect(result).toBe(`<img src="x">`);
});

it('should sanitize the input 3', () => {
const mockHtml = `<svg><g/onload=alert(2)//<p>`;
const result = getSanitizeContent(mockHtml);

expect(result).toBe(`<svg><g></g></svg>`);
});

it('should sanitize the input 4', () => {
const mockHtml = `<p>abc<iframe//src=jAva&Tab;script:alert(3)>def</p>`;
const result = getSanitizeContent(mockHtml);

expect(result).toBe(`<p>abc</p>`);
});
});
17 changes: 17 additions & 0 deletions openmetadata-ui/src/main/resources/ui/src/utils/sanitize.utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright 2024 Collate.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import DOMPurify from 'dompurify';

export const getSanitizeContent = (html: string): string => {
return DOMPurify.sanitize(html);
};
17 changes: 17 additions & 0 deletions openmetadata-ui/src/main/resources/ui/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4081,6 +4081,13 @@
resolved "https://registry.yarnpkg.com/@types/diff/-/diff-5.0.2.tgz#dd565e0086ccf8bc6522c6ebafd8a3125c91c12b"
integrity sha512-uw8eYMIReOwstQ0QKF0sICefSy8cNO/v7gOTiIy9SbwuHyEecJUm7qlgueOO5S1udZ5I/irVydHVwMchgzbKTg==

"@types/dompurify@^3.0.5":
version "3.0.5"
resolved "https://registry.yarnpkg.com/@types/dompurify/-/dompurify-3.0.5.tgz#02069a2fcb89a163bacf1a788f73cb415dd75cb7"
integrity sha512-1Wg0g3BtQF7sSb27fJQAKck1HECM6zV1EB66j8JH9i3LCjYabJa0FSdiSgsD5K/RbrsR0SiraKacLB+T8ZVYAg==
dependencies:
"@types/trusted-types" "*"

"@types/eslint-scope@^3.7.3":
version "3.7.4"
resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.4.tgz#37fc1223f0786c39627068a12e94d6e6fc61de16"
Expand Down Expand Up @@ -4509,6 +4516,11 @@
"@types/testing-library__dom" "*"
pretty-format "^25.1.0"

"@types/trusted-types@*":
version "2.0.7"
resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.7.tgz#baccb07a970b91707df3a3e8ba6896c57ead2d11"
integrity sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==

"@types/trusted-types@^2.0.2":
version "2.0.4"
resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.4.tgz#2b38784cd16957d3782e8e2b31c03bc1d13b4d65"
Expand Down Expand Up @@ -7164,6 +7176,11 @@ dompurify@^2.3.3:
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.3.10.tgz#901f7390ffe16a91a5a556b94043314cd4850385"
integrity sha512-o7Fg/AgC7p/XpKjf/+RC3Ok6k4St5F7Q6q6+Nnm3p2zGWioAY6dh0CbbuwOhH2UcSzKsdniE/YnE2/92JcsA+g==

dompurify@^3.1.5:
version "3.1.5"
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.1.5.tgz#2c6a113fc728682a0f55684b1388c58ddb79dc38"
integrity sha512-lwG+n5h8QNpxtyrJW/gJWckL+1/DQiYMX8f7t8Z2AZTPw1esVrqjI63i7Zc2Gz0aKzLVMYC1V1PL/ky+aY/NgA==

domutils@^2.5.2, domutils@^2.6.0:
version "2.7.0"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.7.0.tgz#8ebaf0c41ebafcf55b0b72ec31c56323712c5442"
Expand Down

0 comments on commit 14235c8

Please sign in to comment.