Keep nodeIntegration off, contextIsolation on, sandbox on, webSecurity on, and add a Content Security Policy. Current Electron versions ship with the first four set safely. Most real problems come from developers turning one off to make a library work, then forgetting about it before release.
Why the defaults matter
An Electron app is a web page with a native shell around it. If a script you did not write runs inside that page, the question is what it can reach. With safe defaults, the answer is "the page, and nothing else." With nodeIntegration enabled for pages that load remote content, a cross site scripting bug becomes remote code execution on the user's machine.
The Electron security guide states the current defaults. Node.js integration has been off for renderers since Electron 5. Context isolation has been on since Electron 12. The renderer sandbox has been on since Electron 20.
The settings to verify
Check each of these in your window creation code and in any helper that builds a BrowserWindow.
nodeIntegrationshould be false, and so shouldnodeIntegrationInWorker.contextIsolationshould be true. The guide notes that turning it off also turns off sandboxing.sandboxshould not be set to false without a written reason.webSecurityshould stay enabled. Disabling it removes the same origin policy and also allows insecure content.allowRunningInsecureContent,experimentalFeaturesandenableBlinkFeaturesshould stay at their defaults.
A one line grep for these option names across the repository is a cheap review step. Anything set to the unsafe value needs an owner and a reason in a comment.
Controls that are not on by default
Some protections only exist if you add them.
- Content Security Policy. Set it with a response header hook or a meta tag. A policy such as
script-src 'self'limits what a page can load. - Permission handling. The guide says that without a custom permission request handler, requests are approved automatically. Add one that checks the requesting origin and the permission type.
- Navigation and new windows. Handle
will-navigateandsetWindowOpenHandlerso a page cannot send the window somewhere unexpected. Parse URLs properly instead of using a prefix check. shell.openExternal. Never pass it untrusted input.- Local files. The guide advises against loading pages over
file://and suggests a custom protocol instead.
Keep Electron current
The guide is blunt about this: older Electron versions have more publicly known exploits. An Electron release bundles its own Chromium and Node.js, so a desktop app does not pick up browser fixes unless you ship a new build. Plan for regular upgrades, one major version at a time, using the breaking changes document.
A simple release gate
Add a short test that creates each window type and asserts the web preferences. It takes a few minutes to write and catches the regression where someone flips a flag during a debugging session.
Safeguard can scan an Electron project's npm dependencies and produce an SBOM, which helps with the "keep it current" part. You can try a free scan at https://gold.safeguard.sh/scan.
Try it yourself
Click through it at your own pace, or open it full screen.
Watch how a newly published issue shows up against an existing project, which is the signal that tells you an Electron or npm upgrade is due.
Quick check
Is contextIsolation enough to make preload code safe?
No. It separates the preload world from the page, but if you expose a generic function such as raw IPC send through the bridge, the page can still ask the main process to do anything. Expose narrow, purpose built functions only.
Do I still need a CSP if I only load my own files?
Yes. A CSP limits damage if an injected script or a compromised dependency tries to load more code or send data out.
Sources
Last reviewed: 19 October 2026.