mirror of https://github.com/requarks/wiki
The sanitising functionality for both html and SVG has been unified into a single file on both the client and server side. Second, a problem with the SVG output from the drawio has also been fixed. Last, it is possible to add a customised path for the drawio web application, which can be used for local hosting the application.
parent
54d21ae538
commit
abab623240
@ -0,0 +1,48 @@
|
|||||||
|
|
||||||
|
import DOMPurify from 'dompurify'
|
||||||
|
|
||||||
|
/* global siteConfig */
|
||||||
|
export default function drawioSanitize(
|
||||||
|
content) {
|
||||||
|
if (siteConfig.drawio.sanitizing === false) {
|
||||||
|
return content
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('DEBUG: Performing sanitizing ...')
|
||||||
|
|
||||||
|
content =
|
||||||
|
DOMPurify.sanitize(
|
||||||
|
content,
|
||||||
|
{
|
||||||
|
USE_PROFILES:
|
||||||
|
{
|
||||||
|
svg: true,
|
||||||
|
html: true
|
||||||
|
},
|
||||||
|
HTML_INTEGRATION_POINTS:
|
||||||
|
{
|
||||||
|
foreignobject: true
|
||||||
|
},
|
||||||
|
ADD_TAGS: [
|
||||||
|
'div',
|
||||||
|
'foreignObject',
|
||||||
|
'switch',
|
||||||
|
'style',
|
||||||
|
'title',
|
||||||
|
'desc',
|
||||||
|
'metadata'],
|
||||||
|
ADD_ATTR: [
|
||||||
|
'xmlns', 'xmlns:xlink', 'xlink:href', 'xml:space', 'xml:base',
|
||||||
|
'font-family', 'font-size', 'font-style', 'font-weight',
|
||||||
|
'alignment-baseline', 'dominant-baseline', 'baseline-shift',
|
||||||
|
'vector-effect', 'text-anchor', 'clip-path', 'mask',
|
||||||
|
'fill-rule', 'stroke-linejoin', 'stroke-linecap',
|
||||||
|
'transform', 'viewBox', 'preserveAspectRatio',
|
||||||
|
'overflow', 'filter', 'style', 'data-name', 'aria-label', 'requiredFeatures', 'pointer-events'],
|
||||||
|
FORBID_TAGS: ['script'], // keep scripting disabled
|
||||||
|
FORBID_ATTR: ['onload', 'onclick', 'onmouseover'], // prevent XSS
|
||||||
|
ALLOW_UNKNOWN_PROTOCOLS: true // for xlink:href
|
||||||
|
})
|
||||||
|
|
||||||
|
return content
|
||||||
|
}
|
||||||
@ -0,0 +1,80 @@
|
|||||||
|
import DOMPurify from 'dompurify'
|
||||||
|
import { JSDOM } from 'jsdom'
|
||||||
|
|
||||||
|
const window = new JSDOM('').window
|
||||||
|
const purify = DOMPurify(window)
|
||||||
|
|
||||||
|
/* global WIKI */
|
||||||
|
export function sanitizer(
|
||||||
|
content,
|
||||||
|
config) {
|
||||||
|
let purifyConfig = {}
|
||||||
|
|
||||||
|
if (('htmlOnly' in config) &&
|
||||||
|
(config.htmlOnly === true)) {
|
||||||
|
WIKI.logger.info('Using htmlOnly sanitizer configuration ...')
|
||||||
|
|
||||||
|
purifyConfig =
|
||||||
|
{
|
||||||
|
USE_PROFILES: {
|
||||||
|
html: true
|
||||||
|
},
|
||||||
|
FORBID_TAGS: ['script'], // keep scripting disabled
|
||||||
|
FORBID_ATTR: ['onload', 'onclick', 'onmouseover'] // prevent XSS
|
||||||
|
}
|
||||||
|
} else if (('svgOnly' in config) &&
|
||||||
|
(config.svgOnly === true)) {
|
||||||
|
WIKI.logger.info('Using svgOnly sanitizer configuration')
|
||||||
|
|
||||||
|
purifyConfig =
|
||||||
|
{
|
||||||
|
USE_PROFILES: {
|
||||||
|
svg: true,
|
||||||
|
svgFilters: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
WIKI.logger.info('Using renderer sanitizer configuration')
|
||||||
|
|
||||||
|
purifyConfig =
|
||||||
|
{
|
||||||
|
USE_PROFILES: {
|
||||||
|
svg: true,
|
||||||
|
svgFilters: true,
|
||||||
|
html: true
|
||||||
|
},
|
||||||
|
HTML_INTEGRATION_POINTS:
|
||||||
|
{
|
||||||
|
foreignobject: true
|
||||||
|
},
|
||||||
|
ADD_TAGS: [
|
||||||
|
'div',
|
||||||
|
'foreignObject',
|
||||||
|
'switch',
|
||||||
|
'style',
|
||||||
|
'title',
|
||||||
|
'desc',
|
||||||
|
'metadata'],
|
||||||
|
ADD_ATTR: [
|
||||||
|
'xmlns', 'xmlns:xlink', 'xlink:href', 'xml:space', 'xml:base',
|
||||||
|
'font-family', 'font-size', 'font-style', 'font-weight',
|
||||||
|
'alignment-baseline', 'dominant-baseline', 'baseline-shift',
|
||||||
|
'vector-effect', 'text-anchor', 'clip-path', 'mask',
|
||||||
|
'fill-rule', 'stroke-linejoin', 'stroke-linecap',
|
||||||
|
'transform', 'viewBox', 'preserveAspectRatio',
|
||||||
|
'overflow', 'filter', 'style', 'data-name', 'aria-label', 'requiredFeatures', 'pointer-events'],
|
||||||
|
FORBID_TAGS: ['script'], // keep scripting disabled
|
||||||
|
FORBID_ATTR: ['onload', 'onclick', 'onmouseover'], // prevent XSS
|
||||||
|
ALLOW_UNKNOWN_PROTOCOLS: true // for xlink:href
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!config.allowIFrames) {
|
||||||
|
purifyConfig.FORBID_TAGS.push('iframe')
|
||||||
|
purifyConfig.FORBID_ATTR.push('allow')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return purify.sanitize(
|
||||||
|
content,
|
||||||
|
purifyConfig)
|
||||||
|
}
|
||||||
@ -1,42 +1,7 @@
|
|||||||
const { JSDOM } = require('jsdom')
|
const { sanitizer } = require('../../../helpers/sanitizer')
|
||||||
const createDOMPurify = require('dompurify')
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
async init(input, config) {
|
async init(input, config) {
|
||||||
if (config.safeHTML) {
|
return sanitizer(input, config)
|
||||||
const window = new JSDOM('').window
|
|
||||||
const DOMPurify = createDOMPurify(window)
|
|
||||||
|
|
||||||
const allowedAttrs = ['v-pre', 'v-slot:tabs', 'v-slot:content', 'target']
|
|
||||||
const allowedTags = ['tabset', 'template']
|
|
||||||
|
|
||||||
if (config.allowDrawIoUnsafe) {
|
|
||||||
allowedTags.push('foreignObject')
|
|
||||||
DOMPurify.addHook('uponSanitizeElement', (elm) => {
|
|
||||||
if (elm.querySelectorAll) {
|
|
||||||
const breaks = elm.querySelectorAll('foreignObject br, foreignObject p')
|
|
||||||
if (breaks && breaks.length) {
|
|
||||||
for (let i = 0; i < breaks.length; i++) {
|
|
||||||
breaks[i].parentNode.replaceChild(
|
|
||||||
window.document.createElement('div'),
|
|
||||||
breaks[i]
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.allowIFrames) {
|
|
||||||
allowedTags.push('iframe')
|
|
||||||
allowedAttrs.push('allow')
|
|
||||||
}
|
|
||||||
|
|
||||||
input = DOMPurify.sanitize(input, {
|
|
||||||
ADD_ATTR: allowedAttrs,
|
|
||||||
ADD_TAGS: allowedTags
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return input
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in new issue