Skip to content
This repository was archived by the owner on Jul 29, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions packages/electron-app/src/main/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import Pino from 'pino';
import path from 'path';
import url from 'url';

import { CSP, IS_PROD, staticPath } from './util';
import { CSP, staticPath } from './util';

const { app, BrowserWindow, session } = electron;
const pino = Pino();
Expand Down Expand Up @@ -59,10 +59,11 @@ function createWindow () {

// Content Security Policy (CSP)
session.defaultSession!.webRequest.onHeadersReceived((details, callback) => {
// Note: `onHeadersReceived` will not be called in prod, because we use the
// file:// protocol: https://electronjs.org/docs/tutorial/security#csp-meta-tag
// Instead, the CSP are the ones in the meta tag inside index.html
pino.debug(
`Configuring Content-Security-Policy for environment ${
IS_PROD ? 'production' : 'development'
}`
'Configuring Content-Security-Policy for environment development'
);

callback({
Expand Down
42 changes: 15 additions & 27 deletions packages/electron-app/src/main/util/csp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,56 +4,44 @@

import { IS_PROD } from './constants';

/* eslint-disable */
// References:
// * https://github.com/parity-js/shell
// * https://github.com/paritytech/fether
const CSP_CONFIG = {
// Disallow mixed content
blockAllMixedContent: 'block-all-mixed-content;',
// Disallow framing and web workers.
// tslint:disable-next-line:quotemark
childSrc: "child-src 'none';",
// FIXME - Only allow connecting to WSS and HTTPS servers.
connectSrc: 'connect-src http: ws:;',
connectSrc: IS_PROD
? 'connect-src ws:;'
// Also allow http in dev mode, for CRA
: 'connect-src http: ws:;',
// Fallback for missing directives.
// Reference: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/default-src
//
// Disallow everything as fallback by default for all CSP fetch directives.
defaultSrc: "default-src 'none';",
// Disallow fonts.
fontSrc: "font-src 'self';", // Additionally used in Parity-JS Shell `'self' data: https:`
// Disallow fonts, we allow https because we are loading from Google Fonts (FIXME don't load from google)
fontSrc: "font-src 'self' data: https:;",
// Disallow submitting any forms
formAction: "form-action 'none';",
// Disallow framing.
frameSrc: "frame-src 'none';",
imgSrc: !IS_PROD
? // Only allow HTTPS for images. Token provider logos must be https://
// Allow `data:` `blob:`.
"img-src 'self' 'unsafe-inline' file: data: blob: https:;"
: // Only allow HTTPS for images. Token provider logos must be https://
// Allow `data:` `blob:`.
"img-src 'unsafe-inline' file: data: blob: https:;", // Additionally used in Parity-JS Shell `'self'`
// Restrict images to only images from known sources
imgSrc: "img-src 'self' data:;",
// Disallow manifests.
manifestSrc: "manifest-src 'none';",
// Disallow media.
mediaSrc: "media-src 'none';",
// Disallow fonts and `<webview>` objects
objectSrc: "object-src 'none';",
// Disallow prefetching.
prefetchSrc: "prefetch-src 'none';",
scriptSrc: !IS_PROD
? // Only allow `http:` and `unsafe-eval` in dev mode (required by create-react-app)
"script-src 'self' file: http: blob: 'unsafe-inline' 'unsafe-eval';"
: "script-src file: 'unsafe-inline';",
styleSrc: !IS_PROD
? "style-src 'self' 'unsafe-inline' file: blob:;" // Additionally used in Parity-JS Shell `data: https:`
: "style-src unsafe-inline' file: blob:;", // Additionally used in Parity-JS Shell `data: https:`
// Allow `blob:` for camera access (worker)
workerSrc: 'worker-src blob:;' // Additionally used in Parity-JS Shell `'self' https:`
// Disallow unknown scripts
scriptSrc: "script-src 'self' 'unsafe-inline';",
// Disallow stylesheets, we allow https because we are loading from Google Fonts (FIXME don't load from google)
styleSrc: "style-src 'self' 'unsafe-inline' https:;",
// Disallow workers, allow `blob:` for camera access if needed
workerSrc: "worker-src 'none';"
};
/* eslint-enable */

const CSP = Object.values(CSP_CONFIG).join(' ');

export { CSP };
export const CSP = Object.values(CSP_CONFIG).join(' ');
52 changes: 36 additions & 16 deletions packages/light-apps/public/index.html
Original file line number Diff line number Diff line change
@@ -1,16 +1,34 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<!--

<head>
<meta charset="utf-8">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<!-- These CSP are for prod. For dev, CSP are set inside @electron-app -->
<meta http-equiv="Content-Security-Policy" content="
block-all-mixed-content;
child-src 'none';
connect-src http: ws:;
Copy link
Copy Markdown
Contributor Author

@amaury1093 amaury1093 Apr 29, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The http here is not needed in prod, and should be overwritten in the onHeadersReceived in dev. However, somehow it doesn't work: https://stackoverflow.com/questions/51969512/define-csp-http-header-in-electron-app#answer-52243138

So we can:

  • either add http in prod, which I believe doesn't introduce a large attack surface, and allow CRA hot reloading
  • or remove http in prod, but then CRA hot reloading breaks.

default-src 'none';
font-src 'self' data: https:;
form-action 'none';
frame-src 'none';
img-src 'self' data:;
manifest-src 'none';
media-src 'none';
object-src 'none';
script-src 'self' 'unsafe-inline';
style-src 'self' 'unsafe-inline' https:;
worker-src 'none';
">
<!--
manifest.json provides metadata used when your web app is added to the
homescreen on Android. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<!--
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Expand All @@ -19,13 +37,15 @@
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>Substrate Light UI</title>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
<title>Substrate Light UI</title>
</head>

<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>

</body>

</body>
</html>