📝 Disable Node Integration
This commit is contained in:
parent
2db125890c
commit
d67c64b6fa
1 changed files with 74 additions and 16 deletions
|
@ -50,8 +50,8 @@ the actual destination), they will be able to execute native code on the user's
|
||||||
machine.
|
machine.
|
||||||
|
|
||||||
> :warning: Under no circumstances should you load and execute remote code with
|
> :warning: Under no circumstances should you load and execute remote code with
|
||||||
Node integration enabled. Instead, use only local files (packaged together with
|
Node.js integration enabled. Instead, use only local files (packaged together with
|
||||||
your application) to execute Node code. To display remote content, use the
|
your application) to execute Node.js code. To display remote content, use the
|
||||||
`webview` tag and make sure to disable the `nodeIntegration`.
|
`webview` tag and make sure to disable the `nodeIntegration`.
|
||||||
|
|
||||||
#### Checklist: Security Recommendations
|
#### Checklist: Security Recommendations
|
||||||
|
@ -59,7 +59,7 @@ your application) to execute Node code. To display remote content, use the
|
||||||
This is not bulletproof, but at the least, you should attempt the following:
|
This is not bulletproof, but at the least, you should attempt the following:
|
||||||
|
|
||||||
* [Only display secure (https) content](#only-display-secure-content)
|
* [Only display secure (https) content](#only-display-secure-content)
|
||||||
* Disable the Node integration in all renderers that display remote content
|
* [Disable the Node integration in all renderers that display remote content](#disable-node-integration-for-remote-content)
|
||||||
(setting `nodeIntegration` to `false` in `webPreferences`)
|
(setting `nodeIntegration` to `false` in `webPreferences`)
|
||||||
* Enable context isolation in all renderers that display remote content
|
* Enable context isolation in all renderers that display remote content
|
||||||
(setting `contextIsolation` to `true` in `webPreferences`)
|
(setting `contextIsolation` to `true` in `webPreferences`)
|
||||||
|
@ -99,23 +99,26 @@ app.on('web-contents-created', (event, contents) => {
|
||||||
```
|
```
|
||||||
|
|
||||||
## Only Display Secure Content
|
## Only Display Secure Content
|
||||||
Any resources not included with your application should be loaded using a secure protocol
|
Any resources not included with your application should be loaded using a secure
|
||||||
like `HTTPS`. Furthermore, avoid "mixed content", which occurs when the initial HTML is
|
protocol like `HTTPS`. Furthermore, avoid "mixed content", which occurs when the
|
||||||
loaded over an `HTTPS` connection, but additional resources (scripts, stylesheets, etc)
|
initial HTML is loaded over an `HTTPS` connection, but additional resources
|
||||||
are loaded over an insecure connection.
|
(scripts, stylesheets, etc) are loaded over an insecure connection.
|
||||||
|
|
||||||
#### Why?
|
### Why?
|
||||||
`HTTPS` has three main benefits:
|
`HTTPS` has three main benefits:
|
||||||
|
|
||||||
1) It authenticates the remote server, ensuring that the host is actually who it claims
|
1) It authenticates the remote server, ensuring that the host is actually who it
|
||||||
to be. When loading a resource from an `HTTPS` host, it prevents an attacker from
|
claims to be. When loading a resource from an `HTTPS` host, it prevents an
|
||||||
impersonating that host, thus ensuring that the computer your app's users are
|
attacker from impersonating that host, thus ensuring that the computer your
|
||||||
connecting to is actually the host you wanted them to connect to.
|
app's users are connecting to is actually the host you wanted them to connect
|
||||||
2) It ensures data integrity, asserting that the data was not modified while in transit
|
to.
|
||||||
between your application and the host.
|
2) It ensures data integrity, asserting that the data was not modified while in
|
||||||
3) It encryps the traffic between your user and the destination host, making it more
|
transit between your application and the host.
|
||||||
difficult to eavesdropping on the information sent between your app and the host.
|
3) It encryps the traffic between your user and the destination host, making it
|
||||||
|
more difficult to eavesdropping on the information sent between your app and
|
||||||
|
the host.
|
||||||
|
|
||||||
|
### How?
|
||||||
```js
|
```js
|
||||||
// Bad
|
// Bad
|
||||||
browserWindow.loadURL('http://my-website.com')
|
browserWindow.loadURL('http://my-website.com')
|
||||||
|
@ -134,5 +137,60 @@ browserWindow.loadURL('https://my-website.com')
|
||||||
<link rel="stylesheet" href="https://cdn.com/style.css">
|
<link rel="stylesheet" href="https://cdn.com/style.css">
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Disable Node Integration for Remote Content
|
||||||
|
It is paramount that you disable Node integration in any renderer (`BrowserWindow`,
|
||||||
|
`BrowserView`, `WebView`) that loads remote content. The goal of disabling Node
|
||||||
|
integration 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
|
||||||
|
control over your website.
|
||||||
|
|
||||||
|
Disabling Node integration does not mean that you cannot grant additional powers
|
||||||
|
to the website you are loading – if you are opening a `BrowserWindow` pointed at
|
||||||
|
`https://my-website.com`, the goal is to give that website exactly the ability it
|
||||||
|
needs, but no more.
|
||||||
|
|
||||||
|
### Why?
|
||||||
|
A cross-site-scripting (XSS) becomes dramatically more dangerous if an attacker
|
||||||
|
can jump out of the renderer process and execute code on the user's computer.
|
||||||
|
Cross-site-scripting attacks are fairly common - and while an issue, their power
|
||||||
|
is usually limited to messing with the website that they are executed on. However,
|
||||||
|
in a renderer process with Node integration enabled, an XSS attack becomes a whole
|
||||||
|
different class of threat vector: A so-called "Remote Code Execution" (RCE) attack.
|
||||||
|
Disabling Node.js integration limits the power of successful XSS attacks.
|
||||||
|
|
||||||
|
### How?
|
||||||
|
```js
|
||||||
|
// Bad
|
||||||
|
const mainWindow = new BrowserWindow()
|
||||||
|
mainWindow.loadURL('https://my-website.com')
|
||||||
|
|
||||||
|
// Good
|
||||||
|
const mainWindow = new BrowserWindow({
|
||||||
|
webPreferences: {
|
||||||
|
nodeIntegration: false,
|
||||||
|
preload: './preload.js'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
mainWindow.loadURL('https://my-website.com')
|
||||||
|
```
|
||||||
|
|
||||||
|
When disabling Node integration, you can still expose APIs to your
|
||||||
|
website that do consume Node.js modules or features. Preload scripts continue to
|
||||||
|
have access to `require` and other Node.js features, allowing developers to expose
|
||||||
|
a custom API to remotely loaded content.
|
||||||
|
|
||||||
|
In the following example preload script, the later loaded website will have access
|
||||||
|
to a `window.readConfig()` method, but no Node.js features.
|
||||||
|
|
||||||
|
```js
|
||||||
|
const { readFileSync } = require('fs')
|
||||||
|
|
||||||
|
window.readConfig = function () {
|
||||||
|
const data = readFileSync('./config.json')
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Again, this list merely minimizes the risk, it does not remove it. If your goal
|
Again, this list merely minimizes the risk, it does not remove it. If your goal
|
||||||
is to display a website, a browser will be a more secure option.
|
is to display a website, a browser will be a more secure option.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue