MovieMapper/preload.js
Jarian Cottingham 73f5585488 security: harden Electron app - context isolation, preload, fix XSS & command injection
- Enable contextIsolation, disable nodeIntegration, remove enableRemoteModule
- Add preload.js with safe contextBridge API exposure
- Fix OS command injection: exec() → execFile() in open-file-in-player
- Fix DOM XSS: replace innerHTML with textContent/createElement in FileListManager, UIManager, ModalManager
- Remove direct fs/electron access from renderer, route through IPC
- Add validate-folder and get-file-stats IPC handlers
- Load renderer modules via script tags with require polyfill
2026-07-05 07:31:06 +00:00

54 lines
1.5 KiB
JavaScript

const { contextBridge, ipcRenderer } = require('electron');
const path = require('path');
const fakeIpcRenderer = {
invoke: (channel, ...args) => ipcRenderer.invoke(channel, ...args),
on: (channel, callback) => {
const listener = (_event, ...args) => callback(...args);
ipcRenderer.on(channel, listener);
return () => ipcRenderer.removeListener(channel, listener);
},
};
const fakeElectronModule = {
ipcRenderer: fakeIpcRenderer,
app: null,
BrowserWindow: null,
dialog: null,
ipcMain: null,
};
const fakePathModule = {
join: (...args) => path.join(...args),
dirname: (p) => path.dirname(p),
basename: (p) => path.basename(p),
extname: (p) => path.extname(p),
sep: path.sep,
resolve: (...args) => path.resolve(...args),
};
contextBridge.exposeInMainWorld('electronAPI', {
ipcRenderer: fakeIpcRenderer,
});
contextBridge.exposeInMainWorld('createModuleRequire', () => {
return function requirePolyfill(moduleName) {
if (moduleName === 'electron') {
return fakeElectronModule;
}
if (moduleName === 'path') {
return fakePathModule;
}
if (moduleName === 'fs') {
throw new Error('Direct fs access disabled. Use IPC.');
}
if (moduleName.startsWith('./')) {
const baseName = moduleName.replace('./', '').replace('.js', '');
const mod = window[baseName];
if (mod) return mod;
throw new Error(`Module not found: ${moduleName}`);
}
throw new Error(`Module not allowed: ${moduleName}`);
};
});