-
-
Notifications
You must be signed in to change notification settings - Fork 6.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cross-Site Scripting:DOM - Issue #847
Comments
Thx, we should look at this |
Hi again. In what context are you getting this error. Mermaid itself takes elements on the wepage compiles them to svg element and inserts the svg in the DOM. Generally when talking about cross site scripting there is a input field or similar in which an external user could add javascript code that the unprepared web site then puts in its DOM where it starts to execute. I am certain mermaid would not allow javascript in the diagram code (even if would be a cool but unsafe feature). |
Even I'm not sure how that'll happen, I even cross checked the security scan report. Even I'm little skeptical about the code where it's happening |
You can confirm this by going to the editor and entering the code given on the NPM advisory https://www.npmjs.com/advisories/751 |
Hey, I was checking the code and I believe that a possible solution to this problem would be: /**
* MermaidAPI.js line 239
*/
function parse (text) {
//SANITIZE INPUT!
const graphType = utils.detectType(text)
let parser
... The testing for this would be interesting though. If you guys believe this would be an elegant solution I can put sometime to try to fix it in the next 48 hours and open a PR |
I spoke to a senior security specialist yesterday about this, thanks @mario-areias. After understanding better the situation, I don't think my above suggestion is valid anymore. It is unfair to tag mermaid as unsafe for Cross Site Scripting. The attack would happen if the attacker gain access to the input method. AFAIK mermaid has two input methods: content in a html page and via API. Content in an HTML pageIf the attacker gain privileged access to the HTML page, than the attack is already executing the XSS. The attacker doesn't need to use mermaid to gain access as he/she would already have the access. Via APIBecause mermaid offers an API, that can be used to receive the input from anywhere, then yes, this can be a compromise of the security. In this case have to implement a counter measure. I tried to simulate the attack via API and the for the simple case that I implemented the API accepted the input as valid. See below: it('should prevent XSS injection', function () {
expect(() => mermaidAPI.parse('graph TD;A["<img src=invalid onerror=alert(\'XSS\')></img>"]')).toThrow()
}) The result is: FAIL src/mermaidAPI.spec.js
● when using mermaidAPI and › checking validity of input › should prevent XSS injection
expect(function).toThrow(undefined)
Expected the function to throw an error.
But it didn't throw anything.
43 | })
44 | it('should prevent XSS injection', function () {
> 45 | expect(() => mermaidAPI.parse('graph TD;A["<img src=invalid onerror=alert(\'XSS\')></img>"]')).toThrow()
| ^
46 | })
47 | })
48 | })
at Object.toThrow (src/mermaidAPI.spec.js:45:102)
Test Suites: 1 failed, 9 passed, 10 total
Tests: 1 failed, 267 passed, 268 total
Snapshots: 0 total
Time: 4.278s In this case, one suggestion from @mario-areias is to scape the output, e. g., replace all ConclusionIf you came here because you want to remove that annoying critical vulnerability from you
|
Hi! Thanks for the anlysis, @rogeralmeida a PR for this would be great. One thing to consider is that in som cases tags are valid. The other way to do this is to sanitize after the parsing. The parsing results in a an object containing the data of the graph later used for rendering like an array of vertices etc. To sanitizing after the parsing would perhaps be easier in some sense but not as elegant. You wound not need to bother with the grammars but the sanitizing would be needed for each diagram type. I think I would go for your suggested route. |
@rogeralmeida I added this to the 8.2.0 project. Let me know if you want me to assign it to you. |
OK, I will give it a go and get back to you soon. |
Relevant examples fro duplicate issue in #869. Hi, I found XSS issues in mermaid. This affects all the projects that use mermaid. There are three different ways to trigger. The first one:
The second one:
The third one(needs click, both nodes will work): graph LR;
alert`md5_salt`-->B;
click alert`md5_salt` eval "Tooltip for a callback"
click B "javascript:alert`salt`" "This is a tooltip for a link"
Here is an example that affects other projects which using mermaid. And all above three payload would work on hackmd.io |
@rogeralmeida How is this progressing? Do you have time for it or do you want me to pitch in. Dont want to have this one dormant. |
One approach that we could use is to disable by default the html tags, leave it available from the configuration part, and add a new configuration to let you decide a closed list of tag that are enabled |
It is important to keep in mind that if I add the following graph to a html page. Then the google analytics script will run as a part of the regular page load, before mermaid starts.
To properly test mermaids handling of the xss issue one need to use the mermaid API so that mermaid does not pick up the text from the page but some other source like an input field. If I take example above and paste in mermaids online editor it wont run as there would be a syntax error. If I fix that and put quotes around the script tag, then it renders as a script tag but it wont run, (second link). So I would need help to get way to reproduce this in order to verify my security fix where I disable tags in node text. |
Hi @knsv I manage to get working by doing a bit different. Try this:
|
Thank you @mario-areias! There is a fix for this in the master branch but not released yet. I could reproduce the issue thanks to your example and was able to verify that alert does not come up after the update. In short there a now a security setting. When set to strict which is default, click handling is disabled and tags inside node text is encoded. |
Glad to hear that @knsv. Let me know when it is released and I can test a bit more to make sure the XSS is gone for good :) |
I was just reviewing your fix on master branch (hope you don't mind!). I don't think the I think we can protect against that by making sure the |
…oc on how to avoid labels out of bounds.
Hi @knsv However, I tried the latest 8.2.1 in the live editor as below: the clicking still works, did I miss any config or it's been inited in another config already? |
Looking at at it. Guessing it will come a 8.2.2 shortly. |
8.2.2 is deployed and configures in the link below: Thanks for pointing this out and let me know if you find more things. |
Thanks for catching up so soon. I found out that if there is an rendering error, it will also evaluate the tags thus causing the XSS as well. |
Good catch! In this case the error was generated in the editor before mermaid was triggered. It was when the code from the editor was put into the DOM for mermaid to pick up. Will fix the editor. |
HI @knsv Thanks for fixing this. However, I found two bypasses: XSS fixes by replacing are quite troublesome to get right (the HTML was a lot easier to fix given we could encode the tags, a much easier fix). I suggested in a previous comment that making sure |
Fixed with mermaid version 8.2.3. Reopen if you find more bypasses. |
Thank you again for fixing this. From looking at the code, it seems a solid fix. I tried to bypass it to no avail. @knsv you probably want contact npm to update their advisory https://www.npmjs.com/advisories/751 with the fixed version. Great job! |
Any word on getting the latest version listed as fixed on the above advisory? Would make our sysadmins feeling better not seeing the "1 high severity" on npm install. |
As this issue is closed, should another issue be opened to get the npm advisory fixed? |
I've contacted npm security team and they have updated the advisory. Hope you don't mind @knsv |
Have we considered creating our own sanitizer using the browser DOMParser api (or jsdom module for node)? The DOMParser api will create a document fragment that behaves just like a normal document except it won't execute any scripts or attempt to render anything.
I made quick POC showing off what's possible: |
… Also sanitized the tooltips so that no tags are allowed in them for (#847).
Sending unvalidated data to a web browser can result in the browser executing malicious code. This was reported by Fortify scanner since I'm using minified version I'm not able to get the exact line.
The text was updated successfully, but these errors were encountered: