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/orgitlab-com
to start with would make sense, maybe even in a smaller group likegitlab-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.