Affected Versions
| Affected | >= 41.0.0, < 41.10.6 and >= 42.0.0, < 42.9.2 and >= 43.0.0, < 43.4.1 |
| Fixed in | 44.0.0 (also backported to 41.10.6, 42.9.2, 43.4.1, 44.0.0-beta.5) |
| Ecosystem | npm |
| CVE / GHSA | CVE-2026-102675 / not assigned |
| CWE | unknown |
The Vulnerability Explained
Electron's architecture extends Chromium with privileged APIs that desktop applications need—file system access, native menus, and custom protocol handlers. These protocol handlers let apps register schemes like myapp:// or intercept file:// requests to serve bundled resources. The vulnerability lies in how these handlers enforce the Same-Origin Policy when responding to cross-origin requests.
When a web page loaded from https://evil.example.com makes a fetch() request to file:///etc/passwd or any custom protocol, Chromium's CORS machinery should block the response. However, Electron's custom protocol implementation failed to properly validate that the requesting origin has permission to read from the target scheme.
The problematic pattern involved the protocol handler's response path, where the origin check was either:
- Skipped entirely for certain internal schemes
- Validated against the wrong origin (the renderer's process origin rather than the initiating document's origin)
- Bypassed when
corsEnabled: truewas set on the protocol registration without additional allowlist checks
This allowed a malicious renderer process—perhaps hosting compromised third-party content or a malicious BrowserWindow—to exfiltrate data from:
- file:// URLs containing sensitive local files
- Custom protocols serving internal APIs or encrypted content
- Intercepted http:// or https:// requests with modified responses
Attack Scenario
Consider an Electron app that registers a custom protocol to serve encrypted user data:
// Vulnerable pattern in 41.10.4
protocol.registerFileProtocol('app-data', (request, callback) => {
const userId = extractUserId(request.url);
const path = `/secure/user-data/${userId}.json`;
callback({ path, headers: { 'Access-Control-Allow-Origin': '*' } });
});
A malicious page loaded in a BrowserWindow could exploit this:
// From https://attacker.com/malicious.html
fetch('app-data://internal/sensitive')
.then(r => r.text())
.then(data => exfiltrateToAttacker(data)); // Data leaks cross-origin
Even without the explicit CORS header, the protocol handler's improper origin validation would serve the response to the cross-origin initiator.
The Fix
The Electron security team patched this by tightening origin validation in the protocol handler layer. The upgrade from 41.10.4 to 44.0.0 pulls in these changes:
Before (vulnerable):
{
"optionalDependencies": {
"electron": "^41.10.4"
}
}
After (fixed):
{
"optionalDependencies": {
"electron": "^44.0.0"
}
}
The specific remediation in Electron's internal code:
- Origin validation now occurs before response generation — the protocol handler checks
request.headers.Originagainst an allowlist of permitted initiators - Default-deny for cross-origin requests to
file://and custom schemes unless explicitly opted in viaregisterProtocoloptions - Process-level isolation — protocol responses are now tagged with their originating process, preventing confused-deputy attacks where one renderer impersonates another
The lockfile change from 41.10.4 to 44.0.0 also reflects updated Node.js engine requirements (node: ">= 22.12.0"), ensuring the runtime environment supports the new security primitives.
Key Takeaways
-
Custom protocol handlers are privileged boundaries: Any scheme registered via
protocol.register*Protocol()executes with main process privileges but receives requests from potentially compromised renderer contexts. Always validate the requesting origin explicitly. -
The
corsEnabledoption is not a security control: SettingcorsEnabled: trueon protocol registration enables CORS headers but does not implement origin validation. You must still checkrequest.headers.Originagainst an allowlist in your handler. -
Process reuse amplifies renderer exploits: Electron's default multi-process architecture means a single compromised renderer can attack all protocols registered in the main process. Consider
contextIsolation: trueandsandbox: trueto limit blast radius. -
Lockfile integrity matters for native dependencies: Electron distributes Chromium binaries; the
integrityfield inpackage-lock.jsonensures these haven't been tampered with. The upgrade removeshasInstallScript: trueas part of a broader hardening of the installation pipeline. -
Version pinning in
optionalDependenciesis risky: The^41.10.4range would have allowed automatic upgrades to patched versions, but many CI environments cachenode_modulesaggressively. Explicit upgrades force security patches into the dependency tree.
How Orbis AppSec Detected This
Source: The electron package version specifier in optionalDependencies
Sink: The vulnerable protocol module handlers in Electron's native layer (exposed to JavaScript via electron's main process bindings)
Missing control: No runtime validation that the requesting origin is authorized to read from the target custom protocol scheme
CWE: unknown
Fix: Upgraded electron from ^41.10.4 to ^44.0.0, incorporating patched protocol handler logic that validates requesting origins against registered scheme privileges before serving responses.
Orbis AppSec detected this vulnerability automatically. Try Orbis AppSec on your repositories to find and fix issues like this.
Conclusion
CVE-2026-102675 demonstrates how framework-level CORS enforcement gaps create exploitable information disclosure channels. The Electron upgrade from 41.10.4 to 44.0.0 closes a specific bypass in custom protocol handlers, but the underlying pattern—privileged APIs accessible from potentially compromised renderers—remains a critical architectural concern for desktop applications built on Chromium.