Skip to content

Commit 40527e4

Browse files
committed
[build] Fix vulnerability in showdown
... by replacing it with markdown-it and adding sanitization ``` npm audit report showdown * Severity: moderate Showdown vulnerable to Regular Expression Denial of Service (ReDoS) in link/anchor parsing - GHSA-rmmh-p597-ppvv No fix available node_modules/showdown ``` Fixes: https://github.com/redhat-developer/vscode-openshift-tools/security/dependabot/156 Signed-off-by: Victor Rubezhny <vrubezhny@redhat.com>
1 parent e010899 commit 40527e4

3 files changed

Lines changed: 16 additions & 31 deletions

File tree

package-lock.json

Lines changed: 1 addition & 26 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@
150150
"json-to-ast": "^2.1.0",
151151
"leasot": "^14.4.0",
152152
"lodash": "^4.18.1",
153+
"markdown-it": "^14.1.1",
153154
"mkdirp": "^3.0.1",
154155
"mocha": "^11.7.5",
155156
"module-alias": "^2.3.4",
@@ -168,7 +169,6 @@
168169
"remap-istanbul": "^0.13.0",
169170
"rxjs": "^7.8.2",
170171
"semver": "^7.7.4",
171-
"showdown": "^2.1.0",
172172
"shx": "^0.4.0",
173173
"sinon": "^21.1.2",
174174
"sinon-chai": "^4.0.1",

src/webview/create-service/app/createForm.tsx

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,10 @@ import type {
3636
} from '@rjsf/utils';
3737
import { getTemplate, getUiOptions } from '@rjsf/utils';
3838
import validator from '@rjsf/validator-ajv8';
39+
import DOMPurify from 'dompurify';
40+
import MarkdownIt from 'markdown-it';
3941
import * as React from 'react';
4042
import 'react-dom';
41-
import { Converter } from 'showdown';
4243
import type { CustomResourceDefinitionStub } from '../../common/createServiceTypes';
4344
import { ErrorPage } from '../../common/errorPage';
4445
import { LoadScreen } from '../../common/loading';
@@ -197,10 +198,19 @@ function SelectService(props: {
197198
}) {
198199
const [isServiceKindTouched, setServiceKindTouched] = React.useState(false);
199200

200-
const converter = React.useMemo(() => {
201-
return new Converter();
201+
const md = React.useMemo(() => {
202+
return new MarkdownIt({
203+
html: false,
204+
linkify: true,
205+
typographer: true,
206+
});
202207
}, []);
203208

209+
const safeConvertToHtml = (textToConvert) => {
210+
const rawHtml = md.render(textToConvert);
211+
return DOMPurify.sanitize(rawHtml);
212+
};
213+
204214
const [isDocumentationExpanded, setDocumentationExpanded] = React.useState(true);
205215

206216
return (
@@ -275,7 +285,7 @@ function SelectService(props: {
275285
<Box margin={1}>
276286
<div
277287
dangerouslySetInnerHTML={{
278-
__html: converter.makeHtml(
288+
__html: safeConvertToHtml(
279289
props.selectedServiceKind.csvDescription,
280290
),
281291
}}

0 commit comments

Comments
 (0)