← WebKit — 2026-W38
71e6e852300a5fd4bef4fec1e59f7f0a3f85846a Forged IsPlayingMediaDidChange activates the display-capture process capability without user consent
severity medium
class AuthorizationError
confidence 0.6
signal score 7.07
Source/WebKit/UIProcess
patch-now
Primitive: display-capture sandbox capability activated/retained without user authorization
Triage note: shouldActivate/shouldDeactivateDisplayCaptureCapability now gate on a new hasDisplayCaptureAuthorization() (m_isPromptingForDisplayCapture || m_hasGrantedDisplayCapture), which is set in willStartCapture and reset in didCommitLoadForFrame/resetState/stopMediaCapture; previously the display-capture extension capability could be activated from mediaState alone and lingered across navigation without the user having authorized screen capture.
Triage note: shouldActivate/shouldDeactivateDisplayCaptureCapability now gate on a new hasDisplayCaptureAuthorization() (m_isPromptingForDisplayCapture || m_hasGrantedDisplayCapture), which is set in willStartCapture and reset in didCommitLoadForFrame/resetState/stopMediaCapture; previously the display-capture extension capability could be activated from mediaState alone and lingered across navigation without the user having authorized screen capture.
Structural signals: smartptr_member_added (+4.87), null_guard (+1.2), msg_soft (+1.0)
Commit message
Forged IsPlayingMediaDidChange activates the display-capture process capability without user consent
https://bugs.webkit.org/show_bug.cgi?id=323828
rdar://178652280
Reviewed by Jean-Yves Avenard.
internals().mediaState is stored verbatim from WebContent IPC, but shouldActivateDisplayCaptureCapability()
used it to drive a privileged action: a compromised WebContent process could set display-capture bits and
have the UI process grant BEProcessCapability screenCapture back to it and to the GPU process, with no
getDisplayMedia() prompt. Both HasActiveScreenCaptureDevice and the IsPromptingFor*Capture bits reach the
predicate and both are forgeable.
Gate activation on a UI-process authorization record instead. m_isPromptingForDisplayCapture is set in
setIsPromptingForGetDisplayMedia, reachable only from UserMediaPermissionRequestProxyCocoa;
m_hasGrantedDisplayCapture is set in willStartCapture's DisplayMedia case, the chokepoint both grantRequest
paths funnel through, and cleared on main-frame didCommitLoadForFrame, resetState, and stopMediaCapture for
Display or EveryKind. hasDisplayCaptureAuthorization() gates both shouldActivate and shouldDeactivate, so
losing authorization revokes an active capability rather than only declining a new one.
Not a MESSAGE_CHECK: an in-flight message still carrying display-capture bits after the UI process resets
access or navigates would terminate a legitimate WebContent process. Gating activation is fail-safe and
sits where the harm occurs.
Also remove ASSERT(userMediaPermissionRequestManager) from updatePlayingMediaDidChange, which forged
capture bits make reachable from WebContent IPC; the null check below it already handles the case.
Test: Tools/TestWebKitAPI/Tests/WebKit/WKWebView/DisplayCaptureCapability.mm
* Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivateForTesting.h:
* Source/WebKit/UIProcess/API/Cocoa/WKWebViewTesting.mm:
(-[WKWebView _isDisplayCaptureCapabilityActiveForTesting]):
* Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm:
(WebKit::WebPageProxy::hasDisplayCaptureAuthorization const):
(WebKit::WebPageProxy::shouldActivateDisplayCaptureCapability const):
(WebKit::WebPageProxy::shouldDeactivateDisplayCaptureCapability const):
* Source/WebKit/UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::didCommitLoadForFrame):
(WebKit::WebPageProxy::stopMediaCapture):
(WebKit::WebPageProxy::resetState):
(WebKit::WebPageProxy::willStartCapture):
(WebKit::WebPageProxy::setIsPromptingForGetDisplayMedia):
(WebKit::WebPageProxy::updatePlayingMediaDidChange):
* Source/WebKit/UIProcess/WebPageProxy.h:
* Source/WebKit/UIProcess/WebPageProxyTesting.cpp:
(WebKit::WebPageProxyTesting::isDisplayCaptureCapabilityActive const):
* Source/WebKit/UIProcess/WebPageProxyTesting.h:
* Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* Tools/TestWebKitAPI/Tests/WebKit/WKWebView/DisplayCaptureCapability.mm: Added.
(TestWebKitAPI::TEST(DisplayCaptureCapability, IgnoresForgedDisplayCaptureMediaState)):
Identifier: 316606.740@safari-7625-branch
Before / after
Loading diff…
On This Page