Skip to content

Commit

Permalink
Update PermissionsPolicy to match latest spec
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=273982
rdar://127848428

Reviewed by Youenn Fablet.

This patch implements some algorithms and does some refactoring/renaming in PermissionPolicy based on latest version of
spec.

* Source/WebCore/Modules/applepay/PaymentSession.cpp:
(WebCore::PaymentSession::canCreateSession):
* Source/WebCore/Modules/audiosession/DOMAudioSession.cpp:
(WebCore::DOMAudioSession::setType):
(WebCore::DOMAudioSession::type const):
(WebCore::DOMAudioSession::state const):
(WebCore::DOMAudioSession::scheduleStateChangeEvent):
* Source/WebCore/Modules/gamepad/NavigatorGamepad.cpp:
* Source/WebCore/Modules/geolocation/Geolocation.cpp:
(WebCore::Geolocation::shouldBlockGeolocationRequests):
* Source/WebCore/Modules/mediastream/MediaDevices.cpp:
(WebCore::checkCameraAccess):
(WebCore::checkMicrophoneAccess):
(WebCore::checkSpeakerAccess):
(WebCore::MediaDevices::listenForDeviceChanges):
* Source/WebCore/Modules/mediastream/UserMediaController.cpp:
(WebCore::UserMediaController::logEnumerateDevicesDenial):
* Source/WebCore/Modules/mediastream/UserMediaRequest.cpp:
(WebCore::UserMediaRequest::start):
* Source/WebCore/Modules/permissions/Permissions.cpp:
(WebCore::isAllowedByPermissionsPolicy):
* Source/WebCore/Modules/screen-wake-lock/WakeLock.cpp:
(WebCore::WakeLock::request):
* Source/WebCore/Modules/speech/SpeechRecognition.cpp:
(WebCore::SpeechRecognition::startRecognition):
* Source/WebCore/Modules/webauthn/AuthenticatorCoordinator.cpp:
(WebCore::AuthenticatorCoordinator::discoverFromExternalSource):
* Source/WebCore/Modules/webxr/WebXRSystem.cpp:
(WebCore::WebXRSystem::isSessionSupported):
(WebCore::WebXRSystem::isFeaturePermitted const):
* Source/WebCore/dom/FullscreenManager.cpp:
(WebCore::FullscreenManager::requestFullscreenForElement):
(WebCore::FullscreenManager::isFullscreenEnabled const):
* Source/WebCore/html/HTMLIFrameElement.cpp:
(WebCore::HTMLIFrameElement::permissionsPolicy const):
* Source/WebCore/html/PermissionsPolicy.cpp:
(WebCore::toFeatureNameForLogging):
(WebCore::readFeatureIdentifier):
(WebCore::splitOnAsciiWhiteSpace):
(WebCore::isPermissionsPolicyAllowedByDocumentAndAllOwners):
(WebCore::PermissionsPolicy::Allowlist::matches const):
(WebCore::PermissionsPolicy::parseAllowlist):
(WebCore::PermissionsPolicy::parsePolicyDirective):
(WebCore::PermissionsPolicy::declaredOrigin const):
(WebCore::PermissionsPolicy::PermissionsPolicy):
(WebCore::PermissionsPolicy::allows const):
(WebCore::policyTypeName): Deleted.
(WebCore::isAllowedByPermissionsPolicy): Deleted.
(WebCore::processOriginItem): Deleted.
(WebCore::updateList): Deleted.
(WebCore::PermissionsPolicy::parse): Deleted.
* Source/WebCore/html/PermissionsPolicy.h:
(WebCore::PermissionsPolicy::defaultPolicy):
(WebCore::PermissionsPolicy::parse):
(WebCore::PermissionsPolicy::Allowlist::Allowlist):
* Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp:
(WebCore::WebGLRenderingContextBase::makeXRCompatible):
* Source/WebCore/loader/FrameLoader.cpp:
(WebCore::FrameLoader::updateRequestAndAddExtraFields):
* Source/WebCore/page/LocalDOMWindow.cpp:
(WebCore::LocalDOMWindow::isAllowedToUseDeviceMotion const):
(WebCore::LocalDOMWindow::isAllowedToUseDeviceOrientation const):
* Source/WebCore/page/Navigator.cpp:
(WebCore::validateWebSharePolicy):
* Source/WebCore/xml/XMLHttpRequest.cpp:
(WebCore::XMLHttpRequest::createRequest):

Canonical link: https://commits.webkit.org/278786@main
  • Loading branch information
szewai committed May 15, 2024
1 parent d206c2d commit 061e4cd
Show file tree
Hide file tree
Showing 21 changed files with 300 additions and 372 deletions.
2 changes: 1 addition & 1 deletion Source/WebCore/Modules/applepay/PaymentSession.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ static bool isSecure(DocumentLoader& documentLoader)

ExceptionOr<void> PaymentSession::canCreateSession(Document& document)
{
if (!isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Type::Payment, document, LogPermissionsPolicyFailure::Yes))
if (!isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Feature::Payment, document, LogPermissionsPolicyFailure::Yes))
return Exception { ExceptionCode::SecurityError, "Third-party iframes are not allowed to request payments unless explicitly allowed via Feature-Policy (payment)"_s };

if (!document.frame())
Expand Down
8 changes: 4 additions & 4 deletions Source/WebCore/Modules/audiosession/DOMAudioSession.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ ExceptionOr<void> DOMAudioSession::setType(Type type)
if (!document)
return Exception { ExceptionCode::InvalidStateError };

if (!isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Type::Microphone, *document, LogPermissionsPolicyFailure::No))
if (!isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Feature::Microphone, *document, LogPermissionsPolicyFailure::No))
return { };

document->topDocument().setAudioSessionType(type);
Expand All @@ -101,7 +101,7 @@ ExceptionOr<void> DOMAudioSession::setType(Type type)
DOMAudioSession::Type DOMAudioSession::type() const
{
RefPtr document = downcast<Document>(scriptExecutionContext());
if (document && !isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Type::Microphone, *document, LogPermissionsPolicyFailure::No))
if (document && !isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Feature::Microphone, *document, LogPermissionsPolicyFailure::No))
return DOMAudioSession::Type::Auto;

return document ? document->topDocument().audioSessionType() : DOMAudioSession::Type::Auto;
Expand All @@ -121,7 +121,7 @@ static DOMAudioSession::State computeAudioSessionState()
DOMAudioSession::State DOMAudioSession::state() const
{
RefPtr document = downcast<Document>(scriptExecutionContext());
if (!document || !isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Type::Microphone, *document, LogPermissionsPolicyFailure::No))
if (!document || !isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Feature::Microphone, *document, LogPermissionsPolicyFailure::No))
return DOMAudioSession::State::Inactive;

if (!m_state)
Expand Down Expand Up @@ -156,7 +156,7 @@ void DOMAudioSession::audioSessionActiveStateChanged()
void DOMAudioSession::scheduleStateChangeEvent()
{
RefPtr document = downcast<Document>(scriptExecutionContext());
if (document && !isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Type::Microphone, *document, LogPermissionsPolicyFailure::No))
if (document && !isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Feature::Microphone, *document, LogPermissionsPolicyFailure::No))
return;

if (m_hasScheduleStateChangeEvent)
Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/Modules/gamepad/NavigatorGamepad.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ ExceptionOr<const Vector<RefPtr<Gamepad>>&> NavigatorGamepad::getGamepads(Naviga
return { emptyGamepads.get() };
}

if (!isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Type::Gamepad, *document, LogPermissionsPolicyFailure::Yes))
if (!isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Feature::Gamepad, *document, LogPermissionsPolicyFailure::Yes))
return Exception { ExceptionCode::SecurityError, "Third-party iframes are not allowed to call getGamepads() unless explicitly allowed via Feature-Policy (gamepad)"_s };

return NavigatorGamepad::from(navigator)->gamepads();
Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/Modules/geolocation/Geolocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ static void logError(const String& target, const bool isSecure, const bool isMix

bool Geolocation::shouldBlockGeolocationRequests()
{
if (!isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Type::Geolocation, *document(), LogPermissionsPolicyFailure::Yes))
if (!isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Feature::Geolocation, *document(), LogPermissionsPolicyFailure::Yes))
return true;

bool isSecure = SecurityOrigin::isSecure(document()->url()) || document()->isSecureContext();
Expand Down
10 changes: 5 additions & 5 deletions Source/WebCore/Modules/mediastream/MediaDevices.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -277,19 +277,19 @@ void MediaDevices::getDisplayMedia(DisplayMediaStreamConstraints&& constraints,

static inline bool checkCameraAccess(const Document& document)
{
return isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Type::Camera, document, LogPermissionsPolicyFailure::No);
return isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Feature::Camera, document, LogPermissionsPolicyFailure::No);
}

static inline bool checkMicrophoneAccess(const Document& document)
{
return isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Type::Microphone, document, LogPermissionsPolicyFailure::No);
return isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Feature::Microphone, document, LogPermissionsPolicyFailure::No);
}

static inline bool checkSpeakerAccess(const Document& document)
{
return document.frame()
&& document.frame()->settings().exposeSpeakersEnabled()
&& isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Type::SpeakerSelection, document, LogPermissionsPolicyFailure::No);
&& isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Feature::SpeakerSelection, document, LogPermissionsPolicyFailure::No);
}

void MediaDevices::exposeDevices(Vector<CaptureDeviceWithCapabilities>&& newDevices, MediaDeviceHashSalts&& deviceIDHashSalts, EnumerateDevicesPromise&& promise)
Expand Down Expand Up @@ -390,8 +390,8 @@ void MediaDevices::listenForDeviceChanges()
if (!controller)
return;

bool canAccessCamera = isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Type::Camera, *document, LogPermissionsPolicyFailure::No);
bool canAccessMicrophone = isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Type::Microphone, *document, LogPermissionsPolicyFailure::No);
bool canAccessCamera = isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Feature::Camera, *document, LogPermissionsPolicyFailure::No);
bool canAccessMicrophone = isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Feature::Microphone, *document, LogPermissionsPolicyFailure::No);

if (m_listeningForDeviceChanges || (!canAccessCamera && !canAccessMicrophone))
return;
Expand Down
4 changes: 2 additions & 2 deletions Source/WebCore/Modules/mediastream/UserMediaController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ void UserMediaController::logGetDisplayMediaDenial(Document& document)
void UserMediaController::logEnumerateDevicesDenial(Document& document)
{
// We redo the check to print to the console log.
isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Type::Camera, document, LogPermissionsPolicyFailure::Yes);
isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Type::Microphone, document, LogPermissionsPolicyFailure::Yes);
isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Feature::Camera, document, LogPermissionsPolicyFailure::Yes);
isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Feature::Microphone, document, LogPermissionsPolicyFailure::Yes);
if (RefPtr window = document.domWindow())
window->printErrorMessage("Not allowed to call enumerateDevices."_s);
}
Expand Down
6 changes: 3 additions & 3 deletions Source/WebCore/Modules/mediastream/UserMediaRequest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,19 +116,19 @@ void UserMediaRequest::start()
switch (m_request.type) {
case MediaStreamRequest::Type::DisplayMedia:
case MediaStreamRequest::Type::DisplayMediaWithAudio:
if (!isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Type::DisplayCapture, document)) {
if (!isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Feature::DisplayCapture, document)) {
deny(MediaAccessDenialReason::PermissionDenied);
controller->logGetDisplayMediaDenial(document);
return;
}
break;
case MediaStreamRequest::Type::UserMedia:
if (m_request.audioConstraints.isValid && !isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Type::Microphone, document)) {
if (m_request.audioConstraints.isValid && !isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Feature::Microphone, document)) {
deny(MediaAccessDenialReason::PermissionDenied);
controller->logGetUserMediaDenial(document);
return;
}
if (m_request.videoConstraints.isValid && !isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Type::Camera, document)) {
if (m_request.videoConstraints.isValid && !isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Feature::Camera, document)) {
deny(MediaAccessDenialReason::PermissionDenied);
controller->logGetUserMediaDenial(document);
return;
Expand Down
6 changes: 3 additions & 3 deletions Source/WebCore/Modules/permissions/Permissions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,11 @@ static bool isAllowedByPermissionsPolicy(const Document& document, PermissionNam
{
switch (name) {
case PermissionName::Camera:
return isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Type::Camera, document, LogPermissionsPolicyFailure::No);
return isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Feature::Camera, document, LogPermissionsPolicyFailure::No);
case PermissionName::Geolocation:
return isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Type::Geolocation, document, LogPermissionsPolicyFailure::No);
return isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Feature::Geolocation, document, LogPermissionsPolicyFailure::No);
case PermissionName::Microphone:
return isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Type::Microphone, document, LogPermissionsPolicyFailure::No);
return isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Feature::Microphone, document, LogPermissionsPolicyFailure::No);
default:
return true;
}
Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/Modules/screen-wake-lock/WakeLock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ void WakeLock::request(WakeLockType lockType, Ref<DeferredPromise>&& promise)
promise->reject(Exception { ExceptionCode::NotAllowedError, "Document is not fully active"_s });
return;
}
if (!isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Type::ScreenWakeLock, *document, LogPermissionsPolicyFailure::Yes)) {
if (!isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Feature::ScreenWakeLock, *document, LogPermissionsPolicyFailure::Yes)) {
promise->reject(Exception { ExceptionCode::NotAllowedError, "'screen-wake-lock' is not allowed by Feature-Policy"_s });
return;
}
Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/Modules/speech/SpeechRecognition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ ExceptionOr<void> SpeechRecognition::startRecognition()
return Exception { ExceptionCode::UnknownError, "Recognition is not in a valid frame"_s };

auto optionalFrameIdentifier = document->frameID();
if (!isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Type::Microphone, document.get(), LogPermissionsPolicyFailure::No)) {
if (!isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Feature::Microphone, document.get(), LogPermissionsPolicyFailure::No)) {
didError({ SpeechRecognitionErrorType::NotAllowed, "Permission is denied"_s });
return { };
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ void AuthenticatorCoordinator::discoverFromExternalSource(const Document& docume
// Step 1, 3, 13 are handled by the caller.
// Step 2.
// This implements https://www.w3.org/TR/webauthn-2/#sctn-permissions-policy
if (scopeAndCrossOriginParent.first != WebAuthn::Scope::SameOrigin && !isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Type::PublickeyCredentialsGetRule, document, LogPermissionsPolicyFailure::No)) {
if (scopeAndCrossOriginParent.first != WebAuthn::Scope::SameOrigin && !isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Feature::PublickeyCredentialsGetRule, document, LogPermissionsPolicyFailure::No)) {
promise.reject(Exception { ExceptionCode::NotAllowedError, "The origin of the document is not the same as its ancestors."_s });
return;
}
Expand Down
4 changes: 2 additions & 2 deletions Source/WebCore/Modules/webxr/WebXRSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ void WebXRSystem::isSessionSupported(XRSessionMode mode, IsSessionSupportedPromi
// 3. If the requesting document's origin is not allowed to use the "xr-spatial-tracking" feature policy,
// reject promise with a "SecurityError" DOMException and return it.
auto document = downcast<Document>(scriptExecutionContext());
if (!isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Type::XRSpatialTracking, *document, LogPermissionsPolicyFailure::Yes)) {
if (!isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Feature::XRSpatialTracking, *document, LogPermissionsPolicyFailure::Yes)) {
promise.reject(Exception { ExceptionCode::SecurityError });
return;
}
Expand Down Expand Up @@ -279,7 +279,7 @@ bool WebXRSystem::isFeaturePermitted(PlatformXR::SessionFeature feature) const
case PlatformXR::SessionFeature::HandTracking:
#endif
RefPtr document = downcast<Document>(scriptExecutionContext());
return document && isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Type::XRSpatialTracking, *document, LogPermissionsPolicyFailure::Yes);
return document && isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Feature::XRSpatialTracking, *document, LogPermissionsPolicyFailure::Yes);
}

ASSERT_NOT_REACHED();
Expand Down
4 changes: 2 additions & 2 deletions Source/WebCore/dom/FullscreenManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ void FullscreenManager::requestFullscreenForElement(Ref<Element>&& element, RefP

// The context object's node document, or an ancestor browsing context's document does not have
// the fullscreen enabled flag set.
if (checkType == EnforceIFrameAllowFullscreenRequirement && !isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Type::Fullscreen, document)) {
if (checkType == EnforceIFrameAllowFullscreenRequirement && !isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Feature::Fullscreen, document)) {
ERROR_LOG(identifier, "task - ancestor document does not enable fullscreen; failing.");
failedPreflights(WTFMove(element), WTFMove(promise));
return;
Expand Down Expand Up @@ -475,7 +475,7 @@ bool FullscreenManager::isFullscreenEnabled() const
// browsing context's documents have their fullscreen enabled flag set, or false otherwise.

// Top-level browsing contexts are implied to have their allowFullscreen attribute set.
return isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Type::Fullscreen, protectedDocument());
return isPermissionsPolicyAllowedByDocumentAndAllOwners(PermissionsPolicy::Feature::Fullscreen, protectedDocument());
}

bool FullscreenManager::willEnterFullscreen(Element& element, HTMLMediaElementEnums::VideoFullscreenMode mode)
Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/html/HTMLIFrameElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ ReferrerPolicy HTMLIFrameElement::referrerPolicy() const
const PermissionsPolicy& HTMLIFrameElement::permissionsPolicy() const
{
if (!m_permissionsPolicy)
m_permissionsPolicy = PermissionsPolicy::parse(document(), *this, attributeWithoutSynchronization(allowAttr));
m_permissionsPolicy = PermissionsPolicy::parse(document(), *this);
return *m_permissionsPolicy;
}

Expand Down
Loading

0 comments on commit 061e4cd

Please sign in to comment.