Skip to content

安全配置

Electron 的安全重点是限制渲染进程能力。渲染进程越像普通浏览器页面,风险越低。

BrowserWindow 配置

ts
const win = new BrowserWindow({
  webPreferences: {
    preload: preloadPath,
    contextIsolation: true,
    nodeIntegration: false,
    sandbox: true,
  },
})

关键配置:

  • contextIsolation: true:隔离 preload 和页面运行上下文。
  • nodeIntegration: false:页面中不能直接使用 Node.js。
  • sandbox: true:进一步限制渲染进程权限。
  • preload:只暴露经过封装的最小 API。

不直接加载远程页面

桌面应用优先加载本地构建产物:

ts
void win.loadFile(indexHtml)

开发环境可以加载本地开发服务器:

ts
void win.loadURL(process.env.ELECTRON_RENDERER_URL)

如果必须加载远程页面,需要额外处理 CSP、导航限制、权限控制和外链打开策略。

限制导航

阻止应用窗口被导航到非预期地址:

ts
win.webContents.on('will-navigate', (event, url) => {
  if (!url.startsWith('file://')) {
    event.preventDefault()
  }
})

外部链接交给系统浏览器:

ts
import { shell } from 'electron'

win.webContents.setWindowOpenHandler(({ url }) => {
  void shell.openExternal(url)
  return { action: 'deny' }
})

打开外部链接前应校验协议,只允许 https: 等安全协议。

Preload 最小暴露

不要暴露底层对象:

ts
// 避免
contextBridge.exposeInMainWorld('ipcRenderer', ipcRenderer)

只暴露业务 API:

ts
contextBridge.exposeInMainWorld('settingsApi', {
  get: (key: string) => ipcRenderer.invoke('settings:get', key),
  set: (key: string, value: string) => ipcRenderer.invoke('settings:set', key, value),
})

权限控制

按需处理权限请求:

ts
session.defaultSession.setPermissionRequestHandler((_webContents, permission, callback) => {
  const allowed = permission === 'clipboard-read'
  callback(allowed)
})

默认策略应偏保守:不明确需要的权限直接拒绝。

Checklist

  • [ ] contextIsolation: true
  • [ ] nodeIntegration: false
  • [ ] sandbox: true
  • [ ] preload 不暴露 ipcRendererrequireprocess
  • [ ] IPC 参数做类型和范围校验
  • [ ] 禁止窗口导航到非预期地址
  • [ ] 外链使用系统浏览器打开
  • [ ] 不在生产环境加载不受控远程页面

基于 MIT 许可发布