Merge branch 'release/8.13.1' into develop
This commit is contained in:
commit
5d5808880f
|
@ -68,5 +68,15 @@ describe('XSS', () => {
|
|||
cy.wait(1000);
|
||||
cy.get('#the-malware').should('not.exist');
|
||||
})
|
||||
it('should not allow maniplulating antiscript to run javascript using onerror in state diagrams with dagre wrapper', () => {
|
||||
cy.visit('http://localhost:9000/xss8.html');
|
||||
cy.wait(1000);
|
||||
cy.get('#the-malware').should('not.exist');
|
||||
})
|
||||
it('should not allow maniplulating antiscript to run javascript using onerror in state diagrams with dagre d3', () => {
|
||||
cy.visit('http://localhost:9000/xss9.html');
|
||||
cy.wait(1000);
|
||||
cy.get('#the-malware').should('not.exist');
|
||||
})
|
||||
|
||||
})
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
<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: 'antiscript',
|
||||
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 = "graph LR\n";
|
||||
diagram += " B(<a href='<";
|
||||
diagram += "script></";
|
||||
diagram += "script>Javascript:xssAttack`1`'>Click)";
|
||||
// diagram += "script\u003aalert\u0028document.domain\u0029\` src=x>\"\);\n";
|
||||
console.log(diagram);
|
||||
// document.querySelector('#diagram').innerHTML = diagram;
|
||||
mermaid.render('diagram', diagram, (res) => {
|
||||
console.log(res);
|
||||
document.querySelector('#res').innerHTML = res;
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
<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-wrapper',
|
||||
},
|
||||
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: 'antiscript',
|
||||
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 = "stateDiagram-v2\n";
|
||||
diagram += "<img/src='1'/onerror=xssAttack()> --> B";
|
||||
// diagram += "script\u003aalert\u0028document.domain\u0029\` src=x>\"\);\n";
|
||||
console.log(diagram);
|
||||
// document.querySelector('#diagram').innerHTML = diagram;
|
||||
mermaid.render('diagram', diagram, (res) => {
|
||||
console.log(res);
|
||||
document.querySelector('#res').innerHTML = res;
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
<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: 'antiscript',
|
||||
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 = "stateDiagram-v2\n";
|
||||
diagram += "<img/src='1'/onerror=xssAttack()> --> B";
|
||||
// diagram += "script\u003aalert\u0028document.domain\u0029\` src=x>\"\);\n";
|
||||
console.log(diagram);
|
||||
// document.querySelector('#diagram').innerHTML = diagram;
|
||||
mermaid.render('diagram', diagram, (res) => {
|
||||
console.log(res);
|
||||
document.querySelector('#res').innerHTML = res;
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -8,8 +8,8 @@
|
|||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||
<!-- <link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/vue.css"> -->
|
||||
<link rel="stylesheet" href="theme.css">
|
||||
<!-- <script src="//cdn.jsdelivr.net/npm/mermaid@8.12.0/dist/mermaid.min.js"></script> -->
|
||||
<script src="http://localhost:9000/mermaid.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/mermaid@8.13.0/dist/mermaid.min.js"></script>
|
||||
<!-- <script src="http://localhost:9000/mermaid.js"></script> -->
|
||||
<script>
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "mermaid",
|
||||
"version": "8.13.0",
|
||||
"version": "8.13.1",
|
||||
"description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
|
||||
"main": "dist/mermaid.core.js",
|
||||
"keywords": [
|
||||
|
|
|
@ -366,7 +366,7 @@ const rectWithTitle = (parent, node) => {
|
|||
log.info('Label text abc79', title, text2, typeof text2 === 'object');
|
||||
|
||||
const text = label.node().appendChild(createLabel(title, node.labelStyle, true, true));
|
||||
let bbox;
|
||||
let bbox = { width: 0, height: 0 };
|
||||
if (evaluate(getConfig().flowchart.htmlLabels)) {
|
||||
const div = text.children[0];
|
||||
const dv = select(text);
|
||||
|
|
|
@ -29,10 +29,11 @@ export const removeScript = (txt) => {
|
|||
}
|
||||
}
|
||||
|
||||
rs = rs.replace(/javascript:/g, '#');
|
||||
rs = rs.replace(/onerror=/g, 'onerror:');
|
||||
rs = rs.replace(/<iframe/g, '');
|
||||
|
||||
rs = rs.replace(/script>/gi, '#');
|
||||
rs = rs.replace(/script>/gi, '#');
|
||||
rs = rs.replace(/javascript:/gi, '#');
|
||||
rs = rs.replace(/onerror=/gi, 'onerror:');
|
||||
rs = rs.replace(/<iframe/gi, '');
|
||||
return rs;
|
||||
};
|
||||
|
||||
|
@ -64,7 +65,10 @@ const sanitizeMore = (text, config) => {
|
|||
};
|
||||
|
||||
export const sanitizeText = (text, config) => {
|
||||
const txt = sanitizeMore(DOMPurify.sanitize(text), config);
|
||||
const level = config.securityLevel;
|
||||
console.log('security level', level);
|
||||
if (!text) return text;
|
||||
const txt = DOMPurify.sanitize(sanitizeMore(text, config));
|
||||
return txt;
|
||||
};
|
||||
|
||||
|
|
|
@ -112,7 +112,7 @@ describe('[Singlenodes] when parsing', () => {
|
|||
expect(vert['a'].type).toBe('diamond');
|
||||
});
|
||||
|
||||
it('should handle a single diamond node with html in it', function() {
|
||||
it('should handle a single diamond node with html in it (SN3)', function() {
|
||||
// Silly but syntactically correct
|
||||
const res = flow.parser.parse('graph TD;a{A <br> end};');
|
||||
|
||||
|
@ -121,7 +121,7 @@ describe('[Singlenodes] when parsing', () => {
|
|||
|
||||
expect(edges.length).toBe(0);
|
||||
expect(vert['a'].type).toBe('diamond');
|
||||
expect(vert['a'].text).toBe('A <br/> end');
|
||||
expect(vert['a'].text).toBe('A <br> end');
|
||||
});
|
||||
|
||||
it('should handle a single hexagon node', function() {
|
||||
|
@ -144,7 +144,7 @@ describe('[Singlenodes] when parsing', () => {
|
|||
|
||||
expect(edges.length).toBe(0);
|
||||
expect(vert['a'].type).toBe('hexagon');
|
||||
expect(vert['a'].text).toBe('A <br/> end');
|
||||
expect(vert['a'].text).toBe('A <br> end');
|
||||
});
|
||||
|
||||
it('should handle a single round node with html in it', function() {
|
||||
|
@ -156,7 +156,7 @@ describe('[Singlenodes] when parsing', () => {
|
|||
|
||||
expect(edges.length).toBe(0);
|
||||
expect(vert['a'].type).toBe('round');
|
||||
expect(vert['a'].text).toBe('A <br/> end');
|
||||
expect(vert['a'].text).toBe('A <br> end');
|
||||
});
|
||||
|
||||
it('should handle a single node with alphanumerics starting on a char', function() {
|
||||
|
|
|
@ -328,7 +328,7 @@ describe('[Text] when parsing', () => {
|
|||
const edges = flow.parser.yy.getEdges();
|
||||
|
||||
expect(vert['C'].type).toBe('round');
|
||||
expect(vert['C'].text).toBe('Chimpansen hoppar åäö <br/> - ÅÄÖ');
|
||||
expect(vert['C'].text).toBe('Chimpansen hoppar åäö <br> - ÅÄÖ');
|
||||
});
|
||||
// xit('it should handle åäö, minus and space and br',function(){
|
||||
// const res = flow.parser.parse('graph TD; A[Object(foo,bar)]-->B(Thing);');
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { log } from '../../logger';
|
||||
import { generateId } from '../../utils';
|
||||
import mermaidAPI from '../../mermaidAPI';
|
||||
import common from '../common/common';
|
||||
import * as configApi from '../../config';
|
||||
|
||||
const clone = (o) => JSON.parse(JSON.stringify(o));
|
||||
|
||||
let rootDoc = [];
|
||||
|
||||
export const parseDirective = function (statement, context, type) {
|
||||
|
@ -148,7 +148,13 @@ export const addState = function (id, type, doc, descr, note) {
|
|||
}
|
||||
}
|
||||
|
||||
if (note) currentDocument.states[id].note = note;
|
||||
if (note) {
|
||||
currentDocument.states[id].note = note;
|
||||
currentDocument.states[id].note.text = common.sanitizeText(
|
||||
currentDocument.states[id].note.text,
|
||||
configApi.getConfig()
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export const clear = function () {
|
||||
|
@ -195,7 +201,11 @@ export const addRelation = function (_id1, _id2, title) {
|
|||
}
|
||||
addState(id1, type1);
|
||||
addState(id2, type2);
|
||||
currentDocument.relations.push({ id1, id2, title: title });
|
||||
currentDocument.relations.push({
|
||||
id1,
|
||||
id2,
|
||||
title: common.sanitizeText(title, configApi.getConfig()),
|
||||
});
|
||||
};
|
||||
|
||||
const addDescription = function (id, _descr) {
|
||||
|
@ -204,8 +214,7 @@ const addDescription = function (id, _descr) {
|
|||
if (descr[0] === ':') {
|
||||
descr = descr.substr(1).trim();
|
||||
}
|
||||
|
||||
theState.descriptions.push(descr);
|
||||
theState.descriptions.push(common.sanitizeText(descr, configApi.getConfig()));
|
||||
};
|
||||
|
||||
export const cleanupLabel = function (label) {
|
||||
|
|
|
@ -3,10 +3,10 @@ import { select } from 'd3';
|
|||
import stateDb from './stateDb';
|
||||
import state from './parser/stateDiagram';
|
||||
import { getConfig } from '../../config';
|
||||
// import { evaluate } from '../common/common';
|
||||
import { render } from '../../dagre-wrapper/index.js';
|
||||
import { log } from '../../logger';
|
||||
import { configureSvgSize } from '../../utils';
|
||||
import common from '../common/common';
|
||||
|
||||
const conf = {};
|
||||
export const setConf = function (cnf) {
|
||||
|
@ -51,7 +51,7 @@ const setupNode = (g, parent, node, altFlag) => {
|
|||
nodeDb[node.id] = {
|
||||
id: node.id,
|
||||
shape,
|
||||
description: node.id,
|
||||
description: common.sanitizeText(node.id, getConfig()),
|
||||
classes: 'statediagram-state',
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue