Add XSS e2e test and fix error handler issue (#700)

This commit is contained in:
Felix Häusler 2019-02-27 15:16:47 +01:00 committed by Ran Luo
parent 5157b6a462
commit 7aa723b9e7
7 changed files with 76 additions and 14 deletions

View File

@ -16,7 +16,7 @@
"build:dev": "node .electron-vue/build.js",
"build:web": "cross-env BUILD_TARGET=web node .electron-vue/build.js",
"dev": "node .electron-vue/dev-runner.js",
"e2e": "npm run pack && mocha --timeout 10000 test/e2e",
"e2e": "npm run pack && cross-env MARKTEXT_EXIT_ON_ERROR=1 mocha --timeout 10000 test/e2e",
"lint": "eslint --ext .js,.vue -f ./node_modules/eslint-friendly-formatter src test",
"lint:fix": "eslint --ext .js,.vue -f ./node_modules/eslint-friendly-formatter --fix src test",
"pack": "npm run pack:main && npm run pack:renderer",

View File

@ -17,12 +17,12 @@ const ERROR_MSG_RENDERER = 'An unexpected error occurred in the renderer process
// main process error handler
process.on('uncaughtException', error => {
handleError(ERROR_MSG_MAIN, error)
handleError(ERROR_MSG_MAIN, error, 'main')
})
// renderer process error handler
ipcMain.on('AGANI::handle-renderer-error', (e, error) => {
handleError(ERROR_MSG_RENDERER, error)
handleError(ERROR_MSG_RENDERER, error, 'renderer')
})
// start crashReporter to save core dumps to temporary folder
@ -44,16 +44,19 @@ const bundleException = (error, type) => {
}
}
const handleError = (title, error) => {
const handleError = (title, error, type) => {
const { message, stack } = error
// log error
const info = bundleException(error, 'renderer')
const info = bundleException(error, type)
console.error(info)
log(JSON.stringify(info, null, 2))
if (EXIT_ON_ERROR) {
console.log('Mark Text was terminated due to an unexpected error (MARKTEXT_EXIT_ON_ERROR variable was set)!')
process.exit(1)
// eslint, don't lie to me, the return statement is important!
return // eslint-disable-line no-unreachable
} else if (!SHOW_ERROR_DIALOG) {
return
}

View File

@ -1,6 +1,6 @@
import Vue from 'vue'
import axios from 'axios'
import { ipcRenderer } from 'electron'
import { crashReporter, ipcRenderer } from 'electron'
import lang from 'element-ui/lib/locale/lang/en'
import locale from 'element-ui/lib/locale'
import App from './app'
@ -20,6 +20,14 @@ sourceMapSupport.install({
hookRequire: false
})
// Start crash reporter to save core dumps for the renderer process
crashReporter.start({
companyName: 'marktext',
productName: 'marktext',
submitURL: 'http://0.0.0.0/',
uploadToServer: false
})
// Register renderer error handler
window.addEventListener('error', event => {
const { message, name, stack } = event.error

24
test/e2e/data/xss.md Normal file
View File

@ -0,0 +1,24 @@
# XSS Tests
<script>throw new Error('XSS 1')</script>
<img src="#" onerror="throw new Error('XSS 2')">
<svg/onload="throw new Error('XSS 3')">
<svg width="100" height="100">
<script>throw new Error('XSS 4')</script>
<rect width="100" height="100" style="fill:rgb(0,0,0)" />
</svg>
<iframe src="javascript:throw new Error('XSS 5');"></iframe>
<iframe src="#" onerror="throw new Error('XSS 6')" onload="throw new Error('XSS 6')"></iframe>
<iframe src="not-a-real-file.extension" onerror="throw new Error('XSS 7')" onload="throw new Error('XSS 7')"></iframe>
<iframe/src="data:text/html,<svg onload=\"throw new Error('XSS 7')\"">
<embed src="data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjAiIHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIj48c2NyaXB0PnRocm93IG5ldyBFcnJvcignWFNTIDgnKTwvc2NyaXB0Pjwvc3ZnPgo=" type="image/svg+xml" AllowScriptAccess="always"></embed>
<script foo>throw new Error('XSS 9')</script>

View File

@ -7,14 +7,10 @@ describe('Launch', function () {
it('shows the proper application title', function () {
return this.app.client.getTitle()
.then(title => {
if (process.platform === 'darwin') {
const result = /^Mark Text|Untitled-1$/.test(title)
if (!result) {
console.error(`AssertionError: expected '${title}' to equal 'Mark Text' or 'Untitled-1'`)
expect(false).to.equal(true)
}
} else {
expect(title).to.equal('Untitled-1')
const result = /^Mark Text|Untitled-1$/.test(title)
if (!result) {
console.error(`AssertionError: expected '${title}' to equal 'Mark Text' or 'Untitled-1'`)
expect(false).to.equal(true)
}
})
})

View File

@ -0,0 +1,21 @@
import utils from '../utils'
describe('Cross-site Scripting Test', function () {
beforeEach(utils.beforeXss)
afterEach(utils.afterEach)
it('Load malicious document', function (done) {
setTimeout(() => {
// If a test fails, an exception is thrown.
// TODO: The process is not terminated if a test fails because the connection to Electron is lost (spectron bug?).
// I think thats not a problem as long as you kill the process.
// Message:
// chrome not reachable
// Error: Request timed out after the element was still found on the page.
// at execute(<Function>, "require") - api.js:63:26
done()
}, 3000)
})
})

View File

@ -18,5 +18,15 @@ export default {
waitTimeout: 20000
})
return this.app.start()
},
beforeXss () {
this.timeout(20000)
this.app = new Application({
path: electron,
args: ['dist/electron/main.js', 'test/e2e/data/xss.md'],
startTimeout: 20000,
waitTimeout: 20000
})
return this.app.start()
}
}