人人都会AI编程

禁用 nodeIntegration、开启 contextIsolation

更新时间:2026-07-11

在 Electron 应用中,窗口的 webPreferences 配置决定了渲染进程的能力边界。其中两个最关键的安全选项是 nodeIntegrationcontextIsolation。它们的默认值在 Electron 的版本迭代中不断收紧,但显式地理解并正确配置它们,是构建安全桌面应用的第一步。

为什么需要禁用 nodeIntegration

nodeIntegration: true 时,渲染进程中的 JavaScript 可以直接使用 require 引入 Node.js 内置模块(如 fschild_process),也可以直接访问 Electron 的原生 API。这带来的风险是:如果页面中任何地方存在 XSS 漏洞,攻击者注入的代码就能立即获得完整的系统权限——读取任意文件、执行系统命令、监听键盘输入等。

因此,从 Electron 5 开始,官方已将 nodeIntegration 的默认值改为 false禁用 nodeIntegration 的本质,是将渲染进程变回一个相对纯粹的浏览器环境,切断它直接触碰系统资源的能力。 所有需要权限的操作都必须通过主进程完成,主进程可以有选择地暴露安全的接口。

实际配置非常简单,创建窗口时明确指定:

const win = new BrowserWindow({
  width: 800,
  height: 600,
  webPreferences: {
    nodeIntegration: false,  // 渲染进程不能直接使用 require
    contextIsolation: true,  // 配合实现安全隔离
    preload: path.join(__dirname, 'preload.js'),
  },
});

为什么必须开启 contextIsolation

即使禁用了 nodeIntegration,如果 contextIsolationfalse,预加载脚本中定义的变量仍然会直接挂载到渲染进程的 window 对象上。这意味着页面内的脚本可以读取或篡改这些变量,预加载脚本所暴露的能力仍然可能被恶意代码利用。

contextIsolation: true 的作用,是在渲染进程的 JavaScript 环境和预加载脚本之间创建一道隔离墙。预加载脚本仍然可以访问 Node.js 和 Electron API,但它所暴露的任何东西都不会直接出现在页面全局作用域中。相反,你需要显式地使用 contextBridge.exposeInMainWorld 将安全的方法挂载到一个指定的上下文(比如 window.electronAPI),页面只能访问这些被显式暴露的方法,无法触及预加载脚本内部的实现细节。

可以这样理解:contextIsolation 将预加载脚本的权限环境与页面内容的环境完全分离开来,即使页面被注入恶意脚本,攻击者也无法直接调用原生能力。

安全配置的真实示例

下面是一个完整的预加载脚本,用于安全地向渲染进程暴露主进程的文件读取能力:

// preload.js
const { contextBridge, ipcRenderer } = require('electron');

// 使用 contextBridge 暴露一个安全的 API 对象
contextBridge.exposeInMainWorld('electronAPI', {
  // 只暴露需要的方法,不暴露 ipcRenderer 本身
  readFile: (filePath) => ipcRenderer.invoke('read-file', filePath),
  saveFile: (filePath, content) => ipcRenderer.invoke('save-file', filePath, content),
  // 也可以暴露事件监听,但要控制范围
  onFileChanged: (callback) => {
    ipcRenderer.on('file-changed', (event, data) => callback(data));
  },
});

在渲染进程(页面代码)中,你只能使用 window.electronAPI.readFile(...),无法接触到 require 或原始的 ipcRenderer,更无法执行任意系统调用。主进程对应处理:

// main.js 主进程处理 IPC
ipcMain.handle('read-file', async (event, filePath) => {
  const fs = require('fs');
  // 这里可以加入路径校验,防止读取敏感系统文件
  return fs.promises.readFile(filePath, 'utf-8');
});

记住这条黄金规则

在现代 Electron 开发中,始终同时设置 nodeIntegration: falsecontextIsolation: true。这已经是官方脚手架 electron-forge 和最新版文档的默认行为。如果你在调试旧项目时看到 nodeIntegration: truecontextIsolation: false,应把它们视为需要立即修复的安全隐患。

这条规则配合 preload 脚本和 contextBridge,构成了 Electron 应用安全架构的基石。它不会让你的开发效率降低,反而会通过清晰的权限边界,迫使你设计出更健壮的应用结构。