ソースを参照

HUE-9570 [ui] Rewramp deXSS with sanitize-html package (#1418)

* HUE-9570 [ui] Rewramp deXSS with sanitize-html package

* HUE-9570 [ui] Rewramp deXSS with sanitize-html package - Test code

* HUE-9570 [ui] Rewramp deXSS with sanitize-html package - Test code Linf-fix

Co-authored-by: Akhil Naik <asnaik@cloudere.com>
Asnaik HWX 5 年 前
コミット
b92c3efdda

+ 2 - 4
desktop/core/src/desktop/js/utils/hueUtils.js

@@ -15,6 +15,7 @@
 // limitations under the License.
 
 import $ from 'jquery';
+import sanitizeHtml from 'sanitize-html';
 
 export const bootstrapRatios = {
   span3() {
@@ -308,10 +309,7 @@ export const logError = error => {
 export const equalIgnoreCase = (a, b) => a && b && a.toLowerCase() === b.toLowerCase();
 
 const deXSS = str => {
-  if (typeof str !== 'undefined' && str !== null && typeof str === 'string') {
-    return str.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '');
-  }
-  return str;
+  return sanitizeHtml(str);
 };
 
 export const getStyleFromCSSClass = cssClass => {

+ 30 - 0
desktop/core/src/desktop/js/utils/hueUtils.test.js

@@ -73,4 +73,34 @@ describe('hue.utils.js', () => {
   it('should remove JS code from a string', () => {
     expect(hueUtils.deXSS('hello <script>alert(123)</script>world')).toEqual('hello world');
   });
+
+  it('Should not remove strong tag from a string', () => {
+    expect(hueUtils.deXSS('<strong>Hello World</strong>')).toEqual('<strong>Hello World</strong>');
+  });
+
+  it('Should remove img tag from a string', () => {
+    expect(hueUtils.deXSS('<img src=asf onerror=alert(document.cookie) />hello')).toEqual('hello');
+  });
+
+  it('Should not remove p tag from a string', () => {
+    expect(hueUtils.deXSS('<p> Hello World </p>')).toEqual('<p> Hello World </p>');
+  });
+
+  it('Should not remove h1 tag from a string', () => {
+    expect(hueUtils.deXSS('<h1> Hello World </h1>')).toEqual('<h1> Hello World </h1>');
+  });
+
+  it('should preserve entities as such', () => {
+    expect(hueUtils.deXSS('<a name="&lt;silly&gt;">&lt;Kapow!&gt;</a>')).toEqual(
+      '<a name="&lt;silly&gt;">&lt;Kapow!&gt;</a>'
+    );
+  });
+
+  it('should dump comments', () => {
+    expect(hueUtils.deXSS('<p><!-- Blah blah -->Whee</p>')).toEqual('<p>Whee</p>');
+  });
+
+  it('should dump an uppercase javascript url', () => {
+    expect(hueUtils.deXSS('<a href="JAVASCRIPT:alert(\'foo\')">Hax</a>')).toEqual('<a>Hax</a>');
+  });
 });

+ 1 - 1
desktop/core/src/desktop/js/utils/multiLineEllipsisHandler.js

@@ -43,7 +43,7 @@ class MultiLineEllipsisHandler {
     this.updateOverflowHeight();
 
     this.contents = options.text;
-    this.element.innerHTML = this.contents;
+    this.element.innerHTML = hueUtils.deXSS(this.contents);
 
     const linkRegex = /(?:(?:[a-z]+:\/\/)|www\.)[^\s\/]+(?:[.\/]\S+)*[^\s`!()\[\]{};:'".,<>?«»“”‘’]/gi;
 

+ 135 - 6
package-lock.json

@@ -1,6 +1,6 @@
 {
   "name": "gethue",
-  "version": "4.8.0",
+  "version": "4.8.2",
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
@@ -7850,6 +7850,11 @@
       "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
       "dev": true
     },
+    "colorette": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz",
+      "integrity": "sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw=="
+    },
     "colors": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz",
@@ -9161,8 +9166,7 @@
     "deepmerge": {
       "version": "4.2.2",
       "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
-      "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
-      "dev": true
+      "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg=="
     },
     "define-properties": {
       "version": "1.1.3",
@@ -15776,6 +15780,11 @@
       "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==",
       "dev": true
     },
+    "klona": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.4.tgz",
+      "integrity": "sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA=="
+    },
     "knockout": {
       "version": "3.5.1",
       "resolved": "https://registry.npmjs.org/knockout/-/knockout-3.5.1.tgz",
@@ -16067,6 +16076,30 @@
         "immediate": "~3.0.5"
       }
     },
+    "line-column": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/line-column/-/line-column-1.0.2.tgz",
+      "integrity": "sha1-0lryk2tvSEkXKzEuR5LR2Ye8NKI=",
+      "requires": {
+        "isarray": "^1.0.0",
+        "isobject": "^2.0.0"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
+        },
+        "isobject": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+          "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+          "requires": {
+            "isarray": "1.0.0"
+          }
+        }
+      }
+    },
     "lines-and-columns": {
       "version": "1.1.6",
       "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz",
@@ -16856,6 +16889,11 @@
       "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==",
       "dev": true
     },
+    "nanoid": {
+      "version": "3.1.18",
+      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.18.tgz",
+      "integrity": "sha512-rndlDjbbHbcV3xi+R2fpJ+PbGMdfBxz5v1fATIQFq0DP64FsicQdwnKLy47K4kZHdRpmQXtz24eGsxQqamzYTA=="
+    },
     "nanomatch": {
       "version": "1.2.13",
       "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
@@ -17573,6 +17611,11 @@
       "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
       "dev": true
     },
+    "parse-srcset": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz",
+      "integrity": "sha1-8r0iH2zJcKk42IVWq8WJyqqiveE="
+    },
     "parse5": {
       "version": "5.1.1",
       "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz",
@@ -19064,6 +19107,92 @@
         "walker": "~1.0.5"
       }
     },
+    "sanitize-html": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.1.2.tgz",
+      "integrity": "sha512-i/h+fJal+609o6GlWFpQmAL7E5ZL4rrb0QwbDKQue2uift+4WKMe/HViRGawP4Q/UgswdDKxMqjDRrKPtCpBMg==",
+      "requires": {
+        "deepmerge": "^4.2.2",
+        "escape-string-regexp": "^4.0.0",
+        "htmlparser2": "^4.1.0",
+        "is-plain-object": "^5.0.0",
+        "klona": "^2.0.3",
+        "parse-srcset": "^1.0.2",
+        "postcss": "^8.0.2"
+      },
+      "dependencies": {
+        "dom-serializer": {
+          "version": "1.1.0",
+          "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.1.0.tgz",
+          "integrity": "sha512-ox7bvGXt2n+uLWtCRLybYx60IrOlWL/aCebWJk1T0d4m3y2tzf4U3ij9wBMUb6YJZpz06HCCYuyCDveE2xXmzQ==",
+          "requires": {
+            "domelementtype": "^2.0.1",
+            "domhandler": "^3.0.0",
+            "entities": "^2.0.0"
+          }
+        },
+        "domelementtype": {
+          "version": "2.0.2",
+          "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.2.tgz",
+          "integrity": "sha512-wFwTwCVebUrMgGeAwRL/NhZtHAUyT9n9yg4IMDwf10+6iCMxSkVq9MGCVEH+QZWo1nNidy8kNvwmv4zWHDTqvA=="
+        },
+        "domhandler": {
+          "version": "3.3.0",
+          "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-3.3.0.tgz",
+          "integrity": "sha512-J1C5rIANUbuYK+FuFL98650rihynUOEzRLxW+90bKZRWB6A1X1Tf82GxR1qAWLyfNPRvjqfip3Q5tdYlmAa9lA==",
+          "requires": {
+            "domelementtype": "^2.0.1"
+          }
+        },
+        "domutils": {
+          "version": "2.4.2",
+          "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.4.2.tgz",
+          "integrity": "sha512-NKbgaM8ZJOecTZsIzW5gSuplsX2IWW2mIK7xVr8hTQF2v1CJWTmLZ1HOCh5sH+IzVPAGE5IucooOkvwBRAdowA==",
+          "requires": {
+            "dom-serializer": "^1.0.1",
+            "domelementtype": "^2.0.1",
+            "domhandler": "^3.3.0"
+          }
+        },
+        "entities": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz",
+          "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w=="
+        },
+        "escape-string-regexp": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+          "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="
+        },
+        "htmlparser2": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-4.1.0.tgz",
+          "integrity": "sha512-4zDq1a1zhE4gQso/c5LP1OtrhYTncXNSpvJYtWJBtXAETPlMfi3IFNjGuQbYLuVY4ZR0QMqRVvo4Pdy9KLyP8Q==",
+          "requires": {
+            "domelementtype": "^2.0.1",
+            "domhandler": "^3.0.0",
+            "domutils": "^2.0.0",
+            "entities": "^2.0.0"
+          }
+        },
+        "is-plain-object": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
+          "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="
+        },
+        "postcss": {
+          "version": "8.1.8",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.1.8.tgz",
+          "integrity": "sha512-hO6jFWBy0QnBBRaw+s0F4hVPKGDICec/nLNEG1D4qqw9/LBzWMkTjckqqELXAo0J42jN8GFZXtgQfezEaoG9gQ==",
+          "requires": {
+            "colorette": "^1.2.1",
+            "line-column": "^1.0.2",
+            "nanoid": "^3.1.16",
+            "source-map": "^0.6.1"
+          }
+        }
+      }
+    },
     "sass-graph": {
       "version": "2.2.5",
       "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.5.tgz",
@@ -21902,9 +22031,9 @@
           "dev": true
         },
         "debug": {
-          "version": "4.2.0",
-          "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz",
-          "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==",
+          "version": "4.3.1",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
+          "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
           "dev": true,
           "requires": {
             "ms": "2.1.2"

+ 3 - 2
package.json

@@ -66,6 +66,7 @@
     "plotly.js-dist": "1.45.3",
     "regenerator-runtime": "^0.13.3",
     "removeNPMAbsolutePaths": "^1.0.4",
+    "sanitize-html": "^2.1.2",
     "select2": "3.5.1",
     "selectize": "0.12.6",
     "selectize-plugin-clear": "0.0.3",
@@ -73,9 +74,9 @@
     "vue": "2.6.11",
     "vue-class-component": "7.2.3",
     "vue-custom-element": "3.2.14",
-    "vuejs-datepicker": "1.6.2",
     "vue-property-decorator": "9.0.0",
-    "vue-template-compiler": "2.6.11"
+    "vue-template-compiler": "2.6.11",
+    "vuejs-datepicker": "1.6.2"
   },
   "devDependencies": {
     "@babel/core": "7.10.2",