Pacharapol Withayasakpunt Pacharapol Withayasakpunt
Thu 30 April 2020

Securely embed YouTube and other iframe elements in Markdown

You can use any markdown implementation, including MarkdownIt, but first you have to make it insecure first, by allowing HTML.

const markdownIt = MarkdownIt({
  html: true
})

Then, use DOMPurify, but allow <iframe> tag, including related attributes.

Then, sanitize insecure iframes later.

DOMPurify.addHook('uponSanitizeElement', (node, data) => {
  if (data.tagName === 'iframe') {
    const src = node.getAttribute('src') || ''
    if (!src.startsWith('https://www.youtube.com/embed/')) {
      return node.parentNode?.removeChild(node)
    }
  }
})

Other useful tags

As for <style> tag, I think it can be enabled, but always wrap it in scopeCSS or something similar.

As for <script> tag, I recommend you not to use it at all, but if you must, you need post-processing after attaching to DOM to run it.

el.querySelectorAll('script').forEach((el0) => {
  el0.replaceWith(el0.cloneNode(true))
})