[21] postMessage extends user gesture token lifetime
Rated Medium because the diffs fix a TOCTOU on
UserGestureToken::hasExpiredinLocalDOMWindow::processPostMessage: an expiration check at one point and gesture consumption at another let wall-clock time elapse between them, so a token that was just past 1s would still be installed on theUserGestureIndicatorduringMessageEventdispatch — popup-blocker bypass.
Two commits land the same fix into different branches; one is the rapid backport of the other. processPostMessage re-checks userGestureToForward->hasExpired(maximumIntervalForUserGestureForwarding) immediately adjacent to the UserGestureIndicator construction.
Source/WebCore/page/LocalDOMWindow.cpp
TOCTOU on a time-based freshness predicate: the user-gesture expiration check and the gesture-consumption point were not co-located, allowing wall-clock time to elapse between validation and use.
The HTML/WebKit policy is that a forwarded gesture remains usable only within maximumIntervalForUserGestureForwarding (1 s) of the original interaction; before the fix that cap could be silently exceeded because the check didn't bracket consumption. The minimal patch duplicates the check; a cleaner fix would push it into UserGestureIndicator's constructor.
Time-based validity predicates on security tokens are TOCTOU-prone whenever the check and use are not co-located. A page legitimately receiving one click could chain postMessage hops to keep gesture-gated APIs (popup creation, fullscreen entry, autoplay-with-sound) reachable past the policy window.
This vulnerability weakens the user-gesture trust boundary that gates user-initiated APIs.
Audit directions
UserGestureToken::hasExpiredcallsites far from consumption. GrepSource/WebCoreforhasExpired(UserGestureToken::and inspect intervening calls; same gap may exist in fetch keepalive, beacon, navigation API forwarding (maximumIntervalForUserGestureForwardingForFetch).- Capability tokens forwarded across asynchronous boundaries. Audit MessagePort, BroadcastChannel, ServiceWorker
postMessagefor analogous gesture/transient-activation forwarding. - RAII helpers accepting tokens without re-validating freshness.
UserGestureIndicator::UserGestureIndicator(RefPtr<UserGestureToken>, ...)has nohasExpiredin the constructor — the systemic root cause this patch only treats locally. - Chained postMessage hops. Test whether A → B → C with 0 ms delay per hop can keep
processingUserGesture()returning true beyond the 1 s cap by comparing against the ORIGINALm_startTimeacross an arbitrary number of hops.