hashicorp / waypoint

A tool to build, deploy, and release any application on any platform.
https://waypointproject.io
Other
4.76k stars 327 forks source link

Render application READMEs #1616

Open jgwhite opened 3 years ago

jgwhite commented 3 years ago

Render application READMEs as pulled in by core in #1502.

jgwhite commented 3 years ago

Prior art for hardening showdown for the purposes of rendering untrusted READMEs:

import showdown from 'showdown';
import { sanitize, addHook } from 'dompurify';

export function initialize() {
  // Sanitize links and image references that are likely non-resolvable from TFC context.
  // See https://github.com/cure53/DOMPurify/blob/main/demos/README.md for examples and such.
  addHook('afterSanitizeAttributes', function (node) {
    //Only allow http and https links
    let regex = RegExp('^(#|http://|https://)');
    //Delink non http(s) anchors
    if (node.hasAttribute('href')) {
      if (!node.getAttribute('href').match(regex)) {
        let span = document.createElement('span');
        let span_text = document.createTextNode(node.textContent);
        span.appendChild(span_text);
        node.replaceWith(span);
      }
    }
    // if image is not referencing http(s) URI, replace with alt text span
    if (node.hasAttribute('src')) {
      if (!node.getAttribute('src').match(regex)) {
        let alt_text_span = document.createElement('span');
        let alt_text = document.createTextNode(node.getAttribute('alt'));
        alt_text_span.appendChild(alt_text);
        node.replaceWith(alt_text_span);
      }
    }
  });

  showdown.extension('purify', function () {
    return [
      {
        type: 'output',
        filter(text) {
          return sanitize(text, {
            ADD_ATTR: ['target'],
            FORBID_TAGS: ['style'],
          });
        },
      },
    ];
  });
}

export default {
  name: 'showdown-extensions',
  initialize,
};