Electron contextIsolation + preloadセキュリティパターン
問題
ElectronでnodeIntegration: trueにすると、レンダラー(Webページ)からrequire('fs')でファイルシステムに直接アクセスできます。外部URLをロードする場合、深刻なセキュリティリスクになります。
解決方法
// main.js - メインプロセス
const mainWindow = new BrowserWindow({
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
contextIsolation: true, // レンダラーとNode.jsコンテキストを分離
nodeIntegration: false, // レンダラーでrequireをブロック
}
});
// preload.js - ブリッジ役割
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('electronAPI', {
scanNetwork: () => ipcRenderer.invoke('scan-network'),
getVersion: () => ipcRenderer.invoke('get-version'),
onScanResult: (callback) =>
ipcRenderer.on('scan-result', (_, data) => callback(data)),
});
// renderer.js - Webページで使用
const results = await window.electronAPI.scanNetwork();
ポイント
contextIsolation: trueにすると、preloadスクリプトのグローバルオブジェクトとレンダラーのグローバルオブジェクトが完全に分離されます。contextBridge.exposeInMainWorldで許可された関数のみが公開されます。- レンダラーでできるのは
window.electronAPIに定義されたことだけです。require('child_process')のような危険なアクセスは不可能です。 ipcRenderer.invokeはPromiseを返す双方向通信です。メインプロセスでipcMain.handleで受け取って処理します。