Browse Source

Alter call to sanitizeXss

Addressing feature: Custom URL Schemes autolinked #3218

Create a custom SafeAttrValue function which can allow non-standard protocols such as thunderlink: cbthunderlink: and aodroplink: to operate correctly without getting the value stripped away. Any other protocols and code remain to be processed by the default safeAttrValue routine.
brian-j 4 years ago
parent
commit
0180196d7e
2 changed files with 43 additions and 3 deletions
  1. 22 2
      client/components/main/editor.js
  2. 21 1
      packages/markdown/src/template-integration.js

+ 22 - 2
client/components/main/editor.js

@@ -265,6 +265,26 @@ Template.editor.onRendered(() => {
 
 import sanitizeXss from 'xss';
 
+// Additional  safeAttrValue function to allow for other specific protocols
+// See https://github.com/leizongmin/js-xss/issues/52#issuecomment-241354114
+function mySafeAttrValue(tag, name, value, cssFilter) {
+  // only when the tag is 'a' and attribute is 'href'
+  // then use your custom function
+  if (tag === 'a' && name === 'href') {
+    // only filter the value if starts with 'cbthunderlink:' or 'aodroplink'
+    if (/^thunderlink:/ig.test(value) || /^cbthunderlink:/ig.test(value) || /^aodroplink:/ig.test(value)) {
+      return value;
+    }
+		else {
+    	// use the default safeAttrValue function to process all non cbthunderlinks
+    	return sanitizeXss.safeAttrValue(tag, name, value, cssFilter);
+  	}
+  } else {
+    // use the default safeAttrValue function to process it
+    return sanitizeXss.safeAttrValue(tag, name, value, cssFilter);
+  }
+};
+
 // XXX I believe we should compute a HTML rendered field on the server that
 // would handle markdown and user mentions. We can simply have two
 // fields, one source, and one compiled version (in HTML) and send only the
@@ -278,7 +298,7 @@ Blaze.Template.registerHelper(
     const view = this;
     let content = Blaze.toHTML(view.templateContentBlock);
     const currentBoard = Boards.findOne(Session.get('currentBoard'));
-    if (!currentBoard) return HTML.Raw(sanitizeXss(content));
+    if (!currentBoard) return HTML.Raw(sanitizeXss(content, { safeAttrValue: mySafeAttrValue }));
     const knowedUsers = currentBoard.members.map(member => {
       const u = Users.findOne(member.userId);
       if (u) {
@@ -322,7 +342,7 @@ Blaze.Template.registerHelper(
       content = content.replace(fullMention, Blaze.toHTML(link));
     }
 
-    return HTML.Raw(sanitizeXss(content));
+    return HTML.Raw(sanitizeXss(content, { safeAttrValue: mySafeAttrValue }));
   }),
 );
 

+ 21 - 1
packages/markdown/src/template-integration.js

@@ -6,6 +6,26 @@ var Markdown = require('markdown-it')({
 	breaks: true,
 });
 
+// Additional  safeAttrValue function to allow for other specific protocols
+// See https://github.com/leizongmin/js-xss/issues/52#issuecomment-241354114
+function mySafeAttrValue(tag, name, value, cssFilter) {
+  // only when the tag is 'a' and attribute is 'href'
+  // then use your custom function
+  if (tag === 'a' && name === 'href') {
+    // only filter the value if starts with 'cbthunderlink:' or 'aodroplink'
+    if (/^thunderlink:/ig.test(value) || /^cbthunderlink:/ig.test(value) || /^aodroplink:/ig.test(value)) {
+      return value;
+    }
+		else {
+    	// use the default safeAttrValue function to process all non cbthunderlinks
+    	return sanitizeXss.safeAttrValue(tag, name, value, cssFilter);
+  	}
+  } else {
+    // use the default safeAttrValue function to process it
+    return sanitizeXss.safeAttrValue(tag, name, value, cssFilter);
+  }
+};
+
 var emoji = require('markdown-it-emoji');
 Markdown.use(emoji);
 
@@ -22,6 +42,6 @@ if (Package.ui) {
 			text = Blaze._toText(self.templateContentBlock, HTML.TEXTMODE.STRING);
 		}
 
-			return HTML.Raw(sanitizeXss(Markdown.render(text)));
+			return HTML.Raw(sanitizeXss(Markdown.render(text), { safeAttrValue: mySafeAttrValue }));
 	}));
 }