Introduction
A use-after-free in Electron's asynchronous permission request handling means that a desktop application built on the framework could crash or suffer memory corruption because a frame navigated away at the wrong moment. Electron powers applications like Slack, Discord, Visual Studio Code, and 1Password, so the blast radius of CVE-2026-34771 extends across millions of endpoints in enterprise and consumer environments.
The vulnerability, scored CVSS 7.5 (High), affects the interaction between session.setPermissionRequestHandler() and three permission types: fullscreen, pointer lock, and keyboard lock. Applications whose handlers respond synchronously, or that do not register a handler at all, are unaffected. Everyone else needs to upgrade Electron or restructure how they invoke permission callbacks.
Technical information
Root cause
The bug is in how Electron's session API manages the lifetime of permission request callbacks. When a developer registers an asynchronous handler via ses.setPermissionRequestHandler(handler), Electron stores a callback reference tied to the requesting WebContents frame for each incoming permission request. For fullscreen, pointerLock, and keyboardLock permissions, these requests typically come from the main frame.
This is a classic dangling pointer. When one of these permission requests is made, Electron's C++ layer creates native objects associated with the requesting RenderFrameHost and stores a raw pointer in the callback closure. If the requesting frame navigates to a new URL, or the parent BrowserWindow closes before the application resolves the callback (by calling callback(true) or callback(false)), the C++ objects for the frame and window are destroyed and their memory is freed. The stored callback still holds the stale pointer. When the application eventually invokes the callback, it dereferences freed memory. That is a use-after-free, classified as CWE-416.
CVSS breakdown
The CVSS v3.1 metrics, and what each one means in practice:
| Metric | Value | Operational implication |
|---|---|---|
| Base Score | 7.5 (High) | Requires prioritized remediation |
| Attack Vector | Network | Can be initiated remotely via malicious web content loaded into the Electron app |
| Attack Complexity | High | Attacker must win a race condition between frame navigation and callback execution |
| Privileges Required | None | No prior authentication needed to trigger the permission request |
| User Interaction | Required | User must interact with the application to trigger the permission flow or navigation |
| Impact (C/I/A) | High / High / High | Successful exploitation could lead to total compromise of confidentiality, integrity, and availability |
Attack flow
An attack would follow a sequence like this:
-
The attacker crafts web content that a vulnerable Electron application loads. Any mechanism the application uses to render remote or semi-trusted content could serve as the delivery path.
-
The malicious content requests one of the three affected permissions (fullscreen, pointer lock, or keyboard lock). The application's asynchronous
setPermissionRequestHandlerfires, and Electron stores a callback that references the requesting frame's native objects. -
Before the application resolves the callback, the attacker forces the requesting frame to navigate away, for example by redirecting it to a new URL. The underlying C++ objects are destroyed, but the callback reference persists.
-
When the application invokes the stored callback to grant or deny the permission, it dereferences the dangling pointer. Depending on the state of the heap, the result is a crash or potentially exploitable memory corruption.
The High attack complexity rating comes from this race. Whether exploitation succeeds depends on the timing window between the permission request and the callback resolution.
Patch information
The Electron team fixed CVE-2026-34771 in a coordinated security release that patched every supported release branch. The fix was published under GitHub Security Advisory GHSA-8337-3p73-46f4. Patched versions reached npm between March 3 and March 10, 2026, approximately three weeks before the advisory was formally disclosed on April 2, 2026. The gap is deliberate Electron practice. The project ships security fixes silently in minor and patch releases, which gives downstream consumers time to upgrade before vulnerability details become public.
The four patched versions cover every currently supported Electron branch:
| Branch | Patched version | Release date |
|---|---|---|
| 38.x (end of support) | 38.8.6 | ~March 10, 2026 |
| 39.x | 39.8.0 | ~March 3, 2026 |
| 40.x | 40.7.0 | ~March 3, 2026 |
| 41.x (beta) | 41.0.0-beta.8 | ~March 5, 2026 |
None of the public release changelogs for these versions explicitly lists the security fix. The v38.8.6 release notes, for example, list fixes for protocol validation (PR #50157), header character rejection (PR #50130), and permission handler origin correction (PR #50151), but say nothing about the use-after-free. Electron commonly leaves security patches out of its changelogs on purpose, so reading changelogs is not enough for security tracking. Teams should monitor the GitHub Advisory Database and OSV feeds directly.
How the fix works
The patch adds proper object lifetime tracking to the permission request callback path. Callbacks for fullscreen, pointer lock, and keyboard lock permissions are invalidated, or turned into safe no-ops, when the associated frame navigates or the window is destroyed. The mechanism is likely a weak reference to the requesting RenderFrameHost (such as a base::WeakPtr in Chromium's C++ layer) bound to the callback. A callback invoked after the frame is gone would then detect the invalidation instead of dereferencing freed memory. This mirrors patterns already used elsewhere in Chromium's permission infrastructure and in earlier Electron fixes for similar callback lifetime issues, such as PR #45267, which fixed a comparable dangling reference in file permission callbacks by removing consumed callbacks from an internal map.
Batch context
This CVE shipped alongside a batch of other security fixes: CVE-2026-34770 (PowerMonitor UAF), CVE-2026-34772 (download dialog callback UAF), CVE-2026-34774 (offscreen child window UAF), and CVE-2026-34777 (incorrect permission handler origin for iframes). All five share the same fixed versions, which suggests a systematic internal audit of callback lifetime safety across Electron's native layer.
Interim workarounds
For applications that cannot update immediately, the vendor provides two official workarounds:
-
Change the
session.setPermissionRequestHandler()implementation so it responds to all permission requests synchronously. -
If other permissions need an asynchronous flow, explicitly deny
fullscreen,pointer-lock, andkeyboard-lockrequests synchronously, then handle the remaining requests asynchronously.
Affected systems and versions
The affected ranges cover every Electron version from 0.x up to the latest releases:
- All versions before 38.8.6 (every 38.x release before 38.8.6, plus all prior major versions)
- 39.0.0-alpha.1 through 39.7.x
- 40.0.0-alpha.1 through 40.6.x
- 41.0.0-alpha.1 through 41.0.0-beta.7
Only applications that register an asynchronous session.setPermissionRequestHandler() and handle fullscreen, pointer-lock, or keyboard-lock permission requests are vulnerable. Applications that do not set a permission request handler, or whose handler responds synchronously, are not affected.
Fixed versions:
- 38.8.6
- 39.8.0
- 40.7.0
- 41.0.0-beta.8
Vendor security history
Electron is maintained under the OpenJS Foundation and has a formal security policy, with coordinated disclosure through the GitHub Security Advisory platform. The project has a track record of fixing memory safety issues in its native layer. The simultaneous release of five CVEs in this batch (CVE-2026-34770, CVE-2026-34771, CVE-2026-34772, CVE-2026-34774, CVE-2026-34777) indicates the team ran a broader audit of callback lifetime safety across the codebase. Earlier fixes, such as PR #45267 for a dangling reference in file permission callbacks, show that this class of bug keeps recurring in Electron's C++ and Chromium integration layer.
Electron silently ships security fixes in regular releases before public disclosure, on purpose, to give downstream consumers the longest possible upgrade window. That helps defenders, but organizations that rely only on changelog monitoring will miss critical security updates.
References
- GitHub Security Advisory GHSA-8337-3p73-46f4
- NVD Entry for CVE-2026-34771
- OSV Vulnerability Record
- PT Security Vulnerability Database
- Electron v38.8.6 Release Notes
- Electron v39.8.0 Release Notes
- Electron v40.7.0 Release Notes
- Electron v41.0.0-beta.8 Release Notes
- Feedly CVE Tracker
- GitHub Advisory Database Entry
- Electron session API Documentation
- Electron Official Site
- Electron on Wikipedia
- OpenJS Foundation Security
- Electron Security Overview on GitHub



