Run plugin code in a renderer with Node.js integration off, context isolation on and the process sandbox enabled. Let it reach the system only through a small, validated IPC bridge that your main process controls. Never load or execute remote plugin code in a renderer that has Node access.
Why desktop plugins are different
The Electron security guide opens with a warning: Electron is not a web browser. Code you write can access the filesystem and user shell, so the risks scale with the powers granted. It also says displaying arbitrary content from untrusted sources poses a severe security risk that Electron is not intended to handle.
A plugin is untrusted content by definition. If your product has a plugin system on Electron, you have to build the containment yourself.
The core settings
The Electron documentation gives a checklist. The items most relevant to plugins:
- Do not enable Node.js integration for remote content. The guide says under no circumstances should you load and execute remote code with Node.js integration enabled.
- Enable context isolation in all renderers.
- Enable process sandboxing.
- Use a permission request handler for sessions that load remote content.
- Define a restrictive Content Security Policy.
- Disable or limit navigation.
The sandbox documentation explains the effect. With the sandbox on, renderer processes can only perform privileged tasks, such as touching the filesystem or spawning subprocesses, by delegating to the main process over IPC. It also warns that the sandbox is disabled when Node.js integration is enabled in the renderer, so one flag can quietly undo another.
A plugin bridge in four steps
- Define capabilities. List the exact actions a plugin may request, for example read the active document or show a notification. Anything not listed is denied.
- Expose them through a preload script with context isolation on, so plugin pages never see raw IPC objects. The Electron docs note that a preload script is more privileged than a sandboxed renderer and can leak privileged APIs to untrusted code unless context isolation is enabled.
- Validate in the main process. Check the sender, the arguments and the plugin's declared permissions on every call. Do not trust the renderer.
- Log and rate limit. A plugin making thousands of calls a minute should be visible.
Mistakes to avoid
| Mistake | Why it hurts |
|---|---|
| Turning on Node integration for convenience | Disables the sandbox and hands the plugin the machine |
| Passing raw ipcRenderer to the page | Lets plugin code call any channel |
| Trusting a plugin's claim about its identity | Identity must come from your manifest and signature checks |
| Falling behind on Electron versions | Ships known Chromium and Node.js fixes late |
The Electron guide stresses that your product bundles Electron, Chromium and Node.js, and that vulnerabilities in those components can affect you until you update. Plugin containment depends on a current runtime.
What the sandbox does not solve
Electron's own documentation is candid that it cannot match Chromium's resources and that some browser protections, such as Safe Browsing and Certificate Transparency, are disabled in Electron. Treat the sandbox as a strong layer, not a complete one, and keep review, permissions and a kill switch in place.
Quick check
Can a plugin use Node modules safely in the renderer?
Not if the renderer holds untrusted code. Move that work to the main process or a separate trusted helper and expose only a narrow API to the plugin.
Is context isolation optional if the sandbox is on?
No. The Electron documentation says preload scripts can still leak privileged APIs to untrusted code unless context isolation is enabled, so use both.
Safeguard can scan the npm dependencies your app and its bundled plugins ship, with SBOM and dependency scanning and policies for release gates. Try the free scan.
Sources
Last reviewed: 19 October 2026.