CVE-2018-9113: Improper Control of Generation of Code ('Code Injection') (CWE-94)
value: Centers for Disease Control and Prevention MicrobeTRACE 0.1.12 allows remote attackers to execute arbitrary code, related to code injection via a crafted CSV file with an initial '><script type="text/javascript" src=' line. Fix released on 2018-03-29.
CWE description: The product constructs all or part of a code segment using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the syntax or behavior of the intended code segment.
CVSS v3 base score: 7.8
Published: 2018-04-26T06:29Z
Repository: https://github.com/CDCgov/MicrobeTrace
Language: JavaScript
Files changed: components/files.html, index.html, index.js, package.json, scripts/common.js, yarn.lock
Commit date: 2018-03-29 14:06:58 -0400
Commit message: Filtered for XSS attacks properly


Diff: diff --git a/components/files.html b/components/files.html
index 505fdc3..af728b9 100644
--- a/components/files.html
+++ b/components/files.html
@@ -112,11 +112,11 @@ function addFileToTable(file){
   Papa.parse(file, {
     dynamicTyping: true,
     header: true,
     preview: 1,
     complete: function(output){
-      var headers = output.meta.fields.map(app.striptags);
+      var headers = output.meta.fields.map(filterXSS);
       var options = '<option>None</option>' + headers.map(h => `<option value="${h}">${app.titleize(h)}</option>`).join('\n');
       $(`<div class='col-4 '${isFasta?' style="display: none;"':''} data-file='${file.name}'>
           <label for="file-${file.name}-field-1">${isNode?'ID':'Source'}</label>
           <select id="file-${file.name}-field-1" class="custom-select custom-select-sm">${options}</select>
         </div>
@@ -187,11 +187,11 @@ $('#refSeqFileLoad').filestyle({
 $('#refSeqFileLoad').on('change', function(e){
   var file = e.target.files[0];
   var reader = new FileReader();
   reader.onloadend = function(e){
     if (e.target.readyState == FileReader.DONE){
-      $('#reference').val(app.striptags(app.parseFASTA(e.target.result)[0].seq));
+      $('#reference').val(filterXSS(app.parseFASTA(e.target.result)[0].seq));
     }
   };
   reader.readAsText(file);
 });
 
@@ -252,12 +252,12 @@ $('#main-submit').click(function(e){
       reader.onloadend = function(e){
         anySequences = true;
         var n = 0;
         var seqs = app.parseFASTA(e.target.result);
         seqs.forEach(node => {
-          node.id = app.striptags(node.id);
-          node.seq = app.striptags(node.seq);
+          node.id = filterXSS(node.id);
+          node.seq = filterXSS(node.seq);
           node['origin'] = [filename];
           n += app.addNode(node);
         });
         message(` - Parsed ${n} New, ${seqs.length} Total Nodes from FASTA.`);
         if(fileNum == files.length - 1) nextStuff();
@@ -274,11 +274,11 @@ $('#main-submit').click(function(e){
         dynamicTyping: true,
         skipEmptyLines: true,
         complete: results => {
           results.data.forEach(link => {
             Object.keys(link).forEach(function(key){
-              link[key] = app.striptags(link[key]);
+              link[key] = filterXSS(link[key]);
             });
             l += app.addLink(Object.assign({
               source: '' + link[file.field1],
               target: '' + link[file.field2],
               distance: file.field3 === 'None' ? 0 : link[file.field3],
@@ -286,11 +286,11 @@ $('#main-submit').click(function(e){
               visible: 1
             }, link));
           });
           message(` - Parsed ${l} New, ${results.data.length} Total Links from Link CSV.`);
           results.meta.fields.map(key => {
-            key = app.striptags(key);
+            key = filterXSS(key);
             if(!session.data.linkFields.includes(key)){
               session.data.linkFields.push(key);
             }
           });
           var n = 0;
@@ -315,18 +315,18 @@ $('#main-submit').click(function(e){
         dynamicTyping: true,
         skipEmptyLines: true,
         complete: results => {
           var n = 0;
           results.data.forEach(node => {
-            node = JSON.parse(app.striptags(JSON.stringify(node)));
+            node = JSON.parse(filterXSS(JSON.stringify(node)));
             node.id = '' + node[file.field1];
             if(file.field2 !== 'None') node.seq = node[file.field2];
             node['origin'] = [filename];
             n += app.addNode(node);
           });
           results.meta.fields.forEach(key => {
-            key = app.striptags(key);
+            key = filterXSS(key);
             if(!session.data.nodeFields.includes(key)){
               session.data.nodeFields.push(key);
             }
           });
           if(results.meta.fields.includes('seq')) anySequences = 1;
@@ -346,11 +346,11 @@ $('#main-submit').click(function(e){
         complete: results => {
           var nodeIDs = [];
           var nn = 0, nl = 0;
           results.data.forEach((row, i) => {
             if(i == 0){
-              nodeIDs = row.map(app.striptags);
+              nodeIDs = row.map(filterXSS);
               nodeIDs.forEach((cell, k) => {
                 if(k > 0){
                   nn += app.addNode({
                     id: '' + cell,
                     origin: [filename]
@@ -402,11 +402,11 @@ $('#main-submit').click(function(e){
         session.network.force.alpha(0.3).alphaTarget(0).restart();
         session.network.updateStatistics();
         $('#loadingInformationModal').modal('hide');
         setTimeout(session.network.fit, 1500);
       }
-      drawthresholdHistogram();
+      session.updateThresholdHistogram();
     }
   };
 
   var alignAndComputeDM = function(subset){
     message('Aligning Sequences...');
@@ -448,18 +448,19 @@ $('#main-submit').click(function(e){
         setTimeout(function(){
           session.network.fit();
           $('#loadingInformationModal').modal('hide');
         }, 1500);
       }
-      drawthresholdHistogram();
+      session.updateThresholdHistogram();
     };
   };
 
-  function drawthresholdHistogram(){
+  session.updateThresholdHistogram = function(){
     var width = 280,
         height = 48,
         svg = d3.select("svg#link-threshold-sparkline")
+          .html(null)
           .attr('width', width)
           .attr('height', height);
 
     var lsv = $('#linkSortVariable').val();
     var data = session.data.links.map(function(l){ return parseFloat(l[lsv]); }),
@@ -488,18 +489,13 @@ $('#main-submit').click(function(e){
     bar.append("rect")
         .attr("x", 1)
         .attr("width", 6)
         .attr("height", function(d) { return height - y(d.length); });
 
-    svg.append("g")
-        .attr("class", "axis axis--x")
-        .attr("transform", "translate(0," + height + ")")
-        .call(d3.axisBottom(x));
-
     function updateThreshold(){
       var x = d3.mouse(svg.node())[0],
-      range = max - min;
+          range = max - min;
       session.state.linkThreshold = x / width * range + min;
       $('#default-link-threshold').val(session.state.linkThreshold);
     }
 
     svg.on('click', function(){
@@ -527,9 +523,9 @@ $('#main-submit').click(function(e){
         svg
           .on('mousemove', null)
           .on('mouseup', null);
       });
     });
-  }
+  };
 });
 
 </script>
diff --git a/index.html b/index.html
index d53dab8..a0937ef 100644
--- a/index.html
+++ b/index.html
@@ -348,21 +348,22 @@ performance of this software.</pre>
   <script type="text/javascript" src="node_modules/vue/dist/vue.min.js"></script>
   <script type="text/javascript" src="node_modules/lodash/lodash.min.js"></script>
   <script type="text/javascript" src="node_modules/jquery/dist/jquery.min.js"></script>
   <script type="text/javascript" src="node_modules/popper.js/dist/umd/popper.min.js"></script>
   <script type="text/javascript" src="node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
-  <script type="text/javascript" src="vendor/bootstrap-filestyle.min.js"></script>
   <script type="text/javascript" src="node_modules/golden-layout/dist/goldenlayout.min.js"></script>
-  <script type="text/javascript" src="node_modules/html2canvas/dist/html2canvas.min.js"></script>
   <script type="text/javascript" src="node_modules/papaparse/papaparse.min.js"></script>
+  <script type="text/javascript" src="node_modules/xss/dist/xss.min.js"></script>
+  <script type="text/javascript" src="node_modules/d3/dist/d3.min.js"></script>
+  <script type="text/javascript" src="node_modules/plotly.js/dist/plotly.min.js"></script>
   <script type="text/javascript" src="node_modules/alertifyjs/build/alertify.min.js"></script>
-  <script type="text/javascript" src="node_modules/screenfull/dist/screenfull.js"></script>
   <script type="text/javascript" src="vendor/FileSaver.min.js"></script>
+  <script type="text/javascript" src="node_modules/html2canvas/dist/html2canvas.min.js"></script>
+  <script type="text/javascript" src="node_modules/screenfull/dist/screenfull.js"></script>
   <script type="text/javascript" src="node_modules/clipboard/dist/clipboard.min.js"></script>
+  <script type="text/javascript" src="vendor/bootstrap-filestyle.min.js"></script>
   <script type="text/javascript" src="node_modules/chosen-js/chosen.jquery.min.js"></script>
-  <script type="text/javascript" src="node_modules/d3/dist/d3.min.js"></script>
-  <script type="text/javascript" src="node_modules/plotly.js/dist/plotly.min.js"></script>
   <script type="text/javascript" src="scripts/common.js"></script>
   <script type="text/javascript">
   $(function(){
     "use strict";
 
diff --git a/index.js b/index.js
index 8d1719d..e624457 100755
--- a/index.js
+++ b/index.js
@@ -1,6 +1,7 @@
-const express = require('express')
-const PORT = process.env.PORT || 5000
+#!/usr/bin/env node
+
+const express = require('express');
 
 express()
   .use(express.static(__dirname))
-  .listen(PORT, () => console.log(`Listening on ${ PORT }`))
+  .listen(process.env.PORT || 5000);
diff --git a/package.json b/package.json
index 1ce14bf..bb6160d 100644
--- a/package.json
+++ b/package.json
@@ -8,16 +8,15 @@
   "engines": {
     "node": "9.8.0",
     "yarn": "1.5.1"
   },
   "scripts": {
-    "appcache": "./appcache.sh",
+    "appcache": "sh appcache.sh",
     "start": "node index.js",
     "build": "yarn start && nativifier http://localhost:8080"
   },
   "devDependencies": {
-    "express": "^4.16.3",
     "nativefier": "^7.5.4",
     "yarn": "^1.5.0"
   },
   "dependencies": {
     "3d-force-graph": "^1.25.0",
@@ -33,10 +32,11 @@
     "d3-symbol-extra": "^0.1.0",
     "datatables.net-bs4": "^1.10.16",
     "datatables.net-scroller-bs4": "^1.4.4",
     "datatables.net-select": "^1.2.5",
     "datatables.net-select-bs4": "^1.2.5",
+    "express": "^4.16.3",
     "golden-layout": "^1.5.9",
     "html2canvas": "^1.0.0-alpha.10",
     "jquery": "^3.3.1",
     "lodash": "^4.17.5",
     "msa": "^1.0.3",
@@ -45,8 +45,9 @@
     "plotly.js": "^1.34.0",
     "popper.js": "^1.12.9",
     "screenfull": "^3.3.2",
     "tn93": "^0.1.1",
     "vis": "^4.21.0",
-    "vue": "^2.5.16"
+    "vue": "^2.5.16",
+    "xss": "^0.3.7"
   }
 }
diff --git a/scripts/common.js b/scripts/common.js
index 37d17e9..4bb6e1a 100644
--- a/scripts/common.js
+++ b/scripts/common.js
@@ -113,17 +113,10 @@ app.parseNewick = function(a){
     }
   }
   return r;
 };
 
-app.striptags = function(inp){
-  return ('' + inp)
-    .replace(/<[^>]+?>.*?<\/[^>]+?>/g, '') //Closed Tags
-    .replace(/<[^>]+?\/\s*>/g, '') //Self-Closing Tags
-    .replace(/<[^>]+?>/g, ''); //Unclosed Tags
-};
-
 app.titleize = function(title){
   var small = title.toLowerCase().replace(/_/g, ' ');
   if(small === 'id') return 'ID';
   if(small === 'tn93') return 'TN93';
   if(small === 'snps') return 'SNPs';
diff --git a/yarn.lock b/yarn.lock
index 622c90b..cd12c16 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -290,20 +290,20 @@ asn1@~0.2.3:
 
 assert-plus@1.0.0, assert-plus@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
 
-async@^1.5.2, async@~1.5:
-  version "1.5.2"
-  resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
-
 async@^2.6.0:
   version "2.6.0"
   resolved "https://registry.yarnpkg.com/async/-/async-2.6.0.tgz#61a29abb6fcc026fea77e56d1c6ec53a795951f4"
   dependencies:
     lodash "^4.14.0"
 
+async@~1.5:
+  version "1.5.2"
+  resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
+
 asynckit@^0.4.0:
   version "0.4.0"
   resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
 
 atob-lite@^1.0.0:
@@ -858,14 +858,10 @@ colormap@^2.1.0:
   version "2.3.0"
   resolved "https://registry.yarnpkg.com/colormap/-/colormap-2.3.0.tgz#f725c757c5c6f0940a5342a723c68044ac06cc15"
   dependencies:
     lerp "^1.0.3"
 
-colors@1.0.3:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b"
-
 colors@~0.6.0-1:
   version "0.6.2"
   resolved "https://registry.yarnpkg.com/colors/-/colors-0.6.2.tgz#2423fe6678ac0c5dae8852e5d0e5be08c997abcc"
 
 combined-stream@1.0.6, combined-stream@~1.0.5:
@@ -961,14 +957,10 @@ core-js@^2.0.0, core-js@^2.4.0, core-js@^2.5.0:
 
 core-util-is@1.0.2, core-util-is@~1.0.0:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
 
-corser@~2.0.0:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/corser/-/corser-2.0.1.tgz#8eda252ecaab5840dcd975ceb90d9370c819ff87"
-
 country-regex@^1.1.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/country-regex/-/country-regex-1.1.0.tgz#51c333dcdf12927b7e5eeb9c10ac8112a6120896"
 
 cryptiles@3.x.x:
@@ -998,10 +990,14 @@ css-what@2.1:
 
 csscolorparser@~1.0.2:
   version "1.0.3"
   resolved "https://registry.yarnpkg.com/csscolorparser/-/csscolorparser-1.0.3.tgz#b34f391eea4da8f3e98231e2ccd8df9c041f171b"
 
+cssfilter@0.0.10:
+  version "0.0.10"
+  resolved "https://registry.yarnpkg.com/cssfilter/-/cssfilter-0.0.10.tgz#c6d2672632a2e5c83e013e6864a42ce8defd20ae"
+
 cssom@0.3.x, "cssom@>= 0.3.0 < 0.4.0":
   version "0.3.2"
   resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.2.tgz#b8036170c79f07a90ff2f16e22284027a243848b"
 
 "cssstyle@>= 0.2.29 < 0.3.0":
@@ -1533,19 +1529,10 @@ ecc-jsbn@~0.1.1:
   version "0.1.1"
   resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505"
   dependencies:
     jsbn "~0.1.0"
 
-ecstatic@^3.0.0:
-  version "3.2.0"
-  resolved "https://registry.yarnpkg.com/ecstatic/-/ecstatic-3.2.0.tgz#1b1aee1ca7c6b99cfb5cf6c9b26b481b90c4409f"
-  dependencies:
-    he "^1.1.1"
-    mime "^1.4.1"
-    minimist "^1.1.0"
-    url-join "^2.0.2"
-
 edges-to-adjacency-list@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/edges-to-adjacency-list/-/edges-to-adjacency-list-1.0.0.tgz#c146d2e084addfba74a51293c6e0199a49f757f1"
   dependencies:
     uniq "^1.0.0"
@@ -1746,14 +1733,10 @@ esutils@~1.0.0:
 
 etag@~1.8.1:
   version "1.8.1"
   resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
 
-eventemitter3@1.x.x:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-1.2.0.tgz#1c86991d816ad1e504750e73874224ecf3bec508"
-
 events@^1.0.2:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924"
 
 expect.js@~0.2.0:
@@ -2588,14 +2571,10 @@ hawk@~6.0.2:
     boom "4.x.x"
     cryptiles "3.x.x"
     hoek "4.x.x"
     sntp "2.x.x"
 
-he@^1.1.1:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd"
-
 hoek@4.x.x:
   version "4.2.1"
   resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.1.tgz#9634502aa12c445dd5a7c5734b572bb8738aacbb"
 
 hosted-git-info@^2.1.4:
@@ -2640,30 +2619,10 @@ http-errors@1.6.2, http-errors@~1.6.2:
     depd "1.1.1"
     inherits "2.0.3"
     setprototypeof "1.0.3"
     statuses ">= 1.3.1 < 2"
 
-http-proxy@^1.8.1:
-  version "1.16.2"
-  resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.16.2.tgz#06dff292952bf64dbe8471fa9df73066d4f37742"
-  dependencies:
-    eventemitter3 "1.x.x"
-    requires-port "1.x.x"
-
-http-server@^0.11.1:
-  version "0.11.1"
-  resolved "https://registry.yarnpkg.com/http-server/-/http-server-0.11.1.tgz#2302a56a6ffef7f9abea0147d838a5e9b6b6a79b"
-  dependencies:
-    colors "1.0.3"
-    corser "~2.0.0"
-    ecstatic "^3.0.0"
-    http-proxy "^1.8.1"
-    opener "~1.4.0"
-    optimist "0.6.x"
-    portfinder "^1.0.13"
-    union "~0.4.3"
-
 http-signature@~1.2.0:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
   dependencies:
     assert-plus "^1.0.0"
@@ -3157,14 +3116,10 @@ mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.18:
 
 mime@1.4.1:
   version "1.4.1"
   resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6"
 
-mime@^1.4.1:
-  version "1.6.0"
-  resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
-
 min-document@^2.19.0:
   version "2.19.0"
   resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685"
   dependencies:
     dom-walk "^0.1.0"
@@ -3185,21 +3140,17 @@ minimist@0.0.8:
 
 minimist@1.2.0, minimist@^1.1.0, minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@~1.2.0:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
 
-minimist@~0.0.1:
-  version "0.0.10"
-  resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf"
-
 mkdirp@0.5.0:
   version "0.5.0"
   resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.0.tgz#1d73076a6df986cd9344e15e71fcc05a4c9abf12"
   dependencies:
     minimist "0.0.8"
 
-mkdirp@0.5.x, mkdirp@^0.5.0:
+mkdirp@^0.5.0:
   version "0.5.1"
   resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
   dependencies:
     minimist "0.0.8"
 
@@ -3622,25 +3573,14 @@ once@~1.3.0:
 
 open-iconic@^1.1.1:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/open-iconic/-/open-iconic-1.1.1.tgz#9dcfc8c7cd3c61cdb4a236b1a347894c97adc0c6"
 
-opener@~1.4.0:
-  version "1.4.3"
-  resolved "https://registry.yarnpkg.com/opener/-/opener-1.4.3.tgz#5c6da2c5d7e5831e8ffa3964950f8d6674ac90b8"
-
 optical-properties@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/optical-properties/-/optical-properties-1.0.0.tgz#c3a694bbab7cc4587070886c47f43c8c3a6cceae"
 
-optimist@0.6.x:
-  version "0.6.1"
-  resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686"
-  dependencies:
-    minimist "~0.0.1"
-    wordwrap "~0.0.2"
-
 optionator@^0.8.1:
   version "0.8.2"
   resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64"
   dependencies:
     deep-is "~0.1.3"
@@ -3949,18 +3889,10 @@ polytope-closest-point@^1.0.0:
 
 popper.js@^1.12.9:
   version "1.14.1"
   resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.14.1.tgz#b8815e5cda6f62fc2042e47618649f75866e6753"
 
-portfinder@^1.0.13:
-  version "1.0.13"
-  resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.13.tgz#bb32ecd87c27104ae6ee44b5a3ccbf0ebb1aede9"
-  dependencies:
-    async "^1.5.2"
-    debug "^2.2.0"
-    mkdirp "0.5.x"
-
 prelude-ls@~1.1.2:
   version "1.1.2"
   resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
 
 pretty-bytes@^1.0.2:
@@ -4022,14 +3954,10 @@ q@^1.1.2:
 
 qs@6.5.1, qs@~6.5.1:
   version "6.5.1"
   resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8"
 
-qs@~2.3.3:
-  version "2.3.3"
-  resolved "https://registry.yarnpkg.com/qs/-/qs-2.3.3.tgz#e9e85adbe75da0bbe4c8e0476a086290f863b404"
-
 quat-slerp@^1.0.0:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/quat-slerp/-/quat-slerp-1.0.1.tgz#2baa15ce3a6bbdc3241d972eb17283139ed69f29"
   dependencies:
     gl-quat "^1.0.0"
@@ -4277,14 +4205,10 @@ request@^2.45.0, request@^2.55.0, request@^2.72.0, request@^2.79.0:
     stringstream "~0.0.5"
     tough-cookie "~2.3.3"
     tunnel-agent "^0.6.0"
     uuid "^3.1.0"
 
-requires-port@1.x.x:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
-
 resolve-protobuf-schema@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/resolve-protobuf-schema/-/resolve-protobuf-schema-2.0.0.tgz#e67b062a67f02d11bd6886e70efda788407e0fb4"
   dependencies:
     protocol-buffers-schema "^2.0.2"
@@ -5187,16 +5111,10 @@ union-find@^1.0.0, union-find@^1.0.2:
 
 union-find@~0.0.3:
   version "0.0.4"
   resolved "https://registry.yarnpkg.com/union-find/-/union-find-0.0.4.tgz#b854b3301619bdad144b0014c78f96eac0d2f0f6"
 
-union@~0.4.3:
-  version "0.4.6"
-  resolved "https://registry.yarnpkg.com/union/-/union-0.4.6.tgz#198fbdaeba254e788b0efcb630bc11f24a2959e0"
-  dependencies:
-    qs "~2.3.3"
-
 uniq@^1.0.0, uniq@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff"
 
 universalify@^0.1.0:
@@ -5209,14 +5127,10 @@ unpipe@1.0.0, unpipe@~1.0.0:
 
 update-diff@^1.0.2, update-diff@^1.1.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/update-diff/-/update-diff-1.1.0.tgz#f510182d81ee819fb82c3a6b22b62bbdeda7808f"
 
-url-join@^2.0.2:
-  version "2.0.5"
-  resolved "https://registry.yarnpkg.com/url-join/-/url-join-2.0.5.tgz#5af22f18c052a000a48d7b82c5e9c2e2feeda728"
-
 utf8-byte-length@^1.0.1:
   version "1.0.4"
   resolved "https://registry.yarnpkg.com/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz#f45f150c4c66eee968186505ab93fcbb8ad6bf61"
 
 util-deprecate@~1.0.1:
@@ -5334,14 +5248,10 @@ window-size@0.1.0:
 
 wordwrap@0.0.2:
   version "0.0.2"
   resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f"
 
-wordwrap@~0.0.2:
-  version "0.0.3"
-  resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107"
-
 wordwrap@~1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
 
 world-calendars@^1.0.3:
@@ -5379,10 +5289,17 @@ xmldoc@^0.5.1:
 
 xmldom@0.1.x:
   version "0.1.27"
   resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.27.tgz#d501f97b3bdb403af8ef9ecc20573187aadac0e9"
 
+xss@^0.3.7:
+  version "0.3.7"
+  resolved "https://registry.yarnpkg.com/xss/-/xss-0.3.7.tgz#1df6dc85c0240b455b5e5f0428bdeccd739ab4ee"
+  dependencies:
+    commander "^2.9.0"
+    cssfilter "0.0.10"
+
 "xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0, xtend@~4.0.1:
   version "4.0.1"
   resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"
 
 xtend@^2.1.2:

Vulnerable code:       var headers = output.meta.fields.map(app.striptags);
      $('#reference').val(app.striptags(app.parseFASTA(e.target.result)[0].seq));
          node.id = app.striptags(node.id);
          node.seq = app.striptags(node.seq);
              link[key] = app.striptags(link[key]);
            key = app.striptags(key);
            node = JSON.parse(app.striptags(JSON.stringify(node)));
            key = app.striptags(key);
              nodeIDs = row.map(app.striptags);
      drawthresholdHistogram();
      drawthresholdHistogram();
  function drawthresholdHistogram(){
    svg.append("g")
        .attr("class", "axis axis--x")
        .attr("transform", "translate(0," + height + ")")
        .call(d3.axisBottom(x));

      range = max - min;
  }
  <script type="text/javascript" src="vendor/bootstrap-filestyle.min.js"></script>
  <script type="text/javascript" src="node_modules/html2canvas/dist/html2canvas.min.js"></script>
  <script type="text/javascript" src="node_modules/screenfull/dist/screenfull.js"></script>
  <script type="text/javascript" src="node_modules/d3/dist/d3.min.js"></script>
  <script type="text/javascript" src="node_modules/plotly.js/dist/plotly.min.js"></script>
const express = require('express')
const PORT = process.env.PORT || 5000
  .listen(PORT, () => console.log(`Listening on ${ PORT }`))
    "appcache": "./appcache.sh",
    "express": "^4.16.3",
    "vue": "^2.5.16"
app.striptags = function(inp){
  return ('' + inp)
    .replace(/<[^>]+?>.*?<\/[^>]+?>/g, '') //Closed Tags
    .replace(/<[^>]+?\/\s*>/g, '') //Self-Closing Tags
    .replace(/<[^>]+?>/g, ''); //Unclosed Tags
};

async@^1.5.2, async@~1.5:
  version "1.5.2"
  resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"

colors@1.0.3:
  version "1.0.3"
  resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b"

corser@~2.0.0:
  version "2.0.1"
  resolved "https://registry.yarnpkg.com/corser/-/corser-2.0.1.tgz#8eda252ecaab5840dcd975ceb90d9370c819ff87"

ecstatic@^3.0.0:
  version "3.2.0"
  resolved "https://registry.yarnpkg.com/ecstatic/-/ecstatic-3.2.0.tgz#1b1aee1ca7c6b99cfb5cf6c9b26b481b90c4409f"
  dependencies:
    he "^1.1.1"
    mime "^1.4.1"
    minimist "^1.1.0"
    url-join "^2.0.2"

eventemitter3@1.x.x:
  version "1.2.0"
  resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-1.2.0.tgz#1c86991d816ad1e504750e73874224ecf3bec508"

he@^1.1.1:
  version "1.1.1"
  resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd"

http-proxy@^1.8.1:
  version "1.16.2"
  resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.16.2.tgz#06dff292952bf64dbe8471fa9df73066d4f37742"
  dependencies:
    eventemitter3 "1.x.x"
    requires-port "1.x.x"

http-server@^0.11.1:
  version "0.11.1"
  resolved "https://registry.yarnpkg.com/http-server/-/http-server-0.11.1.tgz#2302a56a6ffef7f9abea0147d838a5e9b6b6a79b"
  dependencies:
    colors "1.0.3"
    corser "~2.0.0"
    ecstatic "^3.0.0"
    http-proxy "^1.8.1"
    opener "~1.4.0"
    optimist "0.6.x"
    portfinder "^1.0.13"
    union "~0.4.3"

mime@^1.4.1:
  version "1.6.0"
  resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"

minimist@~0.0.1:
  version "0.0.10"
  resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf"

mkdirp@0.5.x, mkdirp@^0.5.0:
opener@~1.4.0:
  version "1.4.3"
  resolved "https://registry.yarnpkg.com/opener/-/opener-1.4.3.tgz#5c6da2c5d7e5831e8ffa3964950f8d6674ac90b8"

optimist@0.6.x:
  version "0.6.1"
  resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686"
  dependencies:
    minimist "~0.0.1"
    wordwrap "~0.0.2"

portfinder@^1.0.13:
  version "1.0.13"
  resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.13.tgz#bb32ecd87c27104ae6ee44b5a3ccbf0ebb1aede9"
  dependencies:
    async "^1.5.2"
    debug "^2.2.0"
    mkdirp "0.5.x"

qs@~2.3.3:
  version "2.3.3"
  resolved "https://registry.yarnpkg.com/qs/-/qs-2.3.3.tgz#e9e85adbe75da0bbe4c8e0476a086290f863b404"

requires-port@1.x.x:
  version "1.0.0"
  resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"

union@~0.4.3:
  version "0.4.6"
  resolved "https://registry.yarnpkg.com/union/-/union-0.4.6.tgz#198fbdaeba254e788b0efcb630bc11f24a2959e0"
  dependencies:
    qs "~2.3.3"

url-join@^2.0.2:
  version "2.0.5"
  resolved "https://registry.yarnpkg.com/url-join/-/url-join-2.0.5.tgz#5af22f18c052a000a48d7b82c5e9c2e2feeda728"

wordwrap@~0.0.2:
  version "0.0.3"
  resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107"

Fixed code:       var headers = output.meta.fields.map(filterXSS);
      $('#reference').val(filterXSS(app.parseFASTA(e.target.result)[0].seq));
          node.id = filterXSS(node.id);
          node.seq = filterXSS(node.seq);
              link[key] = filterXSS(link[key]);
            key = filterXSS(key);
            node = JSON.parse(filterXSS(JSON.stringify(node)));
            key = filterXSS(key);
              nodeIDs = row.map(filterXSS);
      session.updateThresholdHistogram();
      session.updateThresholdHistogram();
  session.updateThresholdHistogram = function(){
          .html(null)
          range = max - min;
  };
  <script type="text/javascript" src="node_modules/xss/dist/xss.min.js"></script>
  <script type="text/javascript" src="node_modules/d3/dist/d3.min.js"></script>
  <script type="text/javascript" src="node_modules/plotly.js/dist/plotly.min.js"></script>
  <script type="text/javascript" src="node_modules/html2canvas/dist/html2canvas.min.js"></script>
  <script type="text/javascript" src="node_modules/screenfull/dist/screenfull.js"></script>
  <script type="text/javascript" src="vendor/bootstrap-filestyle.min.js"></script>
#!/usr/bin/env node

const express = require('express');
  .listen(process.env.PORT || 5000);
    "appcache": "sh appcache.sh",
    "express": "^4.16.3",
    "vue": "^2.5.16",
    "xss": "^0.3.7"
async@~1.5:
  version "1.5.2"
  resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"

cssfilter@0.0.10:
  version "0.0.10"
  resolved "https://registry.yarnpkg.com/cssfilter/-/cssfilter-0.0.10.tgz#c6d2672632a2e5c83e013e6864a42ce8defd20ae"

mkdirp@^0.5.0:
xss@^0.3.7:
  version "0.3.7"
  resolved "https://registry.yarnpkg.com/xss/-/xss-0.3.7.tgz#1df6dc85c0240b455b5e5f0428bdeccd739ab4ee"
  dependencies:
    commander "^2.9.0"
    cssfilter "0.0.10"