Просмотр исходного кода

Imprv: Prevent XSS (Cross Site Scripting) - Part 1

client-side processing
Yuki Takei 8 лет назад
Родитель
Сommit
42bd98431a

+ 12 - 15
lib/models/revision.js

@@ -1,7 +1,7 @@
 module.exports = function(crowi) {
   var debug = require('debug')('crowi:models:revision')
     , mongoose = require('mongoose')
-    , xss = require('xss')
+    , Xss = require('../util/xss')
     , ObjectId = mongoose.Schema.Types.ObjectId
     , revisionSchema;
 
@@ -13,20 +13,17 @@ module.exports = function(crowi) {
     createdAt: { type: Date, default: Date.now }
   });
 
-  // create a XSS Filter instance
-  const myxss = new xss.FilterXSS({
-    stripIgnoreTag: true,
-    css: false,
-    // allow all attributes
-    onTagAttr: function (tag, name, value, isWhiteAttr) {
-      return `${name}="${value}"`;
-    }
-  });
-  // prevent XSS when pre save
-  revisionSchema.pre('save', function(next) {
-    this.body = myxss.process(this.body);
-    next();
-  });
+  /*
+   * preparation for https://github.com/weseek/crowi-plus/issues/216
+   */
+  // // create a XSS Filter instance
+  // // TODO read options
+  // this.xss = new Xss(true);
+  // // prevent XSS when pre save
+  // revisionSchema.pre('save', function(next) {
+  //   this.body = xss.process(this.body);
+  //   next();
+  // });
 
   revisionSchema.statics.findLatestRevision = function(path, cb) {
     this.find({path: path})

+ 27 - 0
lib/util/xss.js

@@ -0,0 +1,27 @@
+class Xss {
+
+  constructor(isAllowAllAttrs) {
+    const xss = require('xss');
+
+    // create the option object
+    let option = {
+      stripIgnoreTag: true,
+      css: false,
+    };
+    if (isAllowAllAttrs) {
+      // allow all attributes
+      option.onTagAttr = function(tag, name, value, isWhiteAttr) {
+        return `${name}="${value}"`;
+      }
+    }
+    // create the XSS Filter instance
+    this.myxss = new xss.FilterXSS(option);
+  }
+
+  process(markdown) {
+    return this.myxss.process(markdown);
+  }
+
+}
+
+module.exports = Xss;

+ 2 - 0
resource/js/util/CrowiRenderer.js

@@ -4,6 +4,7 @@ import hljs from 'highlight.js';
 import MarkdownFixer from './PreProcessor/MarkdownFixer';
 import Linker        from './PreProcessor/Linker';
 import ImageExpander from './PreProcessor/ImageExpander';
+import XssFilter from './PreProcessor/XssFilter';
 
 import Emoji         from './PostProcessor/Emoji';
 import Mathjax       from './PostProcessor/Mathjax';
@@ -22,6 +23,7 @@ export default class CrowiRenderer {
       new MarkdownFixer(crowi),
       new Linker(crowi),
       new ImageExpander(crowi),
+      new XssFilter(crowi),
     ];
     this.postProcessors = [
       new Emoji(crowi),

+ 14 - 0
resource/js/util/PreProcessor/XssFilter.js

@@ -0,0 +1,14 @@
+import Xss from '../../../../lib/util/xss';
+
+export default class XssFilter {
+
+  constructor(crowi) {
+    // TODO read options
+    this.xss = new Xss(true);
+  }
+
+  process(markdown) {
+    return this.xss.process(markdown);
+  }
+
+}