From 8d9a9ab0b2895b82351650165b10c6ebf8b17285 Mon Sep 17 00:00:00 2001 From: Max Wu Date: Mon, 21 Dec 2020 14:19:47 +0800 Subject: [PATCH 1/3] fix: avoid eval string when putting back parsed string of mermaid where has stored XSS issue Signed-off-by: Max Wu --- public/js/extra.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/public/js/extra.js b/public/js/extra.js index d1f605c3ec..b36dd931fd 100644 --- a/public/js/extra.js +++ b/public/js/extra.js @@ -397,9 +397,10 @@ export function finishView (view) { var $value = $(value) const $ele = $(value).closest('pre') - window.mermaid.parse($value.text()) + let text = $value.text() + window.mermaid.parse(text) $ele.addClass('mermaid') - $ele.html($value.text()) + $ele.text(text) window.mermaid.init(undefined, $ele) } catch (err) { $value.unwrap() From 064dfb786575cb27e3c63c53f18dcaa8ca7b9128 Mon Sep 17 00:00:00 2001 From: Max Wu Date: Mon, 21 Dec 2020 14:47:13 +0800 Subject: [PATCH 2/3] fix: disable prefer-const lint rule for mermaid block text string Signed-off-by: Max Wu --- public/js/extra.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/public/js/extra.js b/public/js/extra.js index b36dd931fd..1e672c8129 100644 --- a/public/js/extra.js +++ b/public/js/extra.js @@ -397,10 +397,12 @@ export function finishView (view) { var $value = $(value) const $ele = $(value).closest('pre') + /* eslint-disable prefer-const */ let text = $value.text() window.mermaid.parse(text) $ele.addClass('mermaid') $ele.text(text) + /* eslint-enable prefer-const */ window.mermaid.init(undefined, $ele) } catch (err) { $value.unwrap() From 568355acf51a3677262987f8236979d971239ecd Mon Sep 17 00:00:00 2001 From: Max Wu Date: Mon, 21 Dec 2020 14:56:40 +0800 Subject: [PATCH 3/3] fix: properly validate mermaid syntax and handle parse error Signed-off-by: Max Wu --- public/js/extra.js | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/public/js/extra.js b/public/js/extra.js index 1e672c8129..b59a84dce1 100644 --- a/public/js/extra.js +++ b/public/js/extra.js @@ -253,7 +253,12 @@ function replaceExtraTags (html) { return html } -if (typeof window.mermaid !== 'undefined' && window.mermaid) window.mermaid.startOnLoad = false +if (typeof window.mermaid !== 'undefined' && window.mermaid) { + window.mermaid.startOnLoad = false + window.mermaid.parseError = function (err, hash) { + console.warn(err) + } +} // dynamic event or object binding here export function finishView (view) { @@ -397,13 +402,14 @@ export function finishView (view) { var $value = $(value) const $ele = $(value).closest('pre') - /* eslint-disable prefer-const */ - let text = $value.text() - window.mermaid.parse(text) - $ele.addClass('mermaid') - $ele.text(text) - /* eslint-enable prefer-const */ - window.mermaid.init(undefined, $ele) + const text = $value.text() + // validate the syntax first + if (window.mermaid.parse(text)) { + $ele.addClass('mermaid') + $ele.text(text) + // render the diagram + window.mermaid.init(undefined, $ele) + } } catch (err) { $value.unwrap() $value.parent().append(`
${escapeHTML(err.str)}
`)