e2e test for stricter security in mermaid

This commit is contained in:
Knut Sveidqvist
2019-07-14 02:05:59 -07:00
parent 31576f8f55
commit 5abedab095
11 changed files with 220 additions and 6 deletions

View File

@@ -1,19 +1,23 @@
/* eslint-env jest */
import { Base64 } from 'js-base64'
export const mermaidUrl = (graphStr, options) => {
export const mermaidUrl = (graphStr, options, api) => {
const obj = {
code: graphStr,
mermaid: options
}
const objStr = JSON.stringify(obj)
// console.log(Base64)
return 'http://localhost:9000/e2e.html?graph=' + Base64.encodeURI(objStr)
let url = 'http://localhost:9000/e2e.html?graph=' + Base64.encodeURI(objStr)
if (api) {
url = 'http://localhost:9000/xss.html?graph=' + graphStr
}
return url
}
export const imgSnapshotTest = async (page, graphStr, options) => {
export const imgSnapshotTest = async (page, graphStr, options, api) => {
return new Promise(async resolve => {
const url = mermaidUrl(graphStr, options)
const url = mermaidUrl(graphStr, options, api)
await page.goto(url)

View File

@@ -1,4 +1,5 @@
import { Base64 } from 'js-base64'
import mermaid from '../../dist/mermaid.core'
/**
* ##contentLoaded
@@ -22,6 +23,29 @@ const contentLoaded = function () {
global.mermaid.init()
}
}
const contentLoadedApi = function () {
let pos = document.location.href.indexOf('?graph=')
if (pos > 0) {
pos = pos + 7
const graphBase64 = document.location.href.substr(pos)
const graphObj = JSON.parse(Base64.decode(graphBase64))
// const graph = 'hello'
console.log(graphObj)
const div = document.createElement('div')
div.id = 'block'
div.className = 'mermaid'
// div.innerHTML = graphObj.code
document.getElementsByTagName('body')[0].appendChild(div)
global.mermaid.initialize(graphObj.mermaid)
console.log('apa')
mermaid.render('newid', graphObj.code, (svgCode, bindFunctions) => {
div.innerHTML = svgCode
bindFunctions(div)
}, div)
}
}
if (typeof document !== 'undefined') {
/*!
@@ -30,7 +54,12 @@ if (typeof document !== 'undefined') {
window.addEventListener(
'load',
function () {
contentLoaded()
if (this.location.href.match('xss.html')) {
this.console.log('Using api')
contentLoadedApi()
} else {
contentLoaded()
}
},
false
)

44
e2e/platform/xss.html Normal file
View File

@@ -0,0 +1,44 @@
<html>
<head>
<script src="/e2e.js"></script>
<link
href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
rel="stylesheet"
/>
<style>
.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>
<script>
function xssAttack(){
const div = document.createElement('div')
div.id = 'the-malware'
div.className = 'malware'
div.innerHTML = 'XSS Succeeded'
document.getElementsByTagName('body')[0].appendChild(div)
}
</script>
</head>
<body>
<script src="./mermaid.js"></script>
<script>
mermaid.initialize({
startOnLoad: false,
useMaxWidth: true,
});
</script>
</body>
</html>

BIN
e2e/platform/xss.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

15
e2e/spec/xss.spec.js Normal file
View File

@@ -0,0 +1,15 @@
/* eslint-env jest */
import { imgSnapshotTest } from '../helpers/util.js'
const { toMatchImageSnapshot } = require('jest-image-snapshot')
expect.extend({ toMatchImageSnapshot })
/* eslint-disable */
describe('XSS', () => {
it('should handle xss in tags', async () => {
// const str = 'graph LR;\nB-->D(<img onerror=location=`javascript\u003aalert\u0028document.domain\u0029` src=x>);'
const str = 'eyJjb2RlIjoiXG5ncmFwaCBMUlxuICAgICAgQi0tPkQoPGltZyBvbmVycm9yPWxvY2F0aW9uPWBqYXZhc2NyaXB0XFx1MDAzYXhzc0F0dGFja1xcdTAwMjhkb2N1bWVudC5kb21haW5cXHUwMDI5YCBzcmM9eD4pOyIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0In19';
await imgSnapshotTest(page, str,
{}, true)
})
})