FY22Q4 OKR - Sandbox client-side rendering of user data (mermaid, jupyter notebooks, etc)

Proposal

A lot of XSS vulnerabilities have been caused by rendered Mermaid graphs (https://gitlab.com/gitlab-com/gl-security/appsec/appsec-team/-/issues/172) and recently we had another issue when rendering Jupyter notebooks (#341566 (closed)). To put an end to this, it would be worth sandboxing the rendered outputs in an iframe as shown in https://gitlab.com/gitlab-com/gl-security/appsec/appsec-team/-/issues/172#note_628037887.

The iframe's source doesn't need to be hosted on another domain, we can used srcdoc and embed the HTML directly. This should help make the implementation simpler.

Progress:

  • Define plan of action
  • MVC
    • Figure out where to "intercept" the rendering of mermaid and where we're going to insert the iframe
    • Host the mermaid rendering on another page and send the diagram to be rendered securely with postMessage.
    • Add a feature flag disabled by default that uses this sandbox for rendering
    • Open an MR and get this merged
  • Exhaustive testing of the feature to make sure it's production-ready
  • Enable the feature flag on GitLab.com (only in gitlab-org and/or gitlab-com to start with would make sense, maybe even in a smaller group like gitlab-com/gl-security/appsec)
  • Move the iframe isolation outside of the mermaid integration so it can be reused in other components
    • Stretch goal: Use the generalized code from previous step in Jupyter Notebooks rendering
    • Stretch goal: Use the generalized code for MathJax rendering
  • Identify places where using the sandbox would be beneficial
  • Enable feature flag by default
  • Remove feature flag from code base so it can't be disabled and the sandbox is the only way to render mermaid

It would be interesting in the future to make a gem from this so the sandboxing mechanism can be used by any Rails project. Though if it's easier to implement with tight coupling to GitLab-specific code then so be it and we're going to forget about this plan for now.

Retrospective

What went well

  • We have a sandbox for Mermaid in production and shipped to self-managed users!!
  • The most important objectives were completed
  • @djadmin jumped on this unprompted and delivered excellent work, the original idea was that I was going to start the implementation and there's absolutely no way I would have done better work so 👍 👍 🚀

What did not go well

  • I wouldn't say anything didn't go well, but a more elaborate proof of concept than "let's put it in an iframe" might have helped.

What changes will be made

  • We'll find more folks like @djadmin and we'll hire them all
  • More elaborate PoCs as mentioned above, while this tiny PoC was enough to demonstrate the idea it would be good to have something slightly more complex and it would help solve some of the initial challenges ahead of time
Edited by James Ritchey