Skip to content
Permalink
Browse files Browse the repository at this point in the history
Merge pull request from GHSA-p3rp-vmj9-gv6v
Advisory fix 1
  • Loading branch information
knsv committed Dec 29, 2021
2 parents be46ace + 65592e0 commit 066b7a0
Show file tree
Hide file tree
Showing 8 changed files with 272 additions and 14 deletions.
106 changes: 106 additions & 0 deletions cypress/platform/xss16.html
@@ -0,0 +1,106 @@
<html>
<head>
<link
href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
rel="stylesheet"
/>
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet">
<style>
body {
/* background: rgb(221, 208, 208); */
/* background:#333; */
font-family: 'Arial';
/* font-size: 18px !important; */
}
h1 { color: grey;}
.mermaid2 {
display: none;
}
.mermaid svg {
/* font-size: 18px !important; */
}
.malware {
position: fixed;
bottom:0;
left:0;
right:0;
height: 150px;
background: red;
color: black;
display: flex;
display: flex;
justify-content: center;
align-items: center;
font-family: monospace;
font-size: 72px;
}
</style>
</head>
<body>
<div>Security check</div>
<div class="flex">
<div id="diagram" class="mermaid"></div>
<div id="res" class=""></div>
<script src="./mermaid.js"></script>
<script>
mermaid.parseError = function (err, hash) {
// console.error('Mermaid error: ', err);
};
mermaid.initialize({
theme: 'forest',
arrowMarkerAbsolute: true,
// themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
logLevel: 0,
state: {
defaultRenderer: 'dagre-d3',
},
flowchart: {
// defaultRenderer: 'dagre-wrapper',
nodeSpacing: 10,
curve: 'cardinal',
htmlLabels: true,
},
htmlLabels: true,
// gantt: { axisFormat: '%m/%d/%Y' },
sequence: { actorFontFamily: 'courier', actorMargin: 50, showSequenceNumbers: false },
// sequenceDiagram: { actorMargin: 300 } // deprecated
// fontFamily: '"times", sans-serif',
// fontFamily: 'courier',
fontSize: 18,
curve: 'basis',
securityLevel: 'loose',
startOnLoad: false,
secure: ['secure', 'securityLevel', 'startOnLoad', 'maxTextSize'],
// themeVariables: {relationLabelColor: 'red'}
});
function callback() {
alert('It worked');
}
function xssAttack() {
const div = document.createElement('div');
div.id = 'the-malware';
div.className = 'malware';
div.innerHTML = 'XSS Succeeded';
document.getElementsByTagName('body')[0].appendChild(div);
throw new Error('XSS Succeded');
}

var diagram = `sequenceDiagram
participant Alice
links Alice: { "Click me!" : "javasjavascript:cript:alert('goose')" }`;

// // var diagram = "stateDiagram-v2\n";
// // diagram += "<img/src='1'/onerror"
// diagram += '//via.placeholder.com/64\' width=64 />"]';
// console.log(diagram);
// document.querySelector('#diagram').innerHTML = diagram;
mermaid.render('diagram', diagram, (res) => {
console.log(res);
document.querySelector('#res').innerHTML = res;
});
</script>
</body>
</html>

106 changes: 106 additions & 0 deletions cypress/platform/xss17.html
@@ -0,0 +1,106 @@
<html>
<head>
<link
href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
rel="stylesheet"
/>
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet">
<style>
body {
/* background: rgb(221, 208, 208); */
/* background:#333; */
font-family: 'Arial';
/* font-size: 18px !important; */
}
h1 { color: grey;}
.mermaid2 {
display: none;
}
.mermaid svg {
/* font-size: 18px !important; */
}
.malware {
position: fixed;
bottom:0;
left:0;
right:0;
height: 150px;
background: red;
color: black;
display: flex;
display: flex;
justify-content: center;
align-items: center;
font-family: monospace;
font-size: 72px;
}
</style>
</head>
<body>
<div>Security check</div>
<div class="flex">
<div id="diagram" class="mermaid"></div>
<div id="res" class=""></div>
<script src="./mermaid.js"></script>
<script>
mermaid.parseError = function (err, hash) {
// console.error('Mermaid error: ', err);
};
mermaid.initialize({
theme: 'forest',
arrowMarkerAbsolute: true,
// themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
logLevel: 0,
state: {
defaultRenderer: 'dagre-d3',
},
flowchart: {
// defaultRenderer: 'dagre-wrapper',
nodeSpacing: 10,
curve: 'cardinal',
htmlLabels: true,
},
htmlLabels: true,
// gantt: { axisFormat: '%m/%d/%Y' },
sequence: { actorFontFamily: 'courier', actorMargin: 50, showSequenceNumbers: false },
// sequenceDiagram: { actorMargin: 300 } // deprecated
// fontFamily: '"times", sans-serif',
// fontFamily: 'courier',
fontSize: 18,
curve: 'basis',
securityLevel: 'loose',
startOnLoad: false,
secure: ['secure', 'securityLevel', 'startOnLoad', 'maxTextSize'],
// themeVariables: {relationLabelColor: 'red'}
});
function callback() {
alert('It worked');
}
function xssAttack() {
const div = document.createElement('div');
div.id = 'the-malware';
div.className = 'malware';
div.innerHTML = 'XSS Succeeded';
document.getElementsByTagName('body')[0].appendChild(div);
throw new Error('XSS Succeded');
}

var diagram = `sequenceDiagram
participant Alice
link Alice: Click Me!@javasjavascript:cript:alert("goose")`;

// // var diagram = "stateDiagram-v2\n";
// // diagram += "<img/src='1'/onerror"
// diagram += '//via.placeholder.com/64\' width=64 />"]';
// console.log(diagram);
// document.querySelector('#diagram').innerHTML = diagram;
mermaid.render('diagram', diagram, (res) => {
console.log(res);
document.querySelector('#res').innerHTML = res;
});
</script>
</body>
</html>

11 changes: 6 additions & 5 deletions docs/_sidebar.md
@@ -1,10 +1,10 @@
- 📔 Introduction
- 📔 Introduction

- [About Mermaid](README.md)
- [Deployment](n00b-gettingStarted.md)
- [Syntax and Configuration](n00b-syntaxReference.md)

- 📊 Diagram Syntax
- 📊 Diagram Syntax
- [Flowchart](flowchart.md)
- [Sequence diagram](sequenceDiagram.md)
- [Class Diagram](classDiagram.md)
Expand All @@ -16,7 +16,7 @@
- [Requirement Diagram](requirementDiagram.md)
- [Other Examples](examples.md)

- ⚙️ Deployment and Configuration
- ⚙️ Deployment and Configuration

- [Tutorials](Tutorials.md)
- [API-Usage](usage.md)
Expand All @@ -26,12 +26,13 @@
- [Mermaid CLI](mermaidCLI.md)
- [Advanced usage](n00b-advanced.md)

- 📚 Misc
- 📚 Misc
- [Use-Cases and Integrations](integrations.md)
- [FAQ](faq.md)

- 🙌 Contributions and Community
- 🙌 Contributions and Community
- [Overview for Beginners](n00b-overview.md)
- [Development and Contribution ](development.md)
- [Changelog](CHANGELOG.md)
- [Adding Diagrams ](newDiagram.md)
- [Security ](security.md)
17 changes: 17 additions & 0 deletions docs/security.md
@@ -0,0 +1,17 @@
# Security
The Mermaid team takes the security of Mermaid and the applications that use Mermaid seriously. This page describes how to report any vulnerabilities you may find, and lists best practices to minimize the risk of introducing a vulnerability.

## Reporting vulnerabilities
To report a vulnerability, please e-mail security@mermaid.live with a description of the issue, the steps you took to create the issue, affected versions, and if known, mitigations for the issue.

We aim to reply within three working days, probably much sooner.

You should expect a close collaboration as we work to resolve the issue you have reported. Please reach out to security@mermaid.live again if you do not receive prompt attention and regular updates.

You may also reach out to the team via our public Slack chat channels; however, please make sure to e-mail security@mernaid.live when reporting an issue, and avoid revealing information about vulnerabilities in public as that could that could put users at risk.

## Best practices

Keep current with the latest Mermaid releases. We regularly update Mermaid, and these updates may fix security defects discovered in previous versions. Check the Mermaid release notes for security-related updates.

Keep your application’s dependencies up to date. Make sure you upgrade your package dependencies to keep the dependencies up to date. Avoid pinning to specific versions for your dependencies and, if you do, make sure you check periodically to see if your dependencies have had security updates, and update the pin accordingly.
2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "mermaid",
"version": "8.13.6",
"version": "8.13.8",
"description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
"main": "dist/mermaid.core.js",
"module": "dist/mermaid.esm.min.mjs",
Expand Down
14 changes: 13 additions & 1 deletion src/diagrams/common/common.spec.js
@@ -1,4 +1,4 @@
import { removeScript, removeEscapes } from './common';
import { sanitizeText, removeScript, removeEscapes } from './common';

describe('when securityLevel is antiscript, all script must be removed', function () {
it('should remove all script block, script inline.', function () {
Expand Down Expand Up @@ -69,3 +69,15 @@ describe('remove escape code in text', function () {
expect(result).toEqual('script:');
});
});

describe('Sanitize text', function () {
it('should remove script tag', function () {
const maliciousStr = 'javajavascript:script:alert(1)';
const result = sanitizeText(maliciousStr, {
securityLevel: 'strict',
flowchart: { htmlLabels: true },
});
console.log('result', result);
expect(result).not.toContain('javascript:alert(1)');
});
});
14 changes: 8 additions & 6 deletions src/diagrams/sequence/svgDraw.js
@@ -1,5 +1,6 @@
import common from '../common/common';
import { addFunction } from '../../interactionDb';
import { sanitizeUrl } from '@braintree/sanitize-url';

export const drawRect = function (elem, rectData) {
const rectElem = elem.append('rect');
Expand All @@ -19,12 +20,12 @@ export const drawRect = function (elem, rectData) {
return rectElem;
};

const sanitizeUrl = function (s) {
return s
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/javascript:/g, '');
};
// const sanitizeUrl = function (s) {
// return s
// .replace(/&/g, '&amp;')
// .replace(/</g, '&lt;')
// .replace(/javascript:/g, '');
// };

const addPopupInteraction = (id, actorCnt) => {
addFunction(() => {
Expand Down Expand Up @@ -1055,4 +1056,5 @@ export default {
popupMenu,
popdownMenu,
fixLifeLineHeights,
sanitizeUrl,
};
16 changes: 15 additions & 1 deletion src/diagrams/sequence/svgDraw.spec.js
@@ -1,4 +1,4 @@
const svgDraw = require('./svgDraw');
const svgDraw = require('./svgDraw').default;
const { MockD3 } = require('d3');

describe('svgDraw', function () {
Expand Down Expand Up @@ -124,4 +124,18 @@ describe('svgDraw', function () {
expect(rect.lower).toHaveBeenCalled();
});
});
describe('sanitizeUrl', function () {
it('it should sanitize malicious urls', function () {
const maliciousStr = 'javascript:script:alert(1)';
const result = svgDraw.sanitizeUrl(maliciousStr);
console.log('result', result);
expect(result).not.toContain('javascript:alert(1)');
});
it('it should not sanitize non dangerous urls', function () {
const maliciousStr = 'javajavascript:script:alert(1)';
const result = svgDraw.sanitizeUrl(maliciousStr);
console.log('result', result);
expect(result).not.toContain('javascript:alert(1)');
});
});
});

0 comments on commit 066b7a0

Please sign in to comment.