Medium CVSS 8.8 webkit UAF 🔧 Commit mapped

Overview

Medium
Severity
8.8
CVSS
No
Exploited ITW
Fixed
Fix Status
DescriptionProcessing maliciously crafted web content may lead to an unexpected process crash
ComponentWebCore Inspector
Bug ClassUAF
Tracker310880
Fix commit5233199dcb0c (WebKit/WebKit) +8/-6
CWECWE-119, CWE-120 (Buffer bounds error, Buffer overflow)
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
CISA KEVNot listed
Creditedwac and Kookhwan Lee working with TrendAI Zero Day Initiative
Disclosed2026-05-11

Background

Style resolver
WebCore::Style::Resolver computes matched CSS rules for elements; it is owned by a Style::Scope and can be torn down on style recalc.
Bare reference vs Ref<>
auto& x = obj.styleResolver() aliases without owning, so it dangles if the resolver is destroyed; Ref<> holds a strong reference.
Inspector CSS agent
The backend that answers Web Inspector CSS-domain requests such as matched-rule queries for an element.
Ancestor rule walk
Matched-rule computation iterates an element’s ancestors, each with its own style resolver, any of which can be invalidated during the walk.

Root Cause Analysis

The Web Inspector CSS agent (InspectorCSSAgent) computed matched CSS rules for an element and its ancestors, and it held the element’s style resolver in a bare reference: auto& styleResolver = element->styleResolver();. It then used that reference across operations that can run style resolution and walk/mutate the render tree – pseudoStyleRulesForElement for the element and each pseudo-element, and a loop over ancestorsOfType<Element> calling ancestor.styleResolver() and styleRulesForElement. A style resolver is owned by its Style::Scope and can be destroyed or replaced during style recalc / DOM changes that occur while these calls run, so the retained styleResolver& (and the ancestor& from the range-for) can dangle, and a later use is a use-after-free.

The fix retains everything it dereferences across those steps: Ref styleResolver = element->styleResolver();, Ref ancestor : ancestorsOfType<Element>(*element), and Ref parentStyleResolver = ancestor->styleResolver();, and it re-fetches the element’s style resolver freshly inside the ancestor loop rather than reusing a stale reference.

The restored invariant is that the style resolver (and each ancestor element) is kept alive for the duration of the rule-matching that uses it. This path is reached through the Web Inspector CSS domain.

Key insight
The inspector CSS agent aliased element->styleResolver() (and ancestors) by bare reference across style-resolving calls that can free it, so a style recalc mid-walk left a dangling resolver; retaining them with Ref<> fixes the lifetime.

Attack Path

  1. Attach the inspector An active Web Inspector session enables the CSS agent, which computes matched rules for a selected element via InspectorCSSAgent.
  2. Trigger rule matching Invoke the CSS domain operation that calls pseudoStyleRulesForElement and walks ancestors, holding element->styleResolver() by bare reference.
  3. Destroy the resolver mid-walk Cause a style recalc / DOM mutation (e.g. via script or a pseudo/ancestor traversal side effect) that frees or replaces the style resolver while the agent still references it.
  4. Use-after-free The agent dereferences the freed style resolver (or freed ancestor element), crashing or corrupting memory in WebContent.

Impact Assessment

A use-after-free of a style resolver (or ancestor element) held by bare reference in the inspector CSS agent, in the WebContent process. It is reachable only with an active Web Inspector CSS session, which limits exposure from a plain web page; the realistic effect is a crash, with UAF-to-corruption possible under inspector-driven timing. Rated medium.

Changed Functions

FunctionChangeNotes
InspectorCSSAgent::(matched-rules-for-element handler)
Source/WebCore/inspector/agents/InspectorCSSAgent.cpp
modified Holds the style resolver and ancestors by Ref (Ref styleResolver / Ref ancestor / Ref parentStyleResolver) and re-fetches the element's resolver inside the ancestor loop, so nothing dangles across pseudoStyleRulesForElement/styleRulesForElement.

Files Changed

  • Source/WebCore/inspector/agents/InspectorCSSAgent.cpp

Audit Directions

  • Other bare styleResolver() aliases
    grep WebCore for auto& \w+ = .*styleResolver() and other Style::Resolver& locals held across style-resolving or tree-walking calls.
  • Range-for over tree nodes
    Audit for (auto& x : ancestorsOfType/descendantsOfType(...)) loops whose body can run script or style recalc; prefer for (Ref x : ...).
  • Inspector agents holding engine refs
    Review InspectorCSS/DOM agents for bare references to resolvers, scopes, or elements retained across protocol operations.

Original Bug Report

The reporter's bug is still restricted on the tracker.