CVE-2025-43511
Overview
Background
- Web Inspector agent
- Backend objects (here InspectorAnimationAgent) that service the inspector frontend’s protocol domains and hold references to inspected page objects.
- Raw pointer vs WeakRef
- A raw T* is not lifetime-aware and dangles when the object dies; a WeakRef auto-nulls, so lookups can detect a dead object.
- WebAnimation / scriptExecutionContext
- A Web Animations object bound to a document/worker context that can become detached (context null) during teardown or navigation.
- Detached animation
- An animation whose scriptExecutionContext has gone away, so its global object is unavailable.
Root Cause Analysis
The Web Inspector animation agent tracked live animations in m_animationIdMap, a map from an inspector animation-id string to a raw WebAnimation*. Nothing kept those pointers in sync with object lifetime: when a WebAnimation was destroyed, its entry remained as a dangling raw pointer. Subsequent agent operations dereferenced it — findAnimationId compared each stored raw pointer to a live animation, and resolveAnimation did animation->protectedScriptExecutionContext()->globalObject() — yielding a use-after-free. resolveAnimation had a second defect: protectedScriptExecutionContext() can return null for an animation detached from its context, and the code dereferenced it unconditionally (a null/недействительный access).
The fix changes m_animationIdMap to hold WeakRef<WebAnimation> values (which automatically drop when the animation dies, so lookups never see a stale pointer — findAnimationId now compares existingAnimation.ptr()), and bindAnimation stores the animation by weak reference. resolveAnimation now takes RefPtr scriptExecutionContext = animation->scriptExecutionContext() and returns an error (‘Animation is detached from context’) when it is null instead of dereferencing it.
The restored invariant is that the inspector’s animation table observes animations weakly and validates liveness/context before use. This path is only reachable while a Web Inspector session is attached and driving the Animation domain.
Attack Path
- Attach the inspector An active Web Inspector session enables the Animation agent, which binds animations into m_animationIdMap by raw pointer.
- Create and destroy an animation Page script creates a Web Animation that the agent binds, then drops all references so the WebAnimation is collected, leaving a dangling raw pointer in the map.
- Trigger a lookup Invoke an agent operation (resolve/findAnimationId) that iterates or dereferences the stored pointer, or resolve an animation whose scriptExecutionContext is null.
- Use-after-free / null deref The agent dereferences the freed WebAnimation (or the null context), crashing or corrupting memory in WebContent.
Impact Assessment
Changed Functions
| Function | Change | Notes |
|---|---|---|
InspectorAnimationAgent::resolveAnimationSource/WebCore/inspector/agents/InspectorAnimationAgent.cpp |
modified | Takes scriptExecutionContext() into a RefPtr and returns an error when null instead of calling protectedScriptExecutionContext()->globalObject() unconditionally. |
InspectorAnimationAgent::findAnimationIdSource/WebCore/inspector/agents/InspectorAnimationAgent.cpp |
modified | Compares existingAnimation.ptr() now that map values are WeakRef rather than raw pointers. |
InspectorAnimationAgent::bindAnimationSource/WebCore/inspector/agents/InspectorAnimationAgent.cpp |
modified | Stores the animation as a weak reference (m_animationIdMap.set(id, animation)) instead of &animation. |
m_animationIdMapSource/WebCore/inspector/agents/InspectorAnimationAgent.h |
modified | Changed from a map to WebAnimation* to a HashMap of WeakRef<WebAnimation, WeakPtrImplWithEventTargetData>, so entries auto-drop on destruction. |
Files Changed
Source/WebCore/inspector/agents/InspectorAnimationAgent.cppSource/WebCore/inspector/agents/InspectorAnimationAgent.h
Audit Directions
- Other raw-pointer maps in inspector agentsgrep Source/WebCore/inspector/agents for HashMap/Vector values typed as bare
*(e.g. Node*, WebAnimation*) that outlive the pointee; prefer WeakRef/WeakHashMap. - Unchecked protected*() dereferencesgrep for protectedScriptExecutionContext()-> and similar protected accessors dereferenced without a null check across WebCore.
- Other id-to-object registriesAudit inspector domains (DOM, Canvas, Animation) that map protocol ids to engine objects for the same raw-pointer lifetime gap.