[27] PerformanceEventTiming UA-shadow-DOM leak
Rated Low because the diff fixes a UA-shadow-DOM encapsulation leak in
PerformanceEventTiming.target: when no author listener was registered, the entry stored an un-retargeted node from inside<input>'s shadow tree, giving script a reference to internal implementation nodes — information disclosure, no memory primitive.
Source/WebCore/page/LocalDOMWindow.cpp
Failure to apply the spec-required shadow-DOM retargeting step when recording a node reference on a Performance API entry.
The bug's trigger condition — "no event listener of this type" — is a useful pattern reminder: code paths that only run when nothing else has observed the event are exactly where state normally sanitized by event dispatch may remain raw. Trigger: register a PerformanceObserver for event with a low durationThreshold, ensure one event's processing is slow (the test busy-waits in a click handler) so sibling pointerup/mouseup entries — which have no author listener — exceed the threshold. Read entry.target.getRootNode() and observe the UA shadow root.
This vulnerability weakens the UA shadow DOM encapsulation boundary browsers rely on to hide internal structure of built-in form controls from web content.
Audit directions
- Performance/observer APIs capturing DOM node references outside normal event dispatch. Audit every site in WebCore that writes a
Node*/EventTarget*into aPerformance*Entry; verify each routes throughDocument::retargetToScope. Start withLargestContentfulPaint,Element Timing,PerformanceLongAnimationFrameTiming. - Code paths only executing when no author listener is registered. Grep for
hasEventListeners,hasCapturingEventListenersearly-returns and verify captured node references have been retargeted. - Other callers of
Document::retargetToScope/Node::retargetTo*. Confirm consistent usage everywhere a shadow-root node could leak.