← Chrome — 2026-W34

9d149ff313cfee6551259d37328823105eda2fb6  [M151] [FedCM] Fix UAF when double clicking user other account

severity high class UAF CVSS 7.5 signal score 13.87 content/browser/ patch-now AI review CONFIRMED
Structural signals: smartptr_member_added (+6.47), null_guard (+1.2), uaf_lifetime (+2.2), msg_strong (+3.0), area:content/browser/ (+1.0)

The bug at a glance

A re-entrant use-after-free of the AccountsFetcher in the privileged browser process is reachable from ordinary web content that invokes a FedCM dialog, gated only by a double-click on ‘Use a different account’; browser-process UAFs are high severity even with user interaction.

A malicious or colluding IdP page can race the FedCM accounts fetch so that re-clicking ‘Use a different account’ re-registers the Request as a sign-in-status observer, triggering a synchronous callback that frees the object currently executing, giving an attacker a controllable UAF in the browser process.

Root cause

Request::LoginToIdP registered Request as an IdpSigninStatusObserver and opened the IdP login popup. Clicking ‘Use a different account’ a second time while the accounts fetch was still in flight re-registered Request as an observer; when the pending response arrived, UpdateIdpSigninStatusForAccountsEndpointResponse synchronously notified observers, so Request kicked off a new accounts fetch that deleted the current AccountsFetcher while it was still running inside OnAccountsResponseReceived. The fix skips re-registration when the login popup is already open and adds a WeakPtr guard so OnAccountsResponseReceived returns safely if the fetcher is destroyed during the synchronous status update.

Key code

WeakPtr guard across the synchronous sign-in-status update that can delete the fetcher

base::WeakPtr<AccountsFetcher> weak_this = weak_ptr_factory_.GetWeakPtr();
  webid::UpdateIdpSigninStatusForAccountsEndpointResponse(
      idp_config_url, status, idp_info->has_failing_idp_signin_status,
      permission_delegate_);
  if (!weak_this) {
    return;
  }

Patch walkthrough

  • content/browser/webid/accounts_fetcher.cc — Captures a WeakPtr before UpdateIdpSigninStatusForAccountsEndpointResponse (which synchronously notifies observers and can delete the AccountsFetcher) and bails out if the object was destroyed, preventing the use-after-free on the rest of OnAccountsResponseReceived.
  • content/browser/webid/request.cc — When LoginToIdP runs while dialog_type_ is already kLoginToIdpPopup it now re-shows (refocuses) the modal and returns early instead of calling AddIdpSigninStatusObserver again, removing the duplicate observer registration that created the re-entrant fetch; also reworks the DialogType UMA/devtools-close logic to only fire on an actual dialog-type change.
  • content/browser/webid/request_unittest.cc — Adds a regression test asserting that a second LoginToIdP while the popup is open refocuses without re-registering the observer (AddIdpSigninStatusObserver called exactly once) and preserves query parameters.

Background

FedCM — Federated Credential Management is a browser API that mediates federated sign-in between a relying party and an identity provider (IdP) via browser-drawn account-chooser dialogs.

IdpSigninStatusObserver — Observer interface notified when an IdP’s stored sign-in status changes, used to re-fetch accounts after the user logs into the IdP popup.

AccountsFetcher — Browser-side helper that fetches the IdP accounts endpoint and reports results via OnAccountsResponseReceived.

Vulnerability window

  1. Reachability — Reachable from ordinary web content in a stock build: a page using the FedCM API displays the account chooser and the user clicks ‘Use a different account’.
  2. Trigger — The user refocuses the dialog and double-clicks ‘Use a different account’ again while the accounts fetch is still in flight, re-registering Request as an observer.
  3. Primitive — The arriving accounts response synchronously updates sign-in status, which notifies the re-registered observer and starts a new fetch that frees the AccountsFetcher mid-callback, yielding a use-after-free in the browser process.
  4. Escalation — Shaping the freed AccountsFetcher allocation could turn the UAF into read/write of attacker-influenced memory in the browser process (inferred).

Proof of concept

Conceptually: an IdP/relying-party page invokes FedCM, the account chooser is shown, the user clicks ‘Use a different account’ to open the login popup, then clicks it again before the queued accounts fetch completes; the second click re-arms the observer so the completing fetch re-enters and destroys the live fetcher. No working exploit is provided.

Exploitation

  1. Setup — Serve a FedCM-enabled relying party plus an IdP whose accounts endpoint response can be delayed to widen the race window (inferred).
  2. Trigger — Induce the double-click on ‘Use a different account’ (social engineering or scripted focus/timing) so the second LoginToIdP re-registers the observer.
  3. Groom — Reclaim the freed AccountsFetcher with controlled data before the dangling use completes (inferred).

Detection & hunting

For defenders and detection engineers:

  • weggli: observer re-registration without an already-open/already-registered guard (e.g. AddIdpSigninStatusObserver called in a path that can run twice) — Audit FedCM Request paths that register observers for idempotency when the popup/dialog is already open.
  • grep for synchronous observer-notification calls (UpdateIdpSigninStatus) not followed by a WeakPtr/this-liveness check* — Flag methods that call synchronous notifiers and then keep touching member state without re-validating the object.

Audit directions

  • content/browser/webid/ — Review every synchronous callback that can re-enter and delete AccountsFetcher/Request (OnAccountsResponseReceived and siblings) for missing WeakPtr guards.
  • Observer-registration sites across FedCM — Look for user-repeatable actions (dialog buttons) that register observers without checking existing state, enabling duplicate registration and re-entrancy.

Before / after

Loading diff…