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 createDOMPurify = require('dompurify')
|
||||
const { sanitizer } = require('../../../helpers/sanitizer')
|
||||
|
||||
module.exports = {
|
||||
async init(input, config) {
|
||||
if (config.safeHTML) {
|
||||
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
|
||||
return sanitizer(input, config)
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in new issue