Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: 386b21db7bdc2fc5135138027639ef8bf8a0402b
https://github.com/WebKit/WebKit/commit/386b21db7bdc2fc5135138027639ef8bf8a0402b
Author: Rupin Mittal <[email protected]>
Date: 2025-05-21 (Wed, 21 May 2025)
Changed paths:
M Source/WebCore/Modules/geolocation/Geolocation.cpp
M Source/WebCore/Modules/geolocation/Geolocation.h
M Source/WebCore/Modules/geolocation/NavigatorGeolocation.cpp
M Source/WebCore/Modules/geolocation/NavigatorGeolocation.h
M Source/WebCore/Modules/permissions/Permissions.cpp
M Source/WebCore/Modules/permissions/Permissions.h
M Source/WebKit/UIProcess/WebPageProxy.cpp
M Tools/TestWebKitAPI/Tests/WebKitCocoa/PermissionsAPI.mm
Log Message:
-----------
[Permissions API] Report the true permission state of Geolocation only when
that API has been used since the page load
https://bugs.webkit.org/show_bug.cgi?id=293089
rdar://151426960
Reviewed by Youenn Fablet.
The current behavior of the Permissions API is:
- Return PROMPT in all cases where the permission state of the Geolocation API
is DENIED.
- Return GRANTED in all cases where the permission state of the Geolocation API
is GRANTED.
This PR changes WebKit's Permissions API to behave like so:
(On both MacOS and iOS).
User action || Client tells WebKit || WebKit
tells website ||
----------------------------------------------||---------------------||-------------------------||
User says GRANTED to prompt once || PROMPT || GRANTED
|| geolocation requested by page since page load
|| PROMPT || PROMPT
|| not requested since page load
User says GRANTED to prompt twice (24h grant) || PROMPT || GRANTED
|| geolocation requested by page since page load
|| PROMPT || PROMPT
|| not requested since page load
User says DENIED to prompt once || PROMPT || DENIED
|| geolocation requested by page since page load
|| PROMPT || PROMPT
|| not requested since page load
User says DENIED to prompt twice (24h grant) || PROMPT || DENIED
|| geolocation requested by page since page load
|| PROMPT || PROMPT
|| not requested since page load
User says GRANTED in permanent settings || GRANTED || GRANTED
||
User says DENIED in permanent settings || DENIED || DENIED
|| geolocation requested by page since page load
|| DENIED || PROMPT
(fingerprinting) || not requested since page load
The "Client tells WebKit" column represents how the client's implementation of
the queryPermission
delegate behaves. Given this behavior, this PR makes changes so that the
Permissions API behaves
like the "WebKit tells website" column.
WebKit's position is that the geolocation permission state should only be
revealed to a site if
that site is willing to show a prompt asking for permission to use that API.
Prompts for geolocation are shown when one of the functions of the Geolocation
API are called
(for example navigator.geolocation.getCurrentPosition). So the Permissions API
should only reveal
the true permission state of the Geolocation API if such a function has been
called since the page
load. If you reload the page, WebKit forgets that you've tried to use the API.
The only exception to this rule is that if a user has permanently GRANTED--the
user is indicating
that they trust this site, so the Permissions API will return the true state
regardless of if the
site has attempted to get the geolocation. It's important to note that these
settings (both permanent
and for a prompt) are per-site settings.
We don't make this exception in the case of permanently DENIED--as
fingerprinting countermeasure,
we still return PROMPT in the case where Geolocation hasn't been requested.
Implementation details:
Navigator has a Geolocation object. On this object, we add a property
(m_hasBeenRequested) which
gets set any time permission to get geolocation is requested. The Geolocation
object is reset
every page load and so is this property.
When Permissions::query is called, it gets the permission state from the
client. For geolocation,
clients return GRANTED or DENIED only in the cases where the user has granted
or denied *permanently*.
If no permanent setting has been set, and user has simply granted or denied via
a prompt, clients
return PROMPT. But if the user grants or denies via a prompt, the
m_allowGeolocation property gets
set on the Geolocation object.
This means that Permissions::queryPermission can see that:
- If the result returned by client is GRANTED or DENIED --> that's a permanent
setting
- If the result returned by client is PROMPT and Geolocation has been requested
--> the user has
responded to the prompt and their answer is contained in
Geolocation::isAllowed()
The behavior in the table is tested by new API tests. These tests work on both
MacOS and iOS.
* Source/WebCore/Modules/geolocation/Geolocation.cpp:
(WebCore::Geolocation::requestPermission):
(WebCore::Geolocation::resetIsAllowed):
* Source/WebCore/Modules/geolocation/Geolocation.h:
We add the new property m_hasBeenRequested here with a function to access it.
To access Geolocation's m_hasBeenRequested property, the Permissions API
code first gets the Geolocation from the NavigatorGeolocation. This is
supplement to the WebPage. Service workers don't have a WebPage and thus
don't have a NavigationGeolocation object. So we want to make sure
we don't try to createa Geolocation object in this case because attempting
to delete it later will result in a crash (we delete it by accessing it
from the supplement first--which doesn't exist in the worker case).
* Source/WebCore/Modules/permissions/Permissions.cpp:
(WebCore::Permissions::query):
(WebCore::Permissions::determineGeolocationPermissionState):
This function decides if the permission state is a permanent one, or a temporary
user-response to a prompt. It contains the logic to change GRANTED and DENIED to
PROMPT in cases where the Geolocation API hasn't been used since the page load.
(The main logic of the above table is implemented here).
* Source/WebCore/Modules/permissions/Permissions.h:
* Source/WebKit/UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::queryPermission):
* Tools/TestWebKitAPI/Tests/WebKitCocoa/PermissionsAPI.mm:
(-[PermissionsAPIUIDelegate
_webView:queryPermission:forOrigin:completionHandler:]):
(-[PermissionsAPIAndGeolocationRequestUIDelegate
_webView:requestGeolocationPermissionForFrame:decisionHandler:]):
(TestWebKitAPI::TEST(PermissionsAPI, DataURL)):
(TestWebKitAPI::TEST(PermissionsAPI, OnChange)):
(TestWebKitAPI::testPermissionsAPIForGeolocation):
(TestWebKitAPI::TEST(PermissionsAPI,
GeolocationPermissionGrantedFromPromptAndGeolcationRequestedSinceLoad)):
(TestWebKitAPI::TEST(PermissionsAPI,
GeolocationPermissionGrantedFromPromptAndGeolocationNotRequestedSinceLoad)):
(TestWebKitAPI::TEST(PermissionsAPI,
GeolcolationPermissionDeniedFromPromptAndGeolocationRequestedSinceLoad)):
(TestWebKitAPI::TEST(PermissionsAPI,
GeolcolationPermissionDeniedFromPromptAndGeolocationNotRequestedSinceLoad)):
(TestWebKitAPI::TEST(PermissionsAPI,
GeolcolationPermissionGrantedPermanentlyAndGeolocationRequestedSinceLoad)):
(TestWebKitAPI::TEST(PermissionsAPI,
GeolcolationPermissionGrantedPermanentlyAndGeolocationNotRequestedSinceLoad)):
(TestWebKitAPI::TEST(PermissionsAPI,
GeolcolationPermissionDeniedPermanentlyAndGeolocationRequestedSinceLoad)):
(TestWebKitAPI::TEST(PermissionsAPI,
GeolcolationPermissionDeniedPermanentlyAndGeolocationNotRequestedSinceLoad)):
Canonical link: https://commits.webkit.org/295237@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes