Browse Source

[frontend] Replace markdown with snarkdown

markdown hasn't been maintained in the past couple of years and has some CVEs reported. As we only use the lib for turning markdown into html a more lightweight library like snarkdown makes more sense.

This also adds deXSS on the markdown output using sanitize-html.
Johan Åhlén 3 years ago
parent
commit
da95c24a5e

+ 7 - 4
desktop/core/src/desktop/js/apps/editor/snippet.js

@@ -18,7 +18,7 @@ import { EXECUTE_ACTIVE_EXECUTABLE_TOPIC } from 'apps/editor/components/events';
 import $ from 'jquery';
 import $ from 'jquery';
 import * as ko from 'knockout';
 import * as ko from 'knockout';
 import komapping from 'knockout.mapping';
 import komapping from 'knockout.mapping';
-import { markdown } from 'markdown';
+import snarkdown from 'snarkdown';
 
 
 import 'apps/editor/components/ko.executableLogs';
 import 'apps/editor/components/ko.executableLogs';
 import 'apps/editor/components/ko.snippetEditorActions';
 import 'apps/editor/components/ko.snippetEditorActions';
@@ -36,6 +36,7 @@ import './components/variableSubstitution/VariableSubstitutionKoBridge.vue';
 
 
 import AceAutocompleteWrapper from 'apps/notebook/aceAutocompleteWrapper';
 import AceAutocompleteWrapper from 'apps/notebook/aceAutocompleteWrapper';
 import apiHelper from 'api/apiHelper';
 import apiHelper from 'api/apiHelper';
+import deXSS from 'utils/html/deXSS';
 import Executor from 'apps/editor/execution/executor';
 import Executor from 'apps/editor/execution/executor';
 import hueAnalytics from 'utils/hueAnalytics';
 import hueAnalytics from 'utils/hueAnalytics';
 import huePubSub from 'utils/huePubSub';
 import huePubSub from 'utils/huePubSub';
@@ -1050,9 +1051,11 @@ export default class Snippet {
   }
   }
 
 
   renderMarkdown() {
   renderMarkdown() {
-    return this.statement_raw().replace(/([^$]*)([$]+[^$]*[$]+)?/g, (a, textRepl, code) => {
-      return markdown.toHTML(textRepl).replace(/^<p>|<\/p>$/g, '') + (code ? code : '');
-    });
+    return this.statement_raw().replace(
+      /([^$]*)([$]+[^$]*[$]+)?/g,
+      (a, textRepl, code) =>
+        deXSS(snarkdown(textRepl)).replace(/^<p>|<\/p>$/g, '') + (code ? code : '')
+    );
   }
   }
 
 
   startLongOperationTimeout() {
   startLongOperationTimeout() {

+ 7 - 4
desktop/core/src/desktop/js/apps/notebook/snippet.js

@@ -17,11 +17,12 @@
 import $ from 'jquery';
 import $ from 'jquery';
 import * as ko from 'knockout';
 import * as ko from 'knockout';
 import komapping from 'knockout.mapping';
 import komapping from 'knockout.mapping';
-import { markdown } from 'markdown';
+import snarkdown from 'snarkdown';
 
 
 import AceAutocompleteWrapper from 'apps/notebook/aceAutocompleteWrapper';
 import AceAutocompleteWrapper from 'apps/notebook/aceAutocompleteWrapper';
 import apiHelper from 'api/apiHelper';
 import apiHelper from 'api/apiHelper';
 import dataCatalog from 'catalog/dataCatalog';
 import dataCatalog from 'catalog/dataCatalog';
+import deXSS from 'utils/html/deXSS';
 import hueAnalytics from 'utils/hueAnalytics';
 import hueAnalytics from 'utils/hueAnalytics';
 import huePubSub from 'utils/huePubSub';
 import huePubSub from 'utils/huePubSub';
 import { getFromLocalStorage, setInLocalStorage } from 'utils/storageUtils';
 import { getFromLocalStorage, setInLocalStorage } from 'utils/storageUtils';
@@ -2799,9 +2800,11 @@ class Snippet {
   }
   }
 
 
   renderMarkdown() {
   renderMarkdown() {
-    return this.statement_raw().replace(/([^$]*)([$]+[^$]*[$]+)?/g, (a, textRepl, code) => {
-      return markdown.toHTML(textRepl).replace(/^<p>|<\/p>$/g, '') + (code ? code : '');
-    });
+    return this.statement_raw().replace(
+      /([^$]*)([$]+[^$]*[$]+)?/g,
+      (a, textRepl, code) =>
+        deXSS(snarkdown(textRepl)).replace(/^<p>|<\/p>$/g, '') + (code ? code : '')
+    );
   }
   }
 
 
   async exportHistory() {
   async exportHistory() {

+ 2 - 0
desktop/core/src/desktop/js/ext/aceHelper.ts

@@ -26,6 +26,7 @@ import 'ext/ace/mode-hive';
 import 'ext/ace/mode-hplsql';
 import 'ext/ace/mode-hplsql';
 import 'ext/ace/mode-impala';
 import 'ext/ace/mode-impala';
 import 'ext/ace/mode-ksql';
 import 'ext/ace/mode-ksql';
+import 'ext/ace/mode-markdown';
 import 'ext/ace/mode-mysql';
 import 'ext/ace/mode-mysql';
 import 'ext/ace/mode-pgsql'
 import 'ext/ace/mode-pgsql'
 import 'ext/ace/mode-phoenix';
 import 'ext/ace/mode-phoenix';
@@ -42,6 +43,7 @@ import 'ext/ace/snippets/hive';
 import 'ext/ace/snippets/hplsql';
 import 'ext/ace/snippets/hplsql';
 import 'ext/ace/snippets/impala';
 import 'ext/ace/snippets/impala';
 import 'ext/ace/snippets/ksql';
 import 'ext/ace/snippets/ksql';
+import 'ext/ace/snippets/markdown';
 import 'ext/ace/snippets/mysql';
 import 'ext/ace/snippets/mysql';
 import 'ext/ace/snippets/pgsql';
 import 'ext/ace/snippets/pgsql';
 import 'ext/ace/snippets/phoenix';
 import 'ext/ace/snippets/phoenix';

+ 13 - 48
package-lock.json

@@ -106,12 +106,12 @@
         "less-loader": "9.0.0",
         "less-loader": "9.0.0",
         "license-checker": "25.0.1",
         "license-checker": "25.0.1",
         "load-grunt-tasks": "5.1.0",
         "load-grunt-tasks": "5.1.0",
-        "markdown": "0.5.0",
         "postcss-less": "6.0.0",
         "postcss-less": "6.0.0",
         "postcss-scss": "4.0.3",
         "postcss-scss": "4.0.3",
         "prettier": "2.3.0",
         "prettier": "2.3.0",
         "sass": "1.34.0",
         "sass": "1.34.0",
         "sass-loader": "11.1.1",
         "sass-loader": "11.1.1",
+        "snarkdown": "2.0.0",
         "source-map-loader": "3.0.0",
         "source-map-loader": "3.0.0",
         "style-loader": "2.0.0",
         "style-loader": "2.0.0",
         "stylelint": "14.3.0",
         "stylelint": "14.3.0",
@@ -13658,33 +13658,6 @@
         "node": ">=0.10.0"
         "node": ">=0.10.0"
       }
       }
     },
     },
-    "node_modules/markdown": {
-      "version": "0.5.0",
-      "resolved": "https://registry.npmjs.org/markdown/-/markdown-0.5.0.tgz",
-      "integrity": "sha1-KCBbVlqK51kt4gdGPWY33BgnIrI=",
-      "dev": true,
-      "dependencies": {
-        "nopt": "~2.1.1"
-      },
-      "bin": {
-        "md2html": "bin/md2html.js"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/markdown/node_modules/nopt": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/nopt/-/nopt-2.1.2.tgz",
-      "integrity": "sha1-bMzZd7gBMqB3MdbozljCyDA8+a8=",
-      "dev": true,
-      "dependencies": {
-        "abbrev": "1"
-      },
-      "bin": {
-        "nopt": "bin/nopt.js"
-      }
-    },
     "node_modules/math-random": {
     "node_modules/math-random": {
       "version": "1.0.4",
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz",
       "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz",
@@ -17263,6 +17236,12 @@
       "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
       "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
       "optional": true
       "optional": true
     },
     },
+    "node_modules/snarkdown": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/snarkdown/-/snarkdown-2.0.0.tgz",
+      "integrity": "sha512-MgL/7k/AZdXCTJiNgrO7chgDqaB9FGM/1Tvlcenenb7div6obaDATzs16JhFyHHBGodHT3B7RzRc5qk8pFhg3A==",
+      "dev": true
+    },
     "node_modules/source-list-map": {
     "node_modules/source-list-map": {
       "version": "2.0.1",
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
       "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
@@ -30472,26 +30451,6 @@
         "object-visit": "^1.0.0"
         "object-visit": "^1.0.0"
       }
       }
     },
     },
-    "markdown": {
-      "version": "0.5.0",
-      "resolved": "https://registry.npmjs.org/markdown/-/markdown-0.5.0.tgz",
-      "integrity": "sha1-KCBbVlqK51kt4gdGPWY33BgnIrI=",
-      "dev": true,
-      "requires": {
-        "nopt": "~2.1.1"
-      },
-      "dependencies": {
-        "nopt": {
-          "version": "2.1.2",
-          "resolved": "https://registry.npmjs.org/nopt/-/nopt-2.1.2.tgz",
-          "integrity": "sha1-bMzZd7gBMqB3MdbozljCyDA8+a8=",
-          "dev": true,
-          "requires": {
-            "abbrev": "1"
-          }
-        }
-      }
-    },
     "math-random": {
     "math-random": {
       "version": "1.0.4",
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz",
       "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz",
@@ -33194,6 +33153,12 @@
         }
         }
       }
       }
     },
     },
+    "snarkdown": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/snarkdown/-/snarkdown-2.0.0.tgz",
+      "integrity": "sha512-MgL/7k/AZdXCTJiNgrO7chgDqaB9FGM/1Tvlcenenb7div6obaDATzs16JhFyHHBGodHT3B7RzRc5qk8pFhg3A==",
+      "dev": true
+    },
     "source-list-map": {
     "source-list-map": {
       "version": "2.0.1",
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
       "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",

+ 1 - 1
package.json

@@ -127,10 +127,10 @@
     "less-loader": "9.0.0",
     "less-loader": "9.0.0",
     "license-checker": "25.0.1",
     "license-checker": "25.0.1",
     "load-grunt-tasks": "5.1.0",
     "load-grunt-tasks": "5.1.0",
-    "markdown": "0.5.0",
     "postcss-less": "6.0.0",
     "postcss-less": "6.0.0",
     "postcss-scss": "4.0.3",
     "postcss-scss": "4.0.3",
     "prettier": "2.3.0",
     "prettier": "2.3.0",
+    "snarkdown": "2.0.0",
     "sass": "1.34.0",
     "sass": "1.34.0",
     "sass-loader": "11.1.1",
     "sass-loader": "11.1.1",
     "source-map-loader": "3.0.0",
     "source-map-loader": "3.0.0",