Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix!: change enableRemoteModule to .enable() for electron@14 #72

Merged
merged 9 commits into from
Sep 14, 2021
15 changes: 9 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,13 @@ configure your bundler appropriately to package the code of `@electron/remote`
in the preload script. Of course, [using `@electron/remote` makes the sandbox
much less effective][remote-considered-harmful].

**Note:** `@electron/remote` respects the `enableRemoteModule` WebPreferences
**Note:** In `electron >= 14.0.0`, you must use the new `enable` API to enable the remote module for each desired `WebContents` separately: `require("@electron/remote/main").enable(webContents)`.

In `electron < 14.0.0`, `@electron/remote` respects the `enableRemoteModule` WebPreferences
value. You must pass `{ webPreferences: { enableRemoteModule: true } }` to
the constructor of `BrowserWindow`s that should be granted permission to use
`@electron/remote`.


# API Reference

The `remote` module provides a simple way to do inter-process communication
Expand Down Expand Up @@ -85,7 +86,9 @@ of the remote module:
require('@electron/remote/main').initialize()
```

**Note:** The remote module can be disabled for security reasons in the following contexts:
**Note:** In `electron >= 14.0.0` the remote module is disabled by default for any `WebContents` instance and is only enabled for specified `WebContents` after explicitly calling `require("@electron/remote/main").enable(webContents)`.

In `electron < 14.0.0` the remote module can be disabled for security reasons in the following contexts:
- [`BrowserWindow`](browser-window.md) - by setting the `enableRemoteModule` option to `false`.
- [`<webview>`](webview-tag.md) - by setting the `enableremotemodule` attribute to `false`.

Expand Down Expand Up @@ -214,8 +217,8 @@ e.g.
```sh
project/
├── main
   ├── foo.js
   └── index.js
├── foo.js
└── index.js
├── package.json
└── renderer
└── index.js
Expand Down Expand Up @@ -339,4 +342,4 @@ Custom value can be returned by setting `event.returnValue`.

[rmi]: https://en.wikipedia.org/wiki/Java_remote_method_invocation
[enumerable-properties]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties
[remote-considered-harmful]: https://medium.com/@nornagon/electrons-remote-module-considered-harmful-70d69500f31
[remote-considered-harmful]: https://medium.com/@nornagon/electrons-remote-module-considered-harmful-70d69500f31
2 changes: 1 addition & 1 deletion src/main/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { initialize } from './server'
export { initialize, enable } from "./server";
20 changes: 16 additions & 4 deletions src/main/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ import { getElectronBinding } from '../common/get-electron-binding'

const v8Util = getElectronBinding('v8_util')

const hasWebPrefsRemoteModuleAPI = (() => {
const electronVersion = Number(process.versions.electron?.split(".")?.[0]);
return Number.isNaN(electronVersion) || electronVersion < 14
})()

// The internal properties of Function.
const FUNCTION_PROPERTIES = [
'length', 'name', 'arguments', 'caller', 'prototype'
Expand Down Expand Up @@ -289,26 +294,33 @@ const unwrapArgs = function (sender: WebContents, frameId: number, contextId: st

const isRemoteModuleEnabledImpl = function (contents: WebContents) {
const webPreferences = contents.getLastWebPreferences() || {}
return webPreferences.enableRemoteModule != null ? !!webPreferences.enableRemoteModule : false
return (webPreferences as any).enableRemoteModule != null ? !!(webPreferences as any).enableRemoteModule : false
nornagon marked this conversation as resolved.
Show resolved Hide resolved
}

const isRemoteModuleEnabledCache = new WeakMap()
const isRemoteModuleEnabledCache = new WeakMap<WebContents, boolean>()

export const isRemoteModuleEnabled = function (contents: WebContents) {
if (!isRemoteModuleEnabledCache.has(contents)) {
if (hasWebPrefsRemoteModuleAPI && !isRemoteModuleEnabledCache.has(contents)) {
isRemoteModuleEnabledCache.set(contents, isRemoteModuleEnabledImpl(contents))
}

return isRemoteModuleEnabledCache.get(contents)
}

export function enable(contents: WebContents) {
isRemoteModuleEnabledCache.set(contents, true)
}

const handleRemoteCommand = function (channel: string, handler: (event: IpcMainEvent, contextId: string, ...args: any[]) => void) {
ipcMain.on(channel, (event, contextId: string, ...args: any[]) => {
let returnValue: MetaType | null | void

if (!isRemoteModuleEnabled(event.sender)) {
event.returnValue = {
type: 'exception',
value: valueToMeta(event.sender, contextId, new Error('@electron/remote is disabled for this WebContents. Set {enableRemoteModule: true} in WebPreferences to enable it.'))
value: valueToMeta(event.sender, contextId, new Error(
'@electron/remote is disabled for this WebContents. Call require("@electron/remote/main").enable(webContents) to enable it.'
))
}
return
}
Expand Down