Electron 应用怎么防 XSS 和代码注入?安全最佳实践
Electron 的安全核心原则:不要信任渲染进程中的任何代码。渲染进程加载的是 Web 内容,可能被 XSS 攻击。如果渲染进程有 Node.js 访问权限(nodeIntegration: true),XSS 就等于远程代码执行——攻击者可以直接读写文件系统。
第一条规则:关闭 nodeIntegration
javascriptnew BrowserWindow({ webPreferences: { nodeIntegration: false, contextIsolation: true } });
nodeIntegration: false:渲染进程的 JS 不能直接调用require('fs')等 Node.js APIcontextIsolation: true:预加载脚本和渲染页面的 JS 运行在不同的 V8 上下文中,渲染页面无法修改预加载脚本的全局变量
这是 Electron 最基本的安全配置。不关 nodeIntegration 的应用,一个 XSS 漏洞就能让攻击者完全控制用户的电脑。
第二条规则:enableRemoteModule 关掉
@electron/remote 模块让渲染进程间接调用主进程的 API。它本质上是把主进程的能力暴露给了渲染进程,和 nodeIntegration: true 一样危险。
javascriptwebPreferences: { nodeIntegration: false, contextIsolation: true, sandbox: true }
sandbox: true 把渲染进程放在 Chromium 沙箱里,即使有漏洞也无法访问系统资源。这是最严格的安全模式。
preload 脚本安全模式
需要渲染进程和主进程通信时,用 preload 脚本暴露有限的 API:
javascript// preload.js const { contextBridge, ipcRenderer } = require('electron'); contextBridge.exposeInMainWorld('electronAPI', { readFile: (path) => ipcRenderer.invoke('read-file', path), saveFile: (path, content) => ipcRenderer.invoke('save-file', path, content) });
javascript// 渲染进程 const content = await window.electronAPI.readFile('/path/to/file');
contextBridge.exposeInMainWorld 只暴露你明确声明的函数,渲染进程无法访问其他任何 Node.js API。攻击者即使注入了 JS,也只能调用 readFile 和 saveFile,不能执行任意系统命令。
不要加载不信任的远程内容
javascript// 危险!加载远程 HTML win.loadURL('https://untrusted-site.com'); // 安全:只加载本地文件 win.loadFile('index.html');
如果必须加载远程内容,用 webSecurity: true(默认开启)确保同源策略生效,并用 allowRunningInsecureContent: false 阻止加载 HTTP 资源。
限制导航和弹窗
javascriptwin.webContents.on('will-navigate', (event, url) => { event.preventDefault(); // 阻止页面跳转 }); win.webContents.setWindowOpenHandler(() => { return { action: 'deny' }; // 阻止弹窗 });
XSS 攻击常用的手法是让页面跳转到恶意域名。阻止导航和弹窗可以切断这个路径。
内容安全策略(CSP)
在 HTML 的 meta 标签或 HTTP 头里设置 CSP,限制资源加载来源:
html<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'">
script-src 'self' 只允许加载同源脚本,阻止攻击者注入外部 JS。unsafe-inline 对 CSS 可以接受(样式注入危害小),对 JS 绝对不能用。
代码签名和公证
未签名的应用会被操作系统拦截(macOS Gatekeeper、Windows SmartScreen),用户看到警告后大概率不敢安装。
- macOS:需要 Apple Developer 证书签名 + 公证(notarization)。electron-builder 配合
electron-notarize工具自动完成。 - Windows:需要代码签名证书(EV 证书最可靠,立即获得 SmartScreen 信誉)。
- Linux:无签名要求,但 AppImage/Flatpak 有各自的签名机制。
自动更新的安全
确保更新包通过 HTTPS 下载,且验证签名。electron-updater 默认在 macOS 上验证代码签名,Windows 上验证 SHA256。不要关闭签名验证。
检查清单
-
nodeIntegration: false -
contextIsolation: true -
sandbox: true(如果不需要 preload 调 Node API) - 不使用
@electron/remote - preload 只暴露最小 API
- CSP 禁止
unsafe-inline脚本 - 阻止渲染进程导航到外部 URL
- 应用签名 + 公证