Electron CVE-2026-34771: Brief Summary of the Async Permission Handler Use After Free

A short review of CVE-2026-34771, a high severity use after free in Electron's asynchronous permission request handler affecting fullscreen, pointer lock, and keyboard lock callbacks, along with patch details and mitigation strategies.

CVE Analysis

8 min read

ZeroPath CVE Analysis
ZeroPath CVE Analysis

2026-04-03

Electron CVE-2026-34771: Brief Summary of the Async Permission Handler Use After Free
Experimental AI-Generated Content

This CVE analysis is an experimental publication that is completely AI-generated. The content may contain errors or inaccuracies and is subject to change as more information becomes available. We are continuously refining our process.

If you have feedback, questions, or notice any errors, please reach out to us.

[email protected]

Introduction

A use after free in Electron's asynchronous permission request handling means that any desktop application built on the framework could crash or suffer memory corruption simply because a frame navigated away at the wrong moment. Given that Electron powers applications like Slack, Discord, Visual Studio Code, and 1Password, the blast radius of CVE-2026-34771 extends across millions of endpoints in enterprise and consumer environments alike.

The vulnerability, scored at CVSS 7.5 (High), specifically targets 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. For everyone else, the fix requires either upgrading Electron or restructuring how permission callbacks are invoked.

Technical Information

Root Cause

The vulnerability lives in the lifecycle management of permission request callbacks within Electron's session API. 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 originate from the main frame.

The problem is a classic dangling pointer scenario. 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 if the parent BrowserWindow is closed before the application resolves the callback (by calling callback(true) or callback(false)), the underlying C++ objects for the frame and window are destroyed and their memory is freed. The stored callback, however, still holds the now stale pointer. When the application eventually invokes the callback, it dereferences freed memory, producing a use after free condition classified as CWE-416.

CVSS Breakdown

The CVSS v3.1 vector provides useful context for understanding exploitability:

MetricValueOperational Implication
Base Score7.5 (High)Requires prioritized remediation
Attack VectorNetworkCan be initiated remotely via malicious web content loaded into the Electron app
Attack ComplexityHighAttacker must win a race condition between frame navigation and callback execution
Privileges RequiredNoneNo prior authentication needed to trigger the permission request
User InteractionRequiredUser must interact with the application to trigger the permission flow or navigation
Impact (C/I/A)High / High / HighSuccessful exploitation could lead to total compromise of confidentiality, integrity, and availability

Attack Flow

An attacker looking to exploit this vulnerability would follow a sequence like this:

  1. Deliver malicious content: The attacker crafts web content that gets loaded within a vulnerable Electron application. This could happen through any mechanism the application uses to render remote or semi trusted content.

  2. Trigger a permission request: The malicious content requests one of the three affected permissions (fullscreen, pointer lock, or keyboard lock). This causes the application's asynchronous setPermissionRequestHandler to fire, storing a callback with a reference to the requesting frame's native objects.

  3. Force frame navigation: Before the application resolves the callback, the attacker forces the requesting frame to navigate away, for example by redirecting to a new URL. This destroys the underlying C++ objects while the callback reference persists.

  4. Callback invocation dereferences freed memory: When the application eventually invokes the stored callback to grant or deny the permission, it dereferences the dangling pointer. Depending on the state of the heap, this results in a crash or potentially exploitable memory corruption.

The High attack complexity rating reflects the fact that the attacker must win this race condition. The timing window between the permission request and the callback resolution determines whether exploitation succeeds.

Patch Information

The Electron team addressed CVE-2026-34771 through a coordinated security release that shipped patches across all supported release branches. The fix was published under GitHub Security Advisory GHSA-8337-3p73-46f4, with patched versions released to npm between March 3 and March 10, 2026, approximately three weeks before the advisory was formally disclosed on April 2, 2026. This staggered approach is a deliberate Electron project practice: security fixes are embedded in minor and patch releases silently, giving downstream consumers time to upgrade before vulnerability details become public.

The four patched versions span every currently supported Electron branch:

BranchPatched VersionRelease Date
38.x (end of support)38.8.6~March 10, 2026
39.x39.8.0~March 3, 2026
40.x40.7.0~March 3, 2026
41.x (beta)41.0.0-beta.8~March 5, 2026

An important operational detail: the security fix itself is not explicitly listed in any of the public release changelogs for these versions. For example, the v38.8.6 release notes enumerate fixes for protocol validation (PR #50157), header character rejection (PR #50130), and permission handler origin correction (PR #50151), but omit any reference to the use after free fix. This deliberate omission is common for Electron security patches and means that simply reading changelogs is insufficient for security tracking. Teams should monitor the GitHub Advisory Database and OSV feeds directly.

How the Fix Works

At its core, the patch adds proper object lifetime tracking to the permission request callback path. The fix ensures that callbacks for fullscreen, pointer lock, and keyboard lock permissions are invalidated or safely turned into no ops when the associated frame navigates or the window is destroyed. This likely involves binding the callback to a weak reference (such as a base::WeakPtr in Chromium's C++ layer) to the requesting RenderFrameHost, so that any attempt to invoke the callback after the frame is gone will safely detect the invalidation rather than dereferencing freed memory. This mirrors patterns already used elsewhere in Chromium's permission infrastructure and in previous Electron fixes for similar callback lifetime issues, such as PR #45267 which addressed a comparable dangling reference in file permission callbacks by removing consumed callbacks from an internal map.

Batch Context

This CVE was part of a batch of security fixes released simultaneously, including 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 share the same fixed version set, suggesting a systematic internal audit of callback lifetime safety across Electron's native layer.

Interim Workarounds

For applications that cannot be immediately updated, the vendor provides two official workarounds:

  1. Synchronous responses: Modify the session.setPermissionRequestHandler() implementation to respond to all permission requests synchronously.

  2. Selective denial: If an asynchronous flow is required for other permissions, explicitly deny fullscreen, pointer-lock, and keyboard-lock requests synchronously before processing other requests asynchronously.

Affected Systems and Versions

The affected version ranges are extensive, spanning all Electron versions from 0.x through the latest releases:

  • All versions before 38.8.6 (this includes every Electron release ever made on the 38.x branch and 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 addressing 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 conducted a broader audit of callback lifetime safety across the codebase. Prior fixes, such as PR #45267 for a dangling reference in file permission callbacks, show that this class of vulnerability has been a recurring concern in Electron's C++ and Chromium integration layer.

The Electron project's practice of silently embedding security fixes in regular releases before public disclosure is a deliberate strategy to maximize the upgrade window for downstream consumers. While this approach benefits defenders, it also means that organizations relying solely on changelog monitoring will miss critical security updates.

References

Detect & fix
what others miss

Security magnifying glass visualization