From 6700f033ab2c2e6f5ab1293025d3485ecc37c321 Mon Sep 17 00:00:00 2001
From: "Cheng-Han, Wu" <jackymaxj@gmail.com>
Date: Thu, 11 Feb 2016 02:36:52 -0600
Subject: [PATCH] Prevent XSS in markdown rendering

---
 bower.json            | 3 ++-
 lib/response.js       | 3 +++
 package.json          | 7 ++++---
 public/js/index.js    | 1 +
 public/views/foot.ejs | 1 +
 5 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/bower.json b/bower.json
index db3d0f8..cf9b79b 100644
--- a/bower.json
+++ b/bower.json
@@ -33,6 +33,7 @@
     "js-yaml": "~3.5.2",
     "to-markdown": "~1.3.0",
     "lz-string": "~1.4.4",
-    "flowchart": "~1.6.1"
+    "flowchart": "~1.6.1",
+    "xss": "~0.2.10"
   }
 }
diff --git a/lib/response.js b/lib/response.js
index 07cb5ba..c12c4ca 100644
--- a/lib/response.js
+++ b/lib/response.js
@@ -11,6 +11,7 @@ var shortId = require('shortid');
 var metaMarked = require('meta-marked');
 var querystring = require('querystring');
 var request = require('request');
+var xss = require('xss');
 
 //core
 var config = require("../config.js");
@@ -227,6 +228,7 @@ function showPublishNote(req, res, next) {
                         //na
                     }
                     var updatetime = notedata.update_time;
+                    body = xss(body); // prevent xss
                     var text = S(body).escapeHTML().s;
                     var title = notedata.title;
                     var decodedTitle = LZString.decompressFromBase64(title);
@@ -610,6 +612,7 @@ function showPublishSlide(req, res, next) {
                     var decodedTitle = LZString.decompressFromBase64(title);
                     if (decodedTitle) title = decodedTitle;
                     title = Note.generateWebTitle(title);
+                    body = xss(body); // prevent xss
                     var text = S(body).escapeHTML().s;
                     render(res, title, text);
                 });
diff --git a/package.json b/package.json
index e46b032..d96fabc 100644
--- a/package.json
+++ b/package.json
@@ -14,7 +14,6 @@
     "cheerio": "^0.19.0",
     "compression": "^1.6.0",
     "connect-mongo": "^1.1.0",
-    "kerberos": "0.0.17",
     "cookie": "0.2.3",
     "cookie-parser": "1.4.1",
     "ejs": "^2.3.4",
@@ -25,6 +24,7 @@
     "highlight.js": "^9.1.0",
     "imgur": "^0.1.7",
     "jsdom-nogyp": "^0.8.3",
+    "kerberos": "0.0.17",
     "lz-string": "1.4.4",
     "markdown-pdf": "^6.0.0",
     "marked": "^0.3.5",
@@ -33,6 +33,7 @@
     "moment": "^2.11.1",
     "mongoose": "^4.3.6",
     "morgan": "^1.6.1",
+    "mustache": "2.2.1",
     "node-uuid": "^1.4.7",
     "passport": "^0.3.2",
     "passport-dropbox-oauth2": "^1.0.0",
@@ -43,13 +44,13 @@
     "pg": "4.x",
     "randomcolor": "^0.4.3",
     "request": "^2.69.0",
+    "reveal.js": "3.2.0",
     "shortid": "2.2.4",
     "socket.io": "1.4.4",
     "string": "^3.3.1",
     "toobusy-js": "^0.4.2",
     "winston": "^2.1.1",
-    "mustache": "2.2.1",
-    "reveal.js": "3.2.0"
+    "xss": "^0.2.10"
   },
   "engines": {
     "node": ">=4.x"
diff --git a/public/js/index.js b/public/js/index.js
index b4e33ae..ad77e0d 100644
--- a/public/js/index.js
+++ b/public/js/index.js
@@ -2131,6 +2131,7 @@ var lastResult = null;
 function updateViewInner() {
     if (currentMode == modeType.edit || !isDirty) return;
     var value = editor.getValue();
+    value = filterXSS(value); // prevent xss
     md.meta = {};
     md.render(value); //only for get meta
     parseMeta(md, ui.area.markdown, $('#toc'), $('#toc-affix'));
diff --git a/public/views/foot.ejs b/public/views/foot.ejs
index b0006f7..3a5ef14 100644
--- a/public/views/foot.ejs
+++ b/public/views/foot.ejs
@@ -29,6 +29,7 @@
 <script src="/vendor/remarkable-regex.js" defer></script>
 <script src="/vendor/gist-embed.js" defer></script>
 <script src="/vendor/lz-string/libs/lz-string.min.js" defer></script>
+<script src="/vendor/xss/dist/xss.min.js" defer></script>
 <script src="/vendor/string.min.js" defer></script>
 <script src="/vendor/highlight-js/highlight.min.js" defer></script>
 <script src="/vendor/js.cookie.js" defer></script>