Skip to content
Permalink
Browse files Browse the repository at this point in the history
Merge pull request from GHSA-h857-2g56-468g
Mount under a template tag instead of div
  • Loading branch information
mattkrick committed Dec 15, 2022
2 parents 51ca0db + 8d70440 commit b107e45
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 12 deletions.
36 changes: 31 additions & 5 deletions dist/lib/sanitizeSVG.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/lib/sanitizeSVG.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/types/sanitizeSVG.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

39 changes: 34 additions & 5 deletions src/sanitizeSVG.ts
@@ -1,3 +1,32 @@
// List of disallowed SVG elements
// Adjusted from https://github.com/cure53/DOMPurify/blob/f6fcdb9f1c13b3559697db0038744a0a327d46ab/src/tags.js#L201
const svgDisallowed = [
'a',
'animate',
'color-profile',
'cursor',
'discard',
'fedropshadow',
'font-face',
'font-face-format',
'font-face-name',
'font-face-src',
'font-face-uri',
'foreignobject',
'hatch',
'hatchpath',
'mesh',
'meshgradient',
'meshpatch',
'meshrow',
'missing-glyph',
'script',
'set',
'solidcolor',
'unknown',
'use'
]

const getWindow = () => (typeof window === 'undefined' ? null : window)
const readAsText = (svg: File | Buffer) =>
new Promise<string | null>((resolve) => {
Expand All @@ -21,13 +50,13 @@ const sanitizeSVG = async (svg: File | Buffer, window = getWindow()) => {
if (isFile(svg) && svg.type !== 'image/svg+xml') return svg
const svgText = await readAsText(svg)
if (!svgText) throw new Error('Image corrupt')
const div = window.document.createElement('div')
div.innerHTML = svgText
const svgEl = div.firstElementChild!
const playground = window.document.createElement('template')
playground.innerHTML = svgText
const svgEl = playground.content.firstElementChild!
const attributes = Array.from(svgEl.attributes).map(({ name }) => name)
const hasScriptAttr = !!attributes.find((attr) => attr.startsWith('on'))
const scripts = svgEl.getElementsByTagName('script')
return scripts.length === 0 && !hasScriptAttr ? svg : null
const disallowedSvgElements = svgEl.querySelectorAll(svgDisallowed.join(','))
return disallowedSvgElements.length === 0 && !hasScriptAttr ? svg : null
}

export default sanitizeSVG

0 comments on commit b107e45

Please sign in to comment.