# Risk map — electron/electron

> Canonical page: https://codevetter.com/unpack/electron/risk-map

# Risk map — electron/electron

Scanned commit 56f681cfe08e1c6bf02cfad2807ff1c47ae13d4f (2026-09-22). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

The largest risks are the security boundary between web content and Node, the breadth of the IPC surface, and the patch-queue maintenance burden. Sandbox/safety defaults are computed from webPreferences in one place (web_contents_preferences.cc) so changes there have wide blast radius; several features (fuses, ELECTRON_RUN_AS_NODE, preload privilege, protocol handlers) deliberately trade security for capability; and ~200 patches to Chromium/Node/V8 must be re-applied and merged on every dependency roll.
- Sandbox defaults are derived, not explicit: RendererProcessPreferences::From marks a renderer sandboxed unless nodeIntegration or nodeIntegrationInWorker is set (or webPreferences.sandbox overrides), and AppendCommandLineSwitches injects --no-sandbox/--no-zygote for unsandboxed renderers — a single pref change flips process isolation. — [shell/browser/web_contents_preferences.cc#L86-L117](https://github.com/electron/electron/blob/56f681cfe08e1c6bf02cfad2807ff1c47ae13d4f/shell/browser/web_contents_preferences.cc#L86-L117) [shell/browser/web_contents_preferences.cc#L126-L159](https://github.com/electron/electron/blob/56f681cfe08e1c6bf02cfad2807ff1c47ae13d4f/shell/browser/web_contents_preferences.cc#L126-L159)
- ELECTRON_DISABLE_SANDBOX unconditionally appends --no-sandbox at BasicStartupComplete, and ELECTRON_RUN_AS_NODE turns the whole binary into Node — both are env-var-controlled capabilities attackers can sometimes influence. — [shell/app/electron_main_delegate.cc#L100-L103](https://github.com/electron/electron/blob/56f681cfe08e1c6bf02cfad2807ff1c47ae13d4f/shell/app/electron_main_delegate.cc#L100-L103) [shell/app/electron_main_delegate.cc#L235-L236](https://github.com/electron/electron/blob/56f681cfe08e1c6bf02cfad2807ff1c47ae13d4f/shell/app/electron_main_delegate.cc#L235-L236) [lib/node/init.ts#L28-L41](https://github.com/electron/electron/blob/56f681cfe08e1c6bf02cfad2807ff1c47ae13d4f/lib/node/init.ts#L28-L41)
- Preload scripts run with Node globals even in isolated worlds; the Module.wrapper hack in lib/renderer/init.ts must stay in sync with the bundle's inject list in build/bundle/bundle.mjs, and mistakes leak process/Buffer into the main world (the deletion path only runs for non-context-isolated renderers). — [lib/renderer/init.ts#L21-L41](https://github.com/electron/electron/blob/56f681cfe08e1c6bf02cfad2807ff1c47ae13d4f/lib/renderer/init.ts#L21-L41) [lib/renderer/init.ts#L125-L141](https://github.com/electron/electron/blob/56f681cfe08e1c6bf02cfad2807ff1c47ae13d4f/lib/renderer/init.ts#L125-L141) [build/bundle/bundle.mjs#L127-L141](https://github.com/electron/electron/blob/56f681cfe08e1c6bf02cfad2807ff1c47ae13d4f/build/bundle/bundle.mjs#L127-L141)
- The IPC surface trusts channel strings end-to-end: internal channels share the same wire as app channels (ipcMainInternal vs ipcMain separated only by the 'internal' bool on the mojo call), so a confused-deputy bug in ipc_dispatch or event.type checks (e.g. rpc-server.ts guards event.type !== 'frame') would let renderer content reach privileged handlers. — [shell/browser/electron_api_ipc_handler_impl.cc#L48-L84](https://github.com/electron/electron/blob/56f681cfe08e1c6bf02cfad2807ff1c47ae13d4f/shell/browser/electron_api_ipc_handler_impl.cc#L48-L84) [lib/browser/rpc-server.ts#L4-L14](https://github.com/electron/electron/blob/56f681cfe08e1c6bf02cfad2807ff1c47ae13d4f/lib/browser/rpc-server.ts#L4-L14) [lib/browser/ipc-dispatch.ts#L5-L7](https://github.com/electron/electron/blob/56f681cfe08e1c6bf02cfad2807ff1c47ae13d4f/lib/browser/ipc-dispatch.ts#L5-L7)
- process._linkedBinding exposes the entire native binding table (ELECTRON_*_BINDINGS) to any code running with Node in the renderer when nodeIntegration is on — including process.crash() and process.hang() which deliberately crash/hang the process. — [shell/common/node_bindings.cc#L68-L120](https://github.com/electron/electron/blob/56f681cfe08e1c6bf02cfad2807ff1c47ae13d4f/shell/common/node_bindings.cc#L68-L120) [shell/common/api/electron_bindings.cc#L113-L123](https://github.com/electron/electron/blob/56f681cfe08e1c6bf02cfad2807ff1c47ae13d4f/shell/common/api/electron_bindings.cc#L113-L123)
- Fuses change security posture post-build without recompilation: grant_file_protocol_extra_privileges defaults to '1' (on) and run_as_node/node_options/node_cli_inspect default on; embedded_asar_integrity_validation and only_load_app_from_asar default off, so integrity guarantees are opt-in. — [build/fuses/fuses.json5#L5-L14](https://github.com/electron/electron/blob/56f681cfe08e1c6bf02cfad2807ff1c47ae13d4f/build/fuses/fuses.json5#L5-L14) [shell/browser/app_package.cc#L91-L98](https://github.com/electron/electron/blob/56f681cfe08e1c6bf02cfad2807ff1c47ae13d4f/shell/browser/app_package.cc#L91-L98) [docs/tutorial/fuses.md](https://github.com/electron/electron/blob/56f681cfe08e1c6bf02cfad2807ff1c47ae13d4f/docs/tutorial/fuses.md)
- protocol.handle bridges raw request data into Fetch objects: uploadData chunk types (rawData/file/stream/blob) are reassembled by hand and blob bytes come from session.defaultSession regardless of the requesting session (noted in the code as relying on globals) — a subtle cross-session data path. — [lib/browser/api/protocol.ts#L58-L106](https://github.com/electron/electron/blob/56f681cfe08e1c6bf02cfad2807ff1c47ae13d4f/lib/browser/api/protocol.ts#L58-L106)
- <webview> webPreferences are parsed from a DOM attribute string via parse-features-string, and guest-view-manager merges them with embedder-inherited security prefs; malformed or malicious attribute values are a parsing/injection surface, mitigated by the inheritedWebPreferences allowlist. — [lib/browser/guest-view-manager.ts#L32-L75](https://github.com/electron/electron/blob/56f681cfe08e1c6bf02cfad2807ff1c47ae13d4f/lib/browser/guest-view-manager.ts#L32-L75) [lib/browser/parse-features-string.ts](https://github.com/electron/electron/blob/56f681cfe08e1c6bf02cfad2807ff1c47ae13d4f/lib/browser/parse-features-string.ts)
- security_warnings.cc exists specifically to nag developers about insecure configurations (insecure content, disabled webSecurity, etc.) in devtools — implying the footguns are common enough to need runtime warnings, gated off in tests via ELECTRON_DISABLE_SECURITY_WARNINGS. — [shell/renderer/security_warnings.cc](https://github.com/electron/electron/blob/56f681cfe08e1c6bf02cfad2807ff1c47ae13d4f/shell/renderer/security_warnings.cc) [spec/index.js#L16](https://github.com/electron/electron/blob/56f681cfe08e1c6bf02cfad2807ff1c47ae13d4f/spec/index.js#L16)
- The uncaughtException handler in lib/browser/init.ts swallows main-process crashes into a GUI error box (showErrorBox) instead of exiting — a deliberate 'don't quit' policy that can mask fatal errors in production apps. — [lib/browser/init.ts#L14-L31](https://github.com/electron/electron/blob/56f681cfe08e1c6bf02cfad2807ff1c47ae13d4f/lib/browser/init.ts#L14-L31)
- patches/ carries ~200 patches across 13 upstream repos (chromium, node, v8, angle, sqlite, webrtc, boringssl, ffmpeg, ...); each Chromium roll (DEPS chromium_version) requires 3-way merging the queue, and patch rot in security-relevant files is a recurring fragility the repo's own docs warn about. — [patches/config.json](https://github.com/electron/electron/blob/56f681cfe08e1c6bf02cfad2807ff1c47ae13d4f/patches/config.json) [DEPS#L3-L8](https://github.com/electron/electron/blob/56f681cfe08e1c6bf02cfad2807ff1c47ae13d4f/DEPS#L3-L8) [docs/development/patches.md](https://github.com/electron/electron/blob/56f681cfe08e1c6bf02cfad2807ff1c47ae13d4f/docs/development/patches.md)
- spec/index.js kills processes matching the Electron execPath between spec files — on macOS via pgrep -f and on Linux by scanning /proc/*/exe — which would terminate any co-located Electron app sharing the binary path if run outside CI. — [spec/index.js#L104-L206](https://github.com/electron/electron/blob/56f681cfe08e1c6bf02cfad2807ff1c47ae13d4f/spec/index.js#L104-L206)
- ElectronBrowserMainParts holds most browser-process singletons (node_bindings_, js_env_, node_env_, browser_, fake_browser_process_) with an enforced single self_ instance; ordering bugs in PostEarlyInitialization (env before LoadAppPackage, JoinAppCode before FeatureList re-init) are load-bearing and poorly isolated. (inferred) — [shell/browser/electron_browser_main_parts.cc#L198-L210](https://github.com/electron/electron/blob/56f681cfe08e1c6bf02cfad2807ff1c47ae13d4f/shell/browser/electron_browser_main_parts.cc#L198-L210) [shell/browser/electron_browser_main_parts.cc#L290-L410](https://github.com/electron/electron/blob/56f681cfe08e1c6bf02cfad2807ff1c47ae13d4f/shell/browser/electron_browser_main_parts.cc#L290-L410)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
