📝 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.
 | 
			
		||||
 | 
			
		||||
> :warning: Under no circumstances should you load and execute remote code with
 | 
			
		||||
Node integration enabled. Instead, use only local files (packaged together with
 | 
			
		||||
your application) to execute Node code. To display remote content, use the
 | 
			
		||||
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` tag and make sure to disable the `nodeIntegration`.
 | 
			
		||||
 | 
			
		||||
#### 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:
 | 
			
		||||
 | 
			
		||||
* [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`)
 | 
			
		||||
* Enable context isolation in all renderers that display remote content
 | 
			
		||||
  (setting `contextIsolation` to `true` in `webPreferences`)
 | 
			
		||||
| 
						 | 
				
			
			@ -99,23 +99,26 @@ app.on('web-contents-created', (event, contents) => {
 | 
			
		|||
```
 | 
			
		||||
 | 
			
		||||
## Only Display Secure Content
 | 
			
		||||
Any resources not included with your application should be loaded using a secure protocol
 | 
			
		||||
like `HTTPS`. Furthermore, avoid "mixed content", which occurs when the initial HTML is
 | 
			
		||||
loaded over an `HTTPS` connection, but additional resources (scripts, stylesheets, etc)
 | 
			
		||||
are loaded over an insecure connection.
 | 
			
		||||
Any resources not included with your application should be loaded using a secure
 | 
			
		||||
protocol like `HTTPS`. Furthermore, avoid "mixed content", which occurs when the
 | 
			
		||||
initial HTML is loaded over an `HTTPS` connection, but additional resources
 | 
			
		||||
(scripts, stylesheets, etc) are loaded over an insecure connection.
 | 
			
		||||
 | 
			
		||||
#### Why?
 | 
			
		||||
### Why?
 | 
			
		||||
`HTTPS` has three main benefits:
 | 
			
		||||
 | 
			
		||||
1) It authenticates the remote server, ensuring that the host is actually who it claims
 | 
			
		||||
   to be. When loading a resource from an `HTTPS` host, it prevents an attacker from
 | 
			
		||||
   impersonating that host, thus ensuring that the computer your app's users are
 | 
			
		||||
   connecting to is actually the host you wanted them to connect to.
 | 
			
		||||
2) It ensures data integrity, asserting that the data was not modified while in transit
 | 
			
		||||
   between your application 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.
 | 
			
		||||
1) It authenticates the remote server, ensuring that the host is actually who it
 | 
			
		||||
   claims to be. When loading a resource from an `HTTPS` host, it prevents an
 | 
			
		||||
   attacker from impersonating that host, thus ensuring that the computer your
 | 
			
		||||
   app's users are connecting to is actually the host you wanted them to connect
 | 
			
		||||
   to.
 | 
			
		||||
2) It ensures data integrity, asserting that the data was not modified while in
 | 
			
		||||
   transit between your application 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
 | 
			
		||||
// Bad
 | 
			
		||||
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">
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## 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
 | 
			
		||||
is to display a website, a browser will be a more secure option.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue