看起来 Electron 的安全性是这样发展的(来源)。
Electron 1 nodeIntegration默认为 true
Renderer 拥有对 Node API 的完全访问权——如果 Renderer 加载远程代码,则存在巨大的安全风险。
Electron 5 nodeIntegration默认为 false
当设置为 false 时,预加载脚本用于向渲染器公开特定的 API。(无论nodeIntegration的值如何,预加载脚本始终可以访问节点 API )
//preload.js
window.api = {
deleteFile: f => require('fs').unlink(f)
}
Electron 5 contextIsolation默认为 true(实际上在 Electron 11 中仍然默认为 false)
这会导致预加载脚本在单独的上下文中运行。你不能再这样做了window.api = ...
。你现在必须做:
//preload.js
const { contextBridge } = require('electron')
contextBridge.exposeInMainWorld('api', {
deleteFile: f => require('fs').unlink(f)
})
require()
沙盒渲染器中的Electron 6 ing 节点内置程序不再隐式加载远程版本
如果 Renderer 已sandbox
设置为 true,则必须执行以下操作:
//preload.js
const { contextBridge, remote } = require('electron')
contextBridge.exposeInMainWorld('api', {
deleteFile: f => remote.require('fs').unlink(f)
})
Electron 10 enableRemoteModule默认为 false(远程module在 Electron 12 中已弃用)
remote
当您需要从沙盒渲染器访问 Node API 时使用该module(如上例所示);或者当您需要访问仅适用于主进程(例如对话框、菜单)的 Electron API 时。如果没有remote
,您将需要编写如下所示的显式 IPC 处理程序。
//preload.js
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('api', {
displayMessage: text => ipcRenderer.invoke("displayMessage", text)
})
//main.js
const { ipcMain, dialog } = require('electron')
ipcMain.handle("displayMessage", text => dialog.showMessageBox(text))
Electron 10 弃用 nodeIntegration标志(在 Electron 12 中删除)
推荐
始终设置{nodeIntegration: false, contextIsolation: true, enableRemoteModule: false}
。
为了最大的安全性,设置{sandbox: true}
. 您的预加载脚本将不得不使用 IPC 调用 Main 进程来完成所有工作。
如果sandbox
为 false,则您的预加载脚本可以直接访问 Node API,如require('fs').readFile
. 只要你不这样做,你就是安全的:
//bad
contextBridge.exposeInMainWorld('api', {
readFile: require('fs').readFile
})