memo: Update security docs: will-navigate, new-window (#13887)
This commit is contained in:
parent
13d3a055fa
commit
ad2d35c7cf
1 changed files with 90 additions and 2 deletions
|
@ -81,7 +81,8 @@ improve the security of your application.
|
||||||
10. [Do not use `enableBlinkFeatures`](#10-do-not-use-enableblinkfeatures)
|
10. [Do not use `enableBlinkFeatures`](#10-do-not-use-enableblinkfeatures)
|
||||||
11. [`<webview>`: Do not use `allowpopups`](#11-do-not-use-allowpopups)
|
11. [`<webview>`: Do not use `allowpopups`](#11-do-not-use-allowpopups)
|
||||||
12. [`<webview>`: Verify options and params](#12-verify-webview-options-before-creation)
|
12. [`<webview>`: Verify options and params](#12-verify-webview-options-before-creation)
|
||||||
|
13. [Disable or limit navigation](#13-disable-or-limit-navigation)
|
||||||
|
14. [Disable or limit creation of new windows](#13-disable-or-limit-creation-of-new-windows)
|
||||||
|
|
||||||
## 1) Only Load Secure Content
|
## 1) Only Load Secure Content
|
||||||
|
|
||||||
|
@ -536,7 +537,7 @@ for newly created [`<webview>`][webview-tag] tags.
|
||||||
|
|
||||||
Before a [`<webview>`][webview-tag] tag is attached, Electron will fire the
|
Before a [`<webview>`][webview-tag] tag is attached, Electron will fire the
|
||||||
`will-attach-webview` event on the hosting `webContents`. Use the event to
|
`will-attach-webview` event on the hosting `webContents`. Use the event to
|
||||||
prevent the creation of webviews with possibly insecure options.
|
prevent the creation of `webViews` with possibly insecure options.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
app.on('web-contents-created', (event, contents) => {
|
app.on('web-contents-created', (event, contents) => {
|
||||||
|
@ -559,6 +560,93 @@ app.on('web-contents-created', (event, contents) => {
|
||||||
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.
|
||||||
|
|
||||||
|
## 13) Disable or limit navigation
|
||||||
|
|
||||||
|
If your app has no need to navigate or only needs to navigate to known pages,
|
||||||
|
it is a good idea to limit navigation outright to that known scope, disallowing
|
||||||
|
any other kinds of navigation.
|
||||||
|
|
||||||
|
### Why?
|
||||||
|
|
||||||
|
Navigation is a common attack vector. If an attacker can convince your app to
|
||||||
|
navigate away from its current page, they can possibly force your app to open
|
||||||
|
web sites on the Internet. Even if your `webContents` are configured to be more
|
||||||
|
secure (like having `nodeIntegration` disabled or `contextIsolation` enabled),
|
||||||
|
getting your app to open a random web site will make the work of exploiting your
|
||||||
|
app a lot easier.
|
||||||
|
|
||||||
|
A common attack pattern is that the attacker convinces your app's users to
|
||||||
|
interact with the app in such a way that it navigates to one of the attacker's
|
||||||
|
pages. This is usually done via links, plugins, or other user-generated content.
|
||||||
|
|
||||||
|
### How?
|
||||||
|
|
||||||
|
If your app has no need for navigation, you can call `event.preventDefault()`
|
||||||
|
in a [`will-navigate`][will-navigate] handler. If you know which pages your app
|
||||||
|
might navigate to, check the URL in the event handler and only let navigation
|
||||||
|
occur if it matches the URLs you're expecting.
|
||||||
|
|
||||||
|
We recommend that you use Node's parser for URLs. Simple string comparisons can
|
||||||
|
sometimes be fooled - a `startsWith('https://google.com')` test would let
|
||||||
|
`https://google.com.attacker.com` through.
|
||||||
|
|
||||||
|
```js
|
||||||
|
const URL = require('url')
|
||||||
|
|
||||||
|
app.on('web-contents-created', (event, contents) => {
|
||||||
|
contents.on('will-navigate', (event, navigationUrl) => {
|
||||||
|
const parsedUrl = new URL(navigationUrl)
|
||||||
|
|
||||||
|
if (url.hostname !== 'my-own-server.com') {
|
||||||
|
event.preventDefault()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
## 14) Disable or limit creation of new windows
|
||||||
|
|
||||||
|
If you have a known set of windows, it's a good idea to limit the creation of
|
||||||
|
additional windows in your app.
|
||||||
|
|
||||||
|
### Why?
|
||||||
|
|
||||||
|
Much like navigation, the creation of new `webContents` is a common attack
|
||||||
|
vector. Attackers attempt to convince your app to create new windows, frames,
|
||||||
|
or other renderer processes with more privileges than they had before; or
|
||||||
|
with pages opened that they couldn't open before.
|
||||||
|
|
||||||
|
If you have no need to create windows in addition to the ones you know you'll
|
||||||
|
need to create, disabling the creation buys you a little bit of extra
|
||||||
|
security at no cost. This is commonly the case for apps that open one
|
||||||
|
`BrowserWindow` and do not need to open an arbitrary number of additional
|
||||||
|
windows at runtime.
|
||||||
|
|
||||||
|
### How?
|
||||||
|
|
||||||
|
[`webContents`][web-contents] will emit the [`new-window`][new-window] event
|
||||||
|
before creating new windows. That event will be passed, amongst other
|
||||||
|
parameters, the `url` the window was requested to open and the options used to
|
||||||
|
create it. We recommend that you use the event to scrutinize the creation of
|
||||||
|
windows, limiting it to only what you need.
|
||||||
|
|
||||||
|
```js
|
||||||
|
const { shell } = require('electron')
|
||||||
|
|
||||||
|
app.on('web-contents-created', (event, contents) => {
|
||||||
|
contents.on('new-window', (event, navigationUrl) => {
|
||||||
|
// In this example, we'll ask the operating system
|
||||||
|
// to open this event's url in the default browser.
|
||||||
|
event.preventDefault()
|
||||||
|
|
||||||
|
shell.openExternal(navigationUrl)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
[browser-window]: ../api/browser-window.md
|
[browser-window]: ../api/browser-window.md
|
||||||
[browser-view]: ../api/browser-view.md
|
[browser-view]: ../api/browser-view.md
|
||||||
[webview-tag]: ../api/webview-tag.md
|
[webview-tag]: ../api/webview-tag.md
|
||||||
|
[web-contents]: ../api/web-contents.md
|
||||||
|
[new-window]: ../api/web-contents#event-new-window
|
||||||
|
[will-navigate]: ../api/web-contents#event-will-navigate
|
||||||
|
|
Loading…
Reference in a new issue