mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-11-16 18:54:12 +01:00
Merge branch 'release/8.13.7'
This commit is contained in:
2
.github/workflows/update-browserlist.yml
vendored
2
.github/workflows/update-browserlist.yml
vendored
@@ -1,5 +1,7 @@
|
|||||||
name: Update Browserslist
|
name: Update Browserslist
|
||||||
on:
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 7 * * 1'
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|||||||
107
cypress/platform/xss15.html
Normal file
107
cypress/platform/xss15.html
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
<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: 'strict',
|
||||||
|
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 John
|
||||||
|
links John: {"XSS": "javas`;
|
||||||
|
diagram += `cript:alert('AudioParam')"}`;
|
||||||
|
|
||||||
|
// var diagram = "stateDiagram-v2\n";
|
||||||
|
// diagram += "<img/src='1'/onerror"
|
||||||
|
// diagram += "=xssAttack()> --> B";
|
||||||
|
console.log(diagram);
|
||||||
|
// document.querySelector('#diagram').innerHTML = diagram;
|
||||||
|
mermaid.render('diagram', diagram, (res) => {
|
||||||
|
console.log(res);
|
||||||
|
document.querySelector('#res').innerHTML = res;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
@@ -13,6 +13,24 @@ export const getRows = (s) => {
|
|||||||
return str.split('#br#');
|
return str.split('#br#');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const removeEscapes = (text) => {
|
||||||
|
let newStr = text.replace(/\\u[\dA-F]{4}/gi, function (match) {
|
||||||
|
return String.fromCharCode(parseInt(match.replace(/\\u/g, ''), 16));
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(newStr);
|
||||||
|
|
||||||
|
newStr = newStr.replace(/\\x([0-9a-f]{2})/gi, (_, c) => String.fromCharCode(parseInt(c, 16)));
|
||||||
|
newStr = newStr.replace(/\\[\d\d\d]{3}/gi, function (match) {
|
||||||
|
return String.fromCharCode(parseInt(match.replace(/\\/g, ''), 8));
|
||||||
|
});
|
||||||
|
newStr = newStr.replace(/\\[\d\d\d]{2}/gi, function (match) {
|
||||||
|
return String.fromCharCode(parseInt(match.replace(/\\/g, ''), 8));
|
||||||
|
});
|
||||||
|
|
||||||
|
return newStr;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes script tags from a text
|
* Removes script tags from a text
|
||||||
*
|
*
|
||||||
@@ -40,13 +58,12 @@ export const removeScript = (txt) => {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let decodedText = removeEscapes(rs);
|
||||||
rs = rs.replace(/script>/gi, '#');
|
decodedText = decodedText.replace(/script>/gi, '#');
|
||||||
rs = rs.replace(/script>/gi, '#');
|
decodedText = decodedText.replace(/javascript:/gi, '#');
|
||||||
rs = rs.replace(/javascript:/gi, '#');
|
decodedText = decodedText.replace(/onerror=/gi, 'onerror:');
|
||||||
rs = rs.replace(/onerror=/gi, 'onerror:');
|
decodedText = decodedText.replace(/<iframe/gi, '');
|
||||||
rs = rs.replace(/<iframe/gi, '');
|
return decodedText;
|
||||||
return rs;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const sanitizeMore = (text, config) => {
|
const sanitizeMore = (text, config) => {
|
||||||
@@ -62,7 +79,7 @@ const sanitizeMore = (text, config) => {
|
|||||||
if (htmlLabels) {
|
if (htmlLabels) {
|
||||||
const level = config.securityLevel;
|
const level = config.securityLevel;
|
||||||
|
|
||||||
if (level === 'antiscript') {
|
if (level === 'antiscript' || level === 'strict') {
|
||||||
txt = removeScript(txt);
|
txt = removeScript(txt);
|
||||||
} else if (level !== 'loose') {
|
} else if (level !== 'loose') {
|
||||||
// eslint-disable-line
|
// eslint-disable-line
|
||||||
@@ -171,4 +188,5 @@ export default {
|
|||||||
removeScript,
|
removeScript,
|
||||||
getUrl,
|
getUrl,
|
||||||
evaluate,
|
evaluate,
|
||||||
|
removeEscapes,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { removeScript } from './common';
|
import { removeScript, removeEscapes } from './common';
|
||||||
|
|
||||||
describe('when securityLevel is antiscript, all script must be removed', function () {
|
describe('when securityLevel is antiscript, all script must be removed', function () {
|
||||||
it('should remove all script block, script inline.', function () {
|
it('should remove all script block, script inline.', function () {
|
||||||
@@ -24,3 +24,48 @@ describe('when securityLevel is antiscript, all script must be removed', functio
|
|||||||
expect(isEqual).toEqual(true);
|
expect(isEqual).toEqual(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('remove escape code in text', function () {
|
||||||
|
it('should remove a unicode colon', function () {
|
||||||
|
const labelString = '\\u003A';
|
||||||
|
|
||||||
|
const result = removeEscapes(labelString);
|
||||||
|
expect(result).toEqual(':');
|
||||||
|
});
|
||||||
|
it('should remove a hex colon', function () {
|
||||||
|
const labelString = '\\x3A';
|
||||||
|
|
||||||
|
const result = removeEscapes(labelString);
|
||||||
|
expect(result).toEqual(':');
|
||||||
|
});
|
||||||
|
it('should remove a oct colon', function () {
|
||||||
|
const labelString = '\\72';
|
||||||
|
|
||||||
|
const result = removeEscapes(labelString);
|
||||||
|
expect(result).toEqual(':');
|
||||||
|
});
|
||||||
|
it('should remove a oct colon 3 numbers', function () {
|
||||||
|
const labelString = '\\072';
|
||||||
|
|
||||||
|
const result = removeEscapes(labelString);
|
||||||
|
expect(result).toEqual(':');
|
||||||
|
});
|
||||||
|
it('should remove multiple colons 3 numbers', function () {
|
||||||
|
const labelString = '\\072\\072\\72';
|
||||||
|
|
||||||
|
const result = removeEscapes(labelString);
|
||||||
|
expect(result).toEqual(':::');
|
||||||
|
});
|
||||||
|
it('should handle greater and smaller then', function () {
|
||||||
|
const labelString = '\\74\\076';
|
||||||
|
|
||||||
|
const result = removeEscapes(labelString);
|
||||||
|
expect(result).toEqual('<>');
|
||||||
|
});
|
||||||
|
it('should handle letters', function () {
|
||||||
|
const labelString = '\\u0073\\143ri\\x70\\u0074\\x3A';
|
||||||
|
|
||||||
|
const result = removeEscapes(labelString);
|
||||||
|
expect(result).toEqual('script:');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user