Security - Add Content Security Policy (#2288)

* Add CSP

* Add content security policy

* Revert commented block

* Experiment with loading the configuration in a vm context

* Fix lint issues

* Fix build issue
This commit is contained in:
Bryan Phelps 2018-06-23 15:05:26 -07:00 committed by GitHub
parent f8d4528174
commit 7b15dce05c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 80 additions and 20 deletions

View File

@ -8,6 +8,7 @@ import * as fs from "fs"
import * as isError from "lodash/isError"
import * as mkdirp from "mkdirp"
import * as path from "path"
import * as vm from "vm"
import "rxjs/add/operator/debounceTime"
import { Subject } from "rxjs/Subject"
@ -18,6 +19,7 @@ import { Event, IEvent } from "oni-types"
import { IConfigurationProvider } from "./Configuration"
import { IConfigurationValues } from "./IConfigurationValues"
// import * as Utility from "./../../Utility"
const CONFIG_UPDATE_DEBOUNCE_TIME = 100 /*ms */
@ -126,15 +128,30 @@ export class FileConfigurationProvider implements IConfigurationProvider {
if (fs.existsSync(this._configurationFilePath)) {
try {
const configurationContent = fs.readFileSync(this._configurationFilePath, "utf-8")
const script = new vm.Script(configurationContent, {
filename: __filename,
})
// Wrap as commonjs module and execute it to use current file path, and so resolve module relativly to current process
const module = { exports: {} }
Function("require", "exports", "module", configurationContent)(
(global as any).require,
module.exports,
module,
)
userRuntimeConfig = promoteConfigurationToRootLevel(module.exports)
const windowAsAny = window as any
const sandbox = {
console,
__filename,
__dirname,
module: {} as any,
require: (str: string) => {
const val = windowAsAny.require(str)
return val
},
exports: {},
}
const context = vm.createContext(sandbox)
script.runInContext(context)
const exports = sandbox.module
? sandbox.module.exports || sandbox.exports
: sandbox.exports
userRuntimeConfig = promoteConfigurationToRootLevel(exports)
} catch (e) {
e.message =
"[Config Error] Failed to parse " +

38
index.dev.html Normal file
View File

@ -0,0 +1,38 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ONI</title>
<link rel="stylesheet" href="font-awesome/css/font-awesome.min.css">
<style>
html, body {
width: 100%;
height: 100%;
padding: 0px;
margin: 0px;
overflow: hidden;
}
body {
font-family: Consolas, Monaco, 'Courier New', monospace;
font-size: 14px;
}
script {
display: none;
}
@keyframes spinner-rotate {
0% { transform: rotateY(0deg); }
100% { transform: rotateY(360deg); }
}
.webpack-loading-image {
animation: spinner-rotate 2s linear infinite;
}
</style>
</head>
<body>
<div id="host"></div>
<script src="preload.js"></script>
</body>
</html>

View File

@ -2,7 +2,7 @@
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy" content="default-src *; img-src blob: data: *; script-src 'self' http://localhost:8191; style-src 'self' 'unsafe-inline'; media-src blob: data: mediastream: *;">
<title>ONI</title>
<link rel="stylesheet" href="font-awesome/css/font-awesome.min.css">
<style>
@ -34,15 +34,6 @@
</head>
<body>
<div id="host"></div>
<script>
console.timeStamp("browser.domloaded")
var path = "lib/browser/bundle.js"
if(process.env.ONI_WEBPACK_LOAD) {
path = "scripts/dev_webpack_loader.js"
}
var scriptTag = document.createElement("script");
scriptTag.src = path
document.body.appendChild(scriptTag);
</script>
<script src="preload.js"></script>
</body>
</html>

View File

@ -168,7 +168,9 @@ export function createWindow(
const rootPath = path.join(__dirname, "..", "..", "..")
const iconPath = path.join(rootPath, "images", "oni.ico")
const indexPath = path.join(rootPath, "index.html?react_perf")
const indexFileName = process.env.ONI_WEBPACK_LOAD ? "index.dev.html" : "index.html"
const indexPath = path.join(rootPath, indexFileName + "?react_perf")
// Create the browser window.
// TODO: Do we need to use non-ico for other platforms?
let currentWindow = new BrowserWindow({

12
preload.js Normal file
View File

@ -0,0 +1,12 @@
if (!process.env.ONI_WEBPACK_LOAD) {
window.eval = global.eval = () => console.warn("eval is not available")
}
console.timeStamp("browser.domloaded")
var path = "lib/browser/bundle.js"
if (process.env.ONI_WEBPACK_LOAD) {
path = "scripts/dev_webpack_loader.js"
}
var scriptTag = document.createElement("script")
scriptTag.src = path
document.body.appendChild(scriptTag)