Added markdown-it-mermaid for some charts support in all input fields. Replaced xss with dompurify.

Thanks to xuguotong and xet7 !

Fixes #3794
This commit is contained in:
Lauri Ojansivu 2021-05-07 02:13:20 +03:00
parent 88e4918208
commit 5ab20a9257
6 changed files with 5604 additions and 889 deletions

View file

@ -1,4 +1,4 @@
import sanitizeXss from 'xss'; import DOMPurify from 'dompurify';
const activitiesPerPage = 500; const activitiesPerPage = 500;
@ -162,11 +162,15 @@ BlazeComponent.extendComponent({
{ {
href: source.url, href: source.url,
}, },
sanitizeXss(source.system), DOMPurify.sanitize(source.system, {
ALLOW_UNKNOWN_PROTOCOLS: true,
}),
), ),
); );
} else { } else {
return sanitizeXss(source.system); return DOMPurify.sanitize(source.system, {
ALLOW_UNKNOWN_PROTOCOLS: true,
});
} }
} }
return null; return null;
@ -190,10 +194,10 @@ BlazeComponent.extendComponent({
href: attachment.url({ download: true }), href: attachment.url({ download: true }),
target: '_blank', target: '_blank',
}, },
sanitizeXss(attachment.name()), DOMPurify.sanitize(attachment.name()),
), ),
)) || )) ||
sanitizeXss(this.currentData().activity.attachmentName) DOMPurify.sanitize(this.currentData().activity.attachmentName)
); );
}, },
@ -232,7 +236,7 @@ BlazeComponent.extendComponent({
Template.activity.helpers({ Template.activity.helpers({
sanitize(value) { sanitize(value) {
return sanitizeXss(value); return DOMPurify.sanitize(value, { ALLOW_UNKNOWN_PROTOCOLS: true });
}, },
}); });
@ -246,7 +250,7 @@ function createCardLink(card) {
href: card.originRelativeUrl(), href: card.originRelativeUrl(),
class: 'action-card', class: 'action-card',
}, },
sanitizeXss(card.title), DOMPurify.sanitize(card.title, { ALLOW_UNKNOWN_PROTOCOLS: true }),
), ),
) )
); );
@ -263,7 +267,7 @@ function createBoardLink(board, list) {
href: board.originRelativeUrl(), href: board.originRelativeUrl(),
class: 'action-board', class: 'action-board',
}, },
sanitizeXss(text), DOMPurify.sanitize(text, { ALLOW_UNKNOWN_PROTOCOLS: true }),
), ),
) )
); );

View file

@ -273,10 +273,12 @@ Template.editor.onRendered(() => {
} }
}); });
import sanitizeXss from 'xss'; import DOMPurify from 'dompurify';
// Additional safeAttrValue function to allow for other specific protocols // Additional safeAttrValue function to allow for other specific protocols
// See https://github.com/leizongmin/js-xss/issues/52#issuecomment-241354114 // See https://github.com/leizongmin/js-xss/issues/52#issuecomment-241354114
/*
function mySafeAttrValue(tag, name, value, cssFilter) { function mySafeAttrValue(tag, name, value, cssFilter) {
// only when the tag is 'a' and attribute is 'href' // only when the tag is 'a' and attribute is 'href'
// then use your custom function // then use your custom function
@ -302,6 +304,7 @@ function mySafeAttrValue(tag, name, value, cssFilter) {
return sanitizeXss.safeAttrValue(tag, name, value, cssFilter); return sanitizeXss.safeAttrValue(tag, name, value, cssFilter);
} }
} }
*/
// XXX I believe we should compute a HTML rendered field on the server that // 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 // would handle markdown and user mentions. We can simply have two
@ -317,7 +320,9 @@ Blaze.Template.registerHelper(
let content = Blaze.toHTML(view.templateContentBlock); let content = Blaze.toHTML(view.templateContentBlock);
const currentBoard = Boards.findOne(Session.get('currentBoard')); const currentBoard = Boards.findOne(Session.get('currentBoard'));
if (!currentBoard) if (!currentBoard)
return HTML.Raw(sanitizeXss(content, { safeAttrValue: mySafeAttrValue })); return HTML.Raw(
DOMPurify.sanitize(content, { ALLOW_UNKNOWN_PROTOCOLS: true }),
);
const knowedUsers = currentBoard.members.map(member => { const knowedUsers = currentBoard.members.map(member => {
const u = Users.findOne(member.userId); const u = Users.findOne(member.userId);
if (u) { if (u) {
@ -361,7 +366,9 @@ Blaze.Template.registerHelper(
content = content.replace(fullMention, Blaze.toHTML(link)); content = content.replace(fullMention, Blaze.toHTML(link));
} }
return HTML.Raw(sanitizeXss(content, { safeAttrValue: mySafeAttrValue })); return HTML.Raw(
DOMPurify.sanitize(content, { ALLOW_UNKNOWN_PROTOCOLS: true }),
);
}), }),
); );

6438
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -45,7 +45,7 @@
"eslint-config-meteor": "0.0.9", "eslint-config-meteor": "0.0.9",
"eslint-config-prettier": "^3.6.0", "eslint-config-prettier": "^3.6.0",
"eslint-import-resolver-meteor": "^0.4.0", "eslint-import-resolver-meteor": "^0.4.0",
"eslint-plugin-import": "^2.20.0", "eslint-plugin-import": "^2.2.0",
"eslint-plugin-meteor": "^5.1.0", "eslint-plugin-meteor": "^5.1.0",
"eslint-plugin-prettier": "^3.1.2", "eslint-plugin-prettier": "^3.1.2",
"lint-staged": "^7.3.0", "lint-staged": "^7.3.0",
@ -56,11 +56,13 @@
"dependencies": { "dependencies": {
"@babel/core": "^7.9.6", "@babel/core": "^7.9.6",
"@babel/runtime": "^7.9.6", "@babel/runtime": "^7.9.6",
"@liradb2000/markdown-it-mermaid": "^0.4.2",
"ajv": "^6.12.4", "ajv": "^6.12.4",
"babel-runtime": "^6.26.0", "babel-runtime": "^6.26.0",
"bcrypt": "^5.0.0", "bcrypt": "^5.0.0",
"bson": "^4.0.3", "bson": "^4.0.3",
"bunyan": "^1.8.12", "bunyan": "^1.8.12",
"dompurify": "^2.2.8",
"es6-promise": "^4.2.4", "es6-promise": "^4.2.4",
"exceljs": "^4.2.1", "exceljs": "^4.2.1",
"fibers": "^5.0.0", "fibers": "^5.0.0",
@ -76,7 +78,6 @@
"page": "^1.11.5", "page": "^1.11.5",
"papaparse": "^5.2.0", "papaparse": "^5.2.0",
"qs": "^6.9.4", "qs": "^6.9.4",
"source-map-support": "^0.5.19", "source-map-support": "^0.5.19"
"xss": "^1.0.8"
} }
} }

View file

@ -1,5 +1,5 @@
import { checkNpmVersions } from 'meteor/tmeasday:check-npm-versions'; import { checkNpmVersions } from 'meteor/tmeasday:check-npm-versions';
checkNpmVersions({ checkNpmVersions({
'xss': '1.0.8', 'dompurify': '2.2.8',
}, 'my:xss'); }, 'my:xss');

View file

@ -1,4 +1,5 @@
import sanitizeXss from 'xss'; import DOMPurify from 'dompurify';
var Markdown = require('markdown-it')({ var Markdown = require('markdown-it')({
html: true, html: true,
linkify: true, linkify: true,
@ -6,7 +7,9 @@ var Markdown = require('markdown-it')({
breaks: true, breaks: true,
}); });
import markdownItMermaid from "@liradb2000/markdown-it-mermaid";
/*
// Static URL Scheme Listing // Static URL Scheme Listing
var urlschemes = [ var urlschemes = [
"aodroplink", "aodroplink",
@ -19,7 +22,7 @@ var urlschemes = [
"mailspring" "mailspring"
]; ];
// Better would be a field in the admin backend to set this dynamically // Better would be a field in the admin backend to set this dynamically
// instead of putting all known or wanted url schemes here hard into code // instead of putting all known or wanted url schemes here hard into code
// but i was not able to access those settings // but i was not able to access those settings
// var urlschemes = currentSetting.automaticLinkedUrlSchemes.split('\n'); // var urlschemes = currentSetting.automaticLinkedUrlSchemes.split('\n');
@ -44,14 +47,18 @@ function mySafeAttrValue(tag, name, value, cssFilter) {
// use the default safeAttrValue function to process all non cbthunderlinks // use the default safeAttrValue function to process all non cbthunderlinks
return sanitizeXss.safeAttrValue(tag, name, value, cssFilter); return sanitizeXss.safeAttrValue(tag, name, value, cssFilter);
} }
// } else if (tag === 'svg') {
// return `<img src="data:image/svg+xml;base64,` + atob(value) + `"></img>`;
} else { } else {
// use the default safeAttrValue function to process it // use the default safeAttrValue function to process it
return sanitizeXss.safeAttrValue(tag, name, value, cssFilter); return sanitizeXss.safeAttrValue(tag, name, value, cssFilter);
} }
}; };
*/
var emoji = require('markdown-it-emoji'); var emoji = require('markdown-it-emoji');
Markdown.use(emoji); Markdown.use(emoji);
Markdown.use(markdownItMermaid);
if (Package.ui) { if (Package.ui) {
const Template = Package.templating.Template; const Template = Package.templating.Template;
@ -66,6 +73,6 @@ if (Package.ui) {
text = Blaze._toText(self.templateContentBlock, HTML.TEXTMODE.STRING); text = Blaze._toText(self.templateContentBlock, HTML.TEXTMODE.STRING);
} }
return HTML.Raw(sanitizeXss(Markdown.render(text), { safeAttrValue: mySafeAttrValue })); return HTML.Raw(DOMPurify.sanitize(Markdown.render(text), {ALLOW_UNKNOWN_PROTOCOLS: true}));
})); }));
} }