|
@@ -44,7 +44,7 @@ effort are always very welcome.
|
|
|
|
|
|
A security issue exists whenever you receive code from a remote destination and
|
|
|
execute it locally. As an example, consider a remote website being displayed
|
|
|
-inside a [`BrowserWindow`](browser-window). If an attacker somehow manages to
|
|
|
+inside a [`BrowserWindow`][browser-window]. If an attacker somehow manages to
|
|
|
change said content (either by attacking the source directly, or by sitting
|
|
|
between your app and the actual destination), they will be able to execute
|
|
|
native code on the user's machine.
|
|
@@ -52,29 +52,29 @@ native code on the user's machine.
|
|
|
> :warning: Under no circumstances should you load and execute remote code with
|
|
|
Node.js integration enabled. Instead, use only local files (packaged together
|
|
|
with your application) to execute Node.js code. To display remote content, use
|
|
|
-the [`webview`](web-view) tag and make sure to disable the `nodeIntegration`.
|
|
|
+the [`webview`][web-view] tag and make sure to disable the `nodeIntegration`.
|
|
|
|
|
|
#### Checklist: Security Recommendations
|
|
|
|
|
|
This is not bulletproof, but at the least, you should attempt the following:
|
|
|
|
|
|
-* [Only load secure content](#only-load-secure-content)
|
|
|
-* [Disable the Node.js integration in all renderers that display remote content](#disable-node.js-integration-for-remote-content)
|
|
|
-* [Enable context isolation in all renderers that display remote content](#enable-context-isolation-for-remote-content)
|
|
|
-* [Use `ses.setPermissionRequestHandler()` in all sessions that load remote content](#handle-session-permission-requests-from-remote-content)
|
|
|
-* [Do not disable `webSecurity`](#do-not-disable-websecurity)
|
|
|
-* [Define a `Content-Security-Policy`](#define-a-content-security-policy)
|
|
|
+1) [Only load secure content](#only-load-secure-content)
|
|
|
+2) [Disable the Node.js integration in all renderers that display remote content](#disable-node.js-integration-for-remote-content)
|
|
|
+3) [Enable context isolation in all renderers that display remote content](#enable-context-isolation-for-remote-content)
|
|
|
+4) [Use `ses.setPermissionRequestHandler()` in all sessions that load remote content](#handle-session-permission-requests-from-remote-content)
|
|
|
+5) [Do not disable `webSecurity`](#do-not-disable-websecurity)
|
|
|
+6) [Define a `Content-Security-Policy`](#define-a-content-security-policy)
|
|
|
and use restrictive rules (i.e. `script-src 'self'`)
|
|
|
-* [Override and disable `eval`](#override-and-disable-eval)
|
|
|
+7) [Override and disable `eval`](#override-and-disable-eval)
|
|
|
, which allows strings to be executed as code.
|
|
|
-* [Do not set `allowRunningInsecureContent` to `true`](#do-not-set-allowRunningInsecureContent-to-true)
|
|
|
-* [Do not enable experimental features](#do-not-enable-experimental-features)
|
|
|
-* [Do not use `blinkFeatures`](#do-not-use-blinkfeatures)
|
|
|
-* [WebViews: Do not use `allowpopups`](#do-not-use-allowpopups)
|
|
|
-* [WebViews: Verify the options and params of all `<webview>` tags](#verify-webview-options-before-creation)
|
|
|
+8) [Do not set `allowRunningInsecureContent` to `true`](#do-not-set-allowRunningInsecureContent-to-true)
|
|
|
+9) [Do not enable experimental features](#do-not-enable-experimental-features)
|
|
|
+10) [Do not use `blinkFeatures`](#do-not-use-blinkfeatures)
|
|
|
+11) [WebViews: Do not use `allowpopups`](#do-not-use-allowpopups)
|
|
|
+12) [WebViews: Verify the options and params of all `<webview>` tags](#verify-webview-options-before-creation)
|
|
|
|
|
|
|
|
|
-## Only Load Secure Content
|
|
|
+## 1) Only Load Secure Content
|
|
|
|
|
|
Any resources not included with your application should be loaded using a
|
|
|
secure protocol like `HTTPS`. In other words, do not use insecure protocols
|
|
@@ -114,11 +114,11 @@ browserWindow.loadURL('https://my-website.com')
|
|
|
```
|
|
|
|
|
|
|
|
|
-## Disable Node.js Integration for Remote Content
|
|
|
+## 2) Disable Node.js Integration for Remote Content
|
|
|
|
|
|
It is paramount that you disable Node.js integration in any renderer
|
|
|
-([`BrowserWindow`](browser-window), [`BrowserView`](browser-view), or
|
|
|
-[`WebView`](web-view)) that loads remote content. The goal is to limit the
|
|
|
+([`BrowserWindow`][browser-window], [`BrowserView`][browser-view], or
|
|
|
+[`WebView`][web-view]) that loads remote content. The goal is to limit the
|
|
|
powers you grant to remote content, thus making it dramatically more difficult
|
|
|
for an attacker to harm your users should they gain the ability to execute
|
|
|
JavaScript on your website.
|
|
@@ -182,7 +182,7 @@ window.readConfig = function () {
|
|
|
```
|
|
|
|
|
|
|
|
|
-## Enable Context Isolation for Remote Content
|
|
|
+## 3) Enable Context Isolation for Remote Content
|
|
|
|
|
|
Context isolation is an Electron feature that allows developers to run code
|
|
|
in preload scripts and in Electron APIs in a dedicated JavaScript context. In
|
|
@@ -239,7 +239,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
```
|
|
|
|
|
|
|
|
|
-## Handle Session Permission Requests From Remote Content
|
|
|
+## 4) Handle Session Permission Requests From Remote Content
|
|
|
|
|
|
You may have seen permission requests while using Chrome: They pop up whenever
|
|
|
the website attempts to use a feature that the user has to manually approve (
|
|
@@ -277,7 +277,48 @@ session
|
|
|
```
|
|
|
|
|
|
|
|
|
-## Define a Content Security Policy
|
|
|
+## 5) Do Not Disable WebSecurity
|
|
|
+
|
|
|
+_Recommendation is Electron's default_
|
|
|
+
|
|
|
+You may have already guessed that disabling the `webSecurity` property on a
|
|
|
+renderer process ([`BrowserWindow`][browser-window],
|
|
|
+[`BrowserView`][browser-view], or [`WebView`][web-view]) disables crucial
|
|
|
+security features.
|
|
|
+
|
|
|
+Do not disable `webSecurity` in production applications.
|
|
|
+
|
|
|
+### Why?
|
|
|
+
|
|
|
+Disabling `webSecurity` will disable the same-origin policy and set
|
|
|
+`allowRunningInsecureContent` property to `true`. In other words, it allows
|
|
|
+the execution of insecure code from different domains.
|
|
|
+
|
|
|
+### How?
|
|
|
+```js
|
|
|
+// Bad
|
|
|
+const mainWindow = new BrowserWindow({
|
|
|
+ webPreferences: {
|
|
|
+ webSecurity: false
|
|
|
+ }
|
|
|
+})
|
|
|
+```
|
|
|
+
|
|
|
+```js
|
|
|
+// Good
|
|
|
+const mainWindow = new BrowserWindow()
|
|
|
+```
|
|
|
+
|
|
|
+```html
|
|
|
+<!-- Bad -->
|
|
|
+<webview disablewebsecurity src="page.html"></webview>
|
|
|
+
|
|
|
+<!-- Good -->
|
|
|
+<webview src="page.html"></webview>
|
|
|
+```
|
|
|
+
|
|
|
+
|
|
|
+## 6) Define a Content Security Policy
|
|
|
|
|
|
A Content Security Policy (CSP) is an additional layer of protection against
|
|
|
cross-site-scripting attacks and data injection attacks. We recommend that they
|
|
@@ -308,7 +349,7 @@ Content-Security-Policy: script-src 'self' https://apis.mydomain.com
|
|
|
```
|
|
|
|
|
|
|
|
|
-## Override and Disable `eval`
|
|
|
+## 7) Override and Disable `eval`
|
|
|
|
|
|
`eval()` is a core JavaScript method that allows the execution of JavaScript
|
|
|
from a string. Disabling it disables your app's ability to evaluate JavaScript
|
|
@@ -336,7 +377,7 @@ window.eval = global.eval = function () {
|
|
|
```
|
|
|
|
|
|
|
|
|
-## Do Not Set `allowRunningInsecureContent` to `true`
|
|
|
+## 8) Do Not Set `allowRunningInsecureContent` to `true`
|
|
|
|
|
|
_Recommendation is Electron's default_
|
|
|
|
|
@@ -370,7 +411,7 @@ const mainWindow = new BrowserWindow({})
|
|
|
```
|
|
|
|
|
|
|
|
|
-## Do Not Enable Experimental Features
|
|
|
+## 9) Do Not Enable Experimental Features
|
|
|
|
|
|
_Recommendation is Electron's default_
|
|
|
|
|
@@ -403,7 +444,7 @@ const mainWindow = new BrowserWindow({})
|
|
|
```
|
|
|
|
|
|
|
|
|
-## Do Not Use `blinkFeatures`
|
|
|
+## 10) Do Not Use `blinkFeatures`
|
|
|
|
|
|
_Recommendation is Electron's default_
|
|
|
|
|
@@ -435,48 +476,7 @@ const mainWindow = new BrowserWindow()
|
|
|
```
|
|
|
|
|
|
|
|
|
-## Do Not Disable WebSecurity
|
|
|
-
|
|
|
-_Recommendation is Electron's default_
|
|
|
-
|
|
|
-You may have already guessed that disabling the `webSecurity` property on a
|
|
|
-renderer process ([`BrowserWindow`](browser-window),
|
|
|
-[`BrowserView`](browser-view), or [`WebView`](web-view)) disables crucial
|
|
|
-security features.
|
|
|
-
|
|
|
-Do not disable `webSecurity` in production applications.
|
|
|
-
|
|
|
-### Why?
|
|
|
-
|
|
|
-Disabling `webSecurity` will disable the same-origin policy and set
|
|
|
-`allowRunningInsecureContent` property to `true`. In other words, it allows
|
|
|
-the execution of insecure code from different domains.
|
|
|
-
|
|
|
-### How?
|
|
|
-```js
|
|
|
-// Bad
|
|
|
-const mainWindow = new BrowserWindow({
|
|
|
- webPreferences: {
|
|
|
- webSecurity: false
|
|
|
- }
|
|
|
-})
|
|
|
-```
|
|
|
-
|
|
|
-```js
|
|
|
-// Good
|
|
|
-const mainWindow = new BrowserWindow()
|
|
|
-```
|
|
|
-
|
|
|
-```html
|
|
|
-<!-- Bad -->
|
|
|
-<webview disablewebsecurity src="page.html"></webview>
|
|
|
-
|
|
|
-<!-- Good -->
|
|
|
-<webview src="page.html"></webview>
|
|
|
-```
|
|
|
-
|
|
|
-
|
|
|
-## Do Not Use `allowpopups`
|
|
|
+## 11) Do Not Use `allowpopups`
|
|
|
|
|
|
_Recommendation is Electron's default_
|
|
|
|
|
@@ -504,7 +504,7 @@ you know it needs that feature.
|
|
|
```
|
|
|
|
|
|
|
|
|
-## Verify WebView Options Before Creation
|
|
|
+## 12) Verify WebView Options Before Creation
|
|
|
|
|
|
A WebView created in a renderer process that does not have Node.js integration
|
|
|
enabled will not be able to enable integration itself. However, a WebView will
|