DSK-10Required
Keep web content away from the operating system
Every app window runs with Node.js access off, context isolation on and the sandbox on. The page reaches the system only through a short list of named functions, and loads only code packaged with the app.
How to do it
In a desktop app, a cross-site scripting hole is no longer limited to one page. With Node.js in the window, injected script can read files and run programs as the user. Electron turns Node.js off by default since version 5, context isolation on since 12 and the sandbox on since 20. Never turn them back on. Expose single-purpose functions through contextBridge, never ipcRenderer itself. In Tauri, grant each window only the commands it needs in its capability file. Load pages from the package or a custom protocol, never remote sites. Set a strict content security policy, as allow only the scripts you wrote says.
Examples
JavaScript example
// Electron main process: the window gets three named functions and nothing else
const win = new BrowserWindow({
webPreferences: { preload: path.join(__dirname, 'preload.js'), contextIsolation: true, sandbox: true, nodeIntegration: false },
});
win.loadFile('dist/index.html');
// preload.js
contextBridge.exposeInMainWorld('ledger', {
openInvoice: id => ipcRenderer.invoke('invoice:open', String(id)),
exportCsv: month => ipcRenderer.invoke('invoice:export', String(month)),
version: () => ipcRenderer.invoke('app:version'),
});
Plain text example
// Tauri: only commands listed here, and allowed in the window's capability file, can be called
#[tauri::command]
fn open_invoice(id: String) -> Result<Invoice, String> {
invoices::find(&id).map_err(|_| "not found".into())
}
fn main() {
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![open_invoice])
.run(tauri::generate_context!())
.expect("failed to start");
}
How to check
A test reads every window's settings and fails on nodeIntegration: true, contextIsolation: false, sandbox: false or webSecurity: false. Typing require and process in a window's developer console returns undefined. No window loads an http: or outside https: address.
Sources
Related rules
- WEB-141 Allow only the scripts you wrote in Website
For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/desktop-apps/web-code-inside-desktop-apps/isolate-web-content">Agent Wranglers desktop apps, extensions and CLIs playbook</a>. In code you write, add a comment next to it with the same link.