Skip to content
Permalink
Browse files

feat: html sanitization on all filter:parse.* hooks, closes #7872

  • Loading branch information...
julianlam committed Aug 30, 2019
1 parent e291a60 commit 2580306db954f79e568d28b2948aea8a918267b1
Showing with 70 additions and 0 deletions.
  1. +28 −0 src/plugins/index.js
  2. +42 −0 src/posts/parse.js
@@ -9,6 +9,7 @@ const nconf = require('nconf');
const util = require('util');

const user = require('../user');
const posts = require('../posts');

const readdirAsync = util.promisify(fs.readdir);

@@ -124,6 +125,33 @@ Plugins.reload = async function () {
console.log('');
}

Plugins.registerHook('core', {
hook: 'filter:parse.post',
method: async (data) => {
data.postData.content = posts.sanitize(data.postData.content);
return data;
},
});

Plugins.registerHook('core', {
hook: 'filter:parse.raw',
method: async content => posts.sanitize(content),
});

Plugins.registerHook('core', {
hook: 'filter:parse.aboutme',
method: async content => posts.sanitize(content),
});

Plugins.registerHook('core', {
hook: 'filter:parse.signature',
method: async (data) => {
data.userData.signature = posts.sanitize(data.userData.signature);
return data;
},
});

// Lower priority runs earlier
Object.keys(Plugins.loadedHooks).forEach(function (hook) {
Plugins.loadedHooks[hook].sort((a, b) => a.priority - b.priority);
});
@@ -3,12 +3,48 @@
var nconf = require('nconf');
var url = require('url');
var winston = require('winston');
const sanitize = require('sanitize-html');
const _ = require('lodash');

var meta = require('../meta');
var plugins = require('../plugins');
var translator = require('../translator');
var utils = require('../utils');

let sanitizeConfig = {
allowedTags: sanitize.defaults.allowedTags.concat([
// Some safe-to-use tags to add
'span', 'a', 'pre', 'small',
'sup', 'sub', 'u', 'del',
'video', 'audio', 'iframe', 'embed',
'img', 'tfoot', 'h1', 'h2',
's', 'button', 'i',
]),
allowedAttributes: {
...sanitize.defaults.allowedAttributes,
a: ['href', 'hreflang', 'media', 'rel', 'target', 'type'],
img: ['alt', 'height', 'ismap', 'src', 'usemap', 'width', 'srcset'],
iframe: ['height', 'name', 'src', 'width'],
video: ['autoplay', 'controls', 'height', 'loop', 'muted', 'poster', 'preload', 'src', 'width'],
audio: ['autoplay', 'controls', 'loop', 'muted', 'preload', 'src'],
embed: ['height', 'src', 'type', 'width'],
},
globalAttributes: ['accesskey', 'class', 'contenteditable', 'dir',
'draggable', 'dropzone', 'hidden', 'id', 'lang', 'spellcheck', 'style',
'tabindex', 'title', 'translate', 'aria-expanded', 'data-*',
],
};

process.nextTick(async () => {
// Each allowed tags should have some common global attributes...
sanitizeConfig.allowedTags.forEach((tag) => {
sanitizeConfig.allowedAttributes[tag] = _.union(sanitizeConfig.allowedAttributes[tag], sanitizeConfig.globalAttributes);
});

// Some plugins might need to adjust or whitelist their own tags...
sanitizeConfig = await plugins.fireHook('filter:sanitize.config', sanitizeConfig);
});

module.exports = function (Posts) {
Posts.urlRegex = {
regex: /href="([^"]+)"/g,
@@ -77,6 +113,12 @@ module.exports = function (Posts) {
return content;
};

Posts.sanitize = function (content) {
return sanitize(content, {
allowedTags: sanitizeConfig.allowedTags, allowedAttributes: sanitizeConfig.allowedAttributes,
});
};

function sanitizeSignature(signature) {
signature = translator.escape(signature);
var tagsToStrip = [];

0 comments on commit 2580306

Please sign in to comment.
You can’t perform that action at this time.