Aug 5, 2026·5 min read·17 visits
Electron contextBridge allowed prototype pollution across the context isolation boundary by using standard V8 property setters instead of direct data property definition during object cloning.
A security vulnerability in Electron's contextBridge allows untrusted renderer contexts to bypass context isolation. By passing an object with a crafted __proto__ property, an attacker can pollute the prototype chain of objects copied into the privileged preload context. This occurs because Electron's C++ property copying layer used standard V8 property assignment, which executes prototype setters. This bypasses Electron's context isolation security boundary, potentially enabling remote code execution (RCE) or privileges escalation. The vulnerability has been addressed in Electron versions 39.8.9, 40.9.2, 41.2.2, and 42.0.0-beta.4.
Electron applications use Context Isolation as a primary security control to isolate privileged script execution environments from untrusted web contents. The contextBridge module serves as the primary secure channel that facilitates structured data transfer across this context boundary. Under normal operating conditions, this bridge creates proxies or clean copies of objects to prevent the renderer from accessing internal Node.js execution properties.\n\nThis vulnerability, tracked as CVE-2026-70610, is a prototype pollution flaw residing within this boundary-crossing serialization mechanism. If a preload script accepts custom object parameters from the untrusted main world, an attacker can manipulate the property transfer sequence to alter the prototype of objects created in the privileged script context.\n\nBy manipulating the prototype of these cloned structures, an attacker can bypass the context isolation boundary entirely. Under specific application-level configurations, this can lead to arbitrary code execution or privileges escalation within the context of the running desktop application.
The core of the issue lies in the C++ layer of Electron's renderer API, specifically within the CreateProxyForAPI function in shell/renderer/api/electron_api_context_bridge.cc. This function executes the serialization and deserialization of objects that traverse the bridge between isolated V8 contexts.\n\nTo copy an object across the boundary, the previous implementation traversed the source object properties and wrote them to a newly created target object using the standard v8::Object::Set function. In V8, invoking Set triggers standard ECMAScript [[Set]] semantics, which aligns with standard property assignment.\n\nBecause the target proxy object is initially empty, it inherits properties from Object.prototype, including the default proto accessor. When the parser attempts to copy a property named proto, the engine traverses the prototype chain, detects the accessor setter on Object.prototype, and executes it. This dynamic modification redirects the internal [[Prototype]] link of the target object to an attacker-controlled reference, establishing a prototype pollution state in the privileged context.
To resolve the vulnerability, the Electron development team updated the property assignment mechanism to bypass prototype setters. The following code block illustrates the exact modifications made in the C++ backend:\n\ncpp\n// Before Patch\n// proxy.Set(key, passed_value.ToLocalChecked());\n\n// After Patch\nv8::Local<v8::Value> proxied_value = passed_value.ToLocalChecked();\nif (key->IsName()) {\n // Bypasses prototype setter by defining property directly\n std::ignore = proxy.GetHandle()->CreateDataProperty(\n destination_context, key.As<v8::Name>(), proxied_value);\n} else {\n // Handles numeric keys directly\n std::ignore = proxy.GetHandle()->CreateDataProperty(\n destination_context, key.As<v8::Uint32>()->Value(),\n proxied_value);\n}\n\n\nBy swapping v8::Object::Set with v8::Object::CreateDataProperty, the engine transitions from [[Set]] semantics to [[DefineOwnProperty]] semantics. This prevents the V8 engine from traversing the prototype chain and invoking the inherited proto setter on Object.prototype.\n\nThe patch is highly complete because it restricts the assignment to the object's own direct properties. No variant attacks targeting alternative setter-based properties can trigger prototype mutations on the newly allocated proxy object, as the property definition operations are strictly non-recursive and localized.
Exploitation requires the application's preload script to expose an API through contextBridge that accepts object-type arguments from the untrusted renderer process. The attacker must execute JavaScript in the renderer context, which can occur via a Cross-Site Scripting vulnerability or by loading untrusted remote content.\n\nThe attacker defines an object with a custom proto property configured via Object.defineProperty to ensure it is enumerable. When passed through the bridge, the serialization logic copies this descriptor, invoking the setter on the destination side.\n\nOnce the prototype chain of the object in the privileged context is polluted, any subsequent property lookup on that object will fall back to the attacker-defined prototype. If the preload script relies on dynamic configurations, helper methods, or optional callbacks, the attacker can redirect control flow or execute malicious scripts inside the node context.\n\nmermaid\ngraph LR\n Renderer["Renderer (Untrusted)"] -- "Sends payload with custom __proto__" --> Bridge["contextBridge (C++ Binding)"]\n Bridge -- "Invokes standard [[Set]]" --> V8Engine["V8 Engine (Privileged Context)"]\n V8Engine -- "Triggers prototype setter" --> PollutedObject["Polluted Object in Preload"]\n PollutedObject -- "Unsafe Property Access" --> RCE["Execution / Privilege Escalation"]\n
The security implications of CVE-2026-70610 are severe for applications that expose flexible, object-based APIs to untrusted content. Although the CVSS score is rated as 5.4 due to the high attack complexity, the actual operational impact can reach arbitrary code execution on the underlying host operating system.\n\nBecause the preload script has access to Node.js APIs or high-privilege IPC channels, polluting objects within its context allows an attacker to manipulate parameters passed to functions like child_process.exec or fs.writeFile.\n\nThe vulnerability represents a direct breach of the primary security boundary in Electron. Since the scope is 'Changed', the vulnerability actively bridges the gap between sandboxed web content and the node execution environment, rendering standard sandbox protections ineffective if the API surface is poorly designed.
Immediate remediation requires upgrading the Electron dependency to a patched version. Developers must verify that their applications utilize Electron versions 39.8.9, 40.9.2, 41.2.2, or 42.0.0-beta.4 depending on their current release line.\n\nFor legacy applications where runtime upgrades are blocked by compatibility constraints, developers should implement application-level filtering. Preload APIs must be modified to accept flat structures or primitive values rather than raw nested objects.\n\nAdditionally, all preload scripts should adopt defensive coding practices. Rather than performing direct property lookups on client-controlled objects, developers should utilize Object.prototype.hasOwnProperty.call() or sanitize objects by recreating them with a null prototype before executing downstream logic.
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:L/I:L/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
Electron Electron | < 39.8.9 | 39.8.9 |
Electron Electron | >= 40.0.0-alpha.1, < 40.9.2 | 40.9.2 |
Electron Electron | >= 41.0.0-alpha.1, < 41.2.2 | 41.2.2 |
Electron Electron | >= 42.0.0-alpha.1, < 42.0.0-beta.4 | 42.0.0-beta.4 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-1321 |
| Attack Vector | Network |
| Attack Complexity | High |
| CVSS Score | 5.4 (Medium) |
| Exploit Status | PoC Available |
| CISA KEV Status | Not Listed |
| Impact | Security Boundary Bypass (Context Isolation Bypass) |
The application receives input from an untrusted source and modifies attributes of a prototype of an object, which can lead to modification of attributes of all objects that inherit from that prototype.
CVE-2026-107387 is a high-impact uncontrolled memory allocation vulnerability in music-metadata, a widely used Node.js metadata parser. The flaw occurs in the APEv2 tag parser, where the library reads an attacker-controlled 32-bit integer indicating the tag size and immediately requests a corresponding heap buffer reservation. Because this allocation occurs before validating if the input stream actually contains those bytes, an attacker can supply a minuscule audio file to trigger large, disproportionate allocations, resulting in heap exhaustion and an uncatchable process-wide Out of Memory (OOM) crash.
An input validation vulnerability exists in music-metadata versions prior to 11.16.0, where parsing a crafted MP4 file containing a sample-description (stsd) box with a zero-value size entry causes a synchronous infinite loop and memory exhaustion, resulting in complete Denial of Service.
A path traversal vulnerability in datamodel-code-generator allows remote attackers to write or overwrite arbitrary files on the local host filesystem via a manipulated Protobuf schema containing malicious weak import paths.
PraisonAI is vulnerable to an arbitrary local file read vulnerability prior to version 4.6.78. The flaw is in the ContextGatherer component, where validation checks are executed only after files are parsed and appended to the context bundle, bypassing security constraints.
An algorithmic complexity vulnerability (CWE-770) in the Excelize library allows remote attackers to cause resource exhaustion (100% CPU usage) via a crafted Microsoft Excel spreadsheet. This occurs because the look-ahead row index parsing in Rows.Columns() fails to enforce upper boundary limits, enabling an out-of-bounds row index to trigger an infinite seek loop inside the Rows iterator.
An unauthenticated Server-Side Request Forgery (SSRF) vulnerability exists in Ghost CMS from version 6.54.1 to 6.65.0. The vulnerability stems from a validation bypass in the favicon resolution logic within the bookmark-fetching subsystem, which allows remote, unauthenticated attackers to trigger arbitrary HTTP requests to the local host and internal networks. This bypass circumvents the custom DNS-level IP blocklist controls configured globally in the application.