Diff
Modified: trunk/LayoutTests/ChangeLog (275275 => 275276)
--- trunk/LayoutTests/ChangeLog 2021-03-31 11:11:17 UTC (rev 275275)
+++ trunk/LayoutTests/ChangeLog 2021-03-31 11:16:12 UTC (rev 275276)
@@ -1,3 +1,13 @@
+2021-03-31 Youenn Fablet <you...@apple.com>
+
+ Apply permission policy to geolocation
+ https://bugs.webkit.org/show_bug.cgi?id=223248
+
+ Reviewed by Eric Carlson.
+
+ * http/tests/security/sandboxed-iframe-geolocation-getCurrentPosition-expected.txt:
+ * http/tests/security/sandboxed-iframe-geolocation-watchPosition-expected.txt:
+
2021-03-31 Carlos Alberto Lopez Perez <clo...@igalia.com>
REGRESSION(r274244): [GTK][WPE] Two http/tests/security/contentSecurityPolicy tests crash
Modified: trunk/LayoutTests/http/tests/security/sandboxed-iframe-geolocation-getCurrentPosition-expected.txt (275275 => 275276)
--- trunk/LayoutTests/http/tests/security/sandboxed-iframe-geolocation-getCurrentPosition-expected.txt 2021-03-31 11:11:17 UTC (rev 275275)
+++ trunk/LayoutTests/http/tests/security/sandboxed-iframe-geolocation-getCurrentPosition-expected.txt 2021-03-31 11:16:12 UTC (rev 275276)
@@ -1,3 +1,4 @@
+CONSOLE MESSAGE: Feature policy 'Geolocation' check failed for iframe with origin 'null' and allow attribute ''.
Tests that navigator.geolocation.getCurrentPosition() returns error PERMISSION_DENIED when called from a document in a sandboxed iframe.
Modified: trunk/LayoutTests/http/tests/security/sandboxed-iframe-geolocation-watchPosition-expected.txt (275275 => 275276)
--- trunk/LayoutTests/http/tests/security/sandboxed-iframe-geolocation-watchPosition-expected.txt 2021-03-31 11:11:17 UTC (rev 275275)
+++ trunk/LayoutTests/http/tests/security/sandboxed-iframe-geolocation-watchPosition-expected.txt 2021-03-31 11:16:12 UTC (rev 275276)
@@ -1,3 +1,4 @@
+CONSOLE MESSAGE: Feature policy 'Geolocation' check failed for iframe with origin 'null' and allow attribute ''.
Tests that navigator.geolocation.watchPosition() returns error PERMISSION_DENIED when called from a document in a sandboxed iframe.
Modified: trunk/Source/WebCore/ChangeLog (275275 => 275276)
--- trunk/Source/WebCore/ChangeLog 2021-03-31 11:11:17 UTC (rev 275275)
+++ trunk/Source/WebCore/ChangeLog 2021-03-31 11:16:12 UTC (rev 275276)
@@ -1,3 +1,22 @@
+2021-03-31 Youenn Fablet <you...@apple.com>
+
+ Apply permission policy to geolocation
+ https://bugs.webkit.org/show_bug.cgi?id=223248
+
+ Reviewed by Eric Carlson.
+
+ Only allow third-party iframes if allowed by permission policy,
+ following https://w3c.github.io/geolocation-api/#permissions-policy.
+ Covered by API tests.
+
+ * Modules/geolocation/Geolocation.cpp:
+ (WebCore::Geolocation::shouldBlockGeolocationRequests):
+ * html/FeaturePolicy.cpp:
+ (WebCore::policyTypeName):
+ (WebCore::FeaturePolicy::parse):
+ (WebCore::FeaturePolicy::allows const):
+ * html/FeaturePolicy.h:
+
2021-03-31 Thibault Saunier <tsaun...@igalia.com> and Philippe Normand <pnorm...@igalia.com>
[WebRTC][GStreamer] Build and use the openh264 based encoder if present on the system
Modified: trunk/Source/WebCore/Modules/geolocation/Geolocation.cpp (275275 => 275276)
--- trunk/Source/WebCore/Modules/geolocation/Geolocation.cpp 2021-03-31 11:11:17 UTC (rev 275275)
+++ trunk/Source/WebCore/Modules/geolocation/Geolocation.cpp 2021-03-31 11:16:12 UTC (rev 275276)
@@ -31,6 +31,7 @@
#if ENABLE(GEOLOCATION)
#include "Document.h"
+#include "FeaturePolicy.h"
#include "Frame.h"
#include "GeoNotifier.h"
#include "GeolocationController.h"
@@ -351,6 +352,9 @@
bool Geolocation::shouldBlockGeolocationRequests()
{
+ if (!isFeaturePolicyAllowedByDocumentAndAllOwners(FeaturePolicy::Type::Geolocation, *document(), LogFeaturePolicyFailure::Yes))
+ return true;
+
bool isSecure = SecurityOrigin::isSecure(document()->url()) || document()->isSecureContext();
bool hasMixedContent = !document()->foundMixedContent().isEmpty();
bool isLocalOrigin = securityOrigin()->isLocal();
@@ -358,7 +362,7 @@
if (isLocalOrigin || (isSecure && !hasMixedContent) || isRequestFromIBooks())
return false;
}
-
+
logError(securityOrigin()->toString(), isSecure, hasMixedContent, document());
return true;
}
Modified: trunk/Source/WebCore/html/FeaturePolicy.cpp (275275 => 275276)
--- trunk/Source/WebCore/html/FeaturePolicy.cpp 2021-03-31 11:11:17 UTC (rev 275275)
+++ trunk/Source/WebCore/html/FeaturePolicy.cpp 2021-03-31 11:16:12 UTC (rev 275276)
@@ -48,6 +48,8 @@
return "SpeakerSelection";
case FeaturePolicy::Type::DisplayCapture:
return "DisplayCapture";
+ case FeaturePolicy::Type::Geolocation:
+ return "Geolocation";
case FeaturePolicy::Type::SyncXHR:
return "SyncXHR";
case FeaturePolicy::Type::Fullscreen:
@@ -167,6 +169,7 @@
bool isMicrophoneInitialized = false;
bool isSpeakerSelectionInitialized = false;
bool isDisplayCaptureInitialized = false;
+ bool isGeolocationInitialized = false;
bool isSyncXHRInitialized = false;
bool isFullscreenInitialized = false;
#if ENABLE(DEVICE_ORIENTATION)
@@ -199,6 +202,11 @@
updateList(document, policy.m_displayCaptureRule, item.substring(16));
continue;
}
+ if (item.startsWith("geolocation")) {
+ isGeolocationInitialized = true;
+ updateList(document, policy.m_geolocationRule, item.substring(12));
+ continue;
+ }
if (item.startsWith("sync-xhr")) {
isSyncXHRInitialized = true;
updateList(document, policy.m_syncXHRRule, item.substring(9));
@@ -244,6 +252,8 @@
policy.m_speakerSelectionRule.allowedList.add(document.securityOrigin().data());
if (!isDisplayCaptureInitialized)
policy.m_displayCaptureRule.allowedList.add(document.securityOrigin().data());
+ if (!isGeolocationInitialized)
+ policy.m_geolocationRule.allowedList.add(document.securityOrigin().data());
#if ENABLE(DEVICE_ORIENTATION)
if (!isGyroscopeInitialized)
policy.m_gyroscopeRule.allowedList.add(document.securityOrigin().data());
@@ -289,6 +299,8 @@
return isAllowedByFeaturePolicy(m_speakerSelectionRule, origin);
case Type::DisplayCapture:
return isAllowedByFeaturePolicy(m_displayCaptureRule, origin);
+ case Type::Geolocation:
+ return isAllowedByFeaturePolicy(m_geolocationRule, origin);
case Type::SyncXHR:
return isAllowedByFeaturePolicy(m_syncXHRRule, origin);
case Type::Fullscreen:
Modified: trunk/Source/WebCore/html/FeaturePolicy.h (275275 => 275276)
--- trunk/Source/WebCore/html/FeaturePolicy.h 2021-03-31 11:11:17 UTC (rev 275275)
+++ trunk/Source/WebCore/html/FeaturePolicy.h 2021-03-31 11:16:12 UTC (rev 275276)
@@ -43,6 +43,7 @@
Microphone,
SpeakerSelection,
DisplayCapture,
+ Geolocation,
SyncXHR,
Fullscreen,
#if ENABLE(DEVICE_ORIENTATION)
@@ -67,6 +68,7 @@
AllowRule m_microphoneRule;
AllowRule m_speakerSelectionRule;
AllowRule m_displayCaptureRule;
+ AllowRule m_geolocationRule;
AllowRule m_syncXHRRule;
AllowRule m_fullscreenRule;
#if ENABLE(DEVICE_ORIENTATION)
Modified: trunk/Tools/ChangeLog (275275 => 275276)
--- trunk/Tools/ChangeLog 2021-03-31 11:11:17 UTC (rev 275275)
+++ trunk/Tools/ChangeLog 2021-03-31 11:16:12 UTC (rev 275276)
@@ -1,3 +1,15 @@
+2021-03-31 Youenn Fablet <you...@apple.com>
+
+ Apply permission policy to geolocation
+ https://bugs.webkit.org/show_bug.cgi?id=223248
+
+ Reviewed by Eric Carlson.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/UIDelegate.mm:
+ (-[GeolocationDelegateNew setValidationHandler:]):
+ (-[GeolocationDelegateNew _webView:requestGeolocationPermissionForOrigin:initiatedByFrame:decisionHandler:]):
+ (-[GeolocationPermissionMessageHandler userContentController:didReceiveScriptMessage:]):
+
2021-03-30 Chris Dumez <cdu...@apple.com>
Service Worker scripts use too much memory in the network process
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/UIDelegate.mm (275275 => 275276)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/UIDelegate.mm 2021-03-31 11:11:17 UTC (rev 275275)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/UIDelegate.mm 2021-03-31 11:16:12 UTC (rev 275276)
@@ -49,6 +49,7 @@
#endif
static bool done;
+static bool didReceiveMessage;
@interface AudioObserver : NSObject
@end
@@ -215,33 +216,43 @@
}
@interface GeolocationDelegateNew : NSObject <WKUIDelegatePrivate>
+- (void)setValidationHandler:(Function<void(WKSecurityOrigin*, WKFrameInfo*)>&&)validationHandler;
@end
-@implementation GeolocationDelegateNew
+@implementation GeolocationDelegateNew {
+ Function<void(WKSecurityOrigin*, WKFrameInfo*)> _validationHandler;
+}
+- (void)setValidationHandler:(Function<void(WKSecurityOrigin*, WKFrameInfo*)>&&)validationHandler {
+ _validationHandler = WTFMove(validationHandler);
+}
+
- (void)_webView:(WKWebView *)webView requestGeolocationPermissionForOrigin:(WKSecurityOrigin*)origin initiatedByFrame:(WKFrameInfo *)frame decisionHandler:(void (^)(WKPermissionDecision decision))decisionHandler {
- EXPECT_WK_STREQ(origin.protocol, @"https");
- EXPECT_WK_STREQ(origin.host, @"127.0.0.1");
- EXPECT_EQ(origin.port, 9090);
+ if (_validationHandler)
+ _validationHandler(origin, frame);
- EXPECT_WK_STREQ(frame.securityOrigin.protocol, @"https");
- EXPECT_WK_STREQ(frame.securityOrigin.host, @"127.0.0.1");
- EXPECT_EQ(frame.securityOrigin.port, 9091);
- EXPECT_FALSE(frame.isMainFrame);
- EXPECT_TRUE(frame.webView == webView);
-
done = true;
decisionHandler(WKPermissionDecisionGrant);
}
@end
+
+@interface GeolocationPermissionMessageHandler : NSObject <WKScriptMessageHandler>
+@end
+@implementation GeolocationPermissionMessageHandler
+- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
+{
+ didReceiveMessage = true;
+}
+@end
+
static const char* mainFrameText = R"DOCDOCDOC(
<html><body>
-<iframe src='' allow='camera:https://127.0.0.1:9091'></iframe>
+<iframe src='' allow='geolocation:https://127.0.0.1:9091'></iframe>
</body></html>
)DOCDOCDOC";
static const char* frameText = R"DOCDOCDOC(
<html><body><script>
-navigator.geolocation.getCurrentPosition(() => { });
+navigator.geolocation.getCurrentPosition(() => { webkit.messageHandlers.testHandler.postMessage("ok") }, () => { webkit.messageHandlers.testHandler.postMessage("ko") });
</script></body></html>
)DOCDOCDOC";
@@ -267,10 +278,14 @@
auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
configuration.get().processPool = pool.get();
+
+ auto messageHandler = adoptNS([[GeolocationPermissionMessageHandler alloc] init]);
+ [[configuration userContentController] addScriptMessageHandler:messageHandler.get() name:@"testHandler"];
+
auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration.get()]);
- auto delegate = adoptNS([[GeolocationDelegateNew alloc] init]);
- [webView setUIDelegate:delegate.get()];
+ auto permissionDelegate = adoptNS([[GeolocationDelegateNew alloc] init]);
+ [webView setUIDelegate:permissionDelegate.get()];
auto navigationDelegate = adoptNS([TestNavigationDelegate new]);
[navigationDelegate setDidReceiveAuthenticationChallenge:^(WKWebView *, NSURLAuthenticationChallenge *challenge, void (^callback)(NSURLSessionAuthChallengeDisposition, NSURLCredential *)) {
@@ -279,10 +294,76 @@
}];
webView.get().navigationDelegate = navigationDelegate.get();
+ [permissionDelegate setValidationHandler:[&webView](WKSecurityOrigin *origin, WKFrameInfo *frame) {
+ EXPECT_WK_STREQ(origin.protocol, @"https");
+ EXPECT_WK_STREQ(origin.host, @"127.0.0.1");
+ EXPECT_EQ(origin.port, 9090);
+
+ EXPECT_WK_STREQ(frame.securityOrigin.protocol, @"https");
+ EXPECT_WK_STREQ(frame.securityOrigin.host, @"127.0.0.1");
+ EXPECT_EQ(frame.securityOrigin.port, 9091);
+ EXPECT_FALSE(frame.isMainFrame);
+ EXPECT_TRUE(frame.webView == webView);
+ }];
+
+ done = false;
+ didReceiveMessage = false;
[webView loadRequest:server1.request()];
- TestWebKitAPI::Util::run(&done);
+ TestWebKitAPI::Util::run(&didReceiveMessage);
+ EXPECT_TRUE(done);
}
+static const char* notAllowingMainFrameText = R"DOCDOCDOC(
+<html><body>
+<iframe src='' allow='geolocation:https://127.0.0.1:9092'></iframe>
+</body></html>
+)DOCDOCDOC";
+
+TEST(WebKit, GeolocationPermissionInDisallowedIFrame)
+{
+ TestWebKitAPI::HTTPServer server1({
+ { "/", { notAllowingMainFrameText } }
+ }, TestWebKitAPI::HTTPServer::Protocol::Https, nullptr, nullptr, 9090);
+
+ TestWebKitAPI::HTTPServer server2({
+ { "/frame", { frameText } },
+ }, TestWebKitAPI::HTTPServer::Protocol::Https, nullptr, nullptr, 9091);
+
+ auto pool = adoptNS([[WKProcessPool alloc] init]);
+
+ WKGeolocationProviderV1 providerCallback;
+ memset(&providerCallback, 0, sizeof(WKGeolocationProviderV1));
+ providerCallback.base.version = 1;
+ providerCallback.startUpdating = [] (WKGeolocationManagerRef manager, const void*) {
+ WKGeolocationManagerProviderDidChangePosition(manager, adoptWK(WKGeolocationPositionCreate(0, 50.644358, 3.345453, 2.53)).get());
+ };
+ WKGeolocationManagerSetProvider(WKContextGetGeolocationManager((WKContextRef)pool.get()), &providerCallback.base);
+
+ auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+ configuration.get().processPool = pool.get();
+
+ auto messageHandler = adoptNS([[GeolocationPermissionMessageHandler alloc] init]);
+ [[configuration userContentController] addScriptMessageHandler:messageHandler.get() name:@"testHandler"];
+
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration.get()]);
+
+ auto permissionDelegate = adoptNS([[GeolocationDelegateNew alloc] init]);
+ [webView setUIDelegate:permissionDelegate.get()];
+
+ auto navigationDelegate = adoptNS([TestNavigationDelegate new]);
+ [navigationDelegate setDidReceiveAuthenticationChallenge:^(WKWebView *, NSURLAuthenticationChallenge *challenge, void (^callback)(NSURLSessionAuthChallengeDisposition, NSURLCredential *)) {
+ EXPECT_WK_STREQ(challenge.protectionSpace.authenticationMethod, NSURLAuthenticationMethodServerTrust);
+ callback(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
+ }];
+ webView.get().navigationDelegate = navigationDelegate.get();
+
+ done = false;
+ didReceiveMessage = false;
+ [webView loadRequest:server1.request()];
+ TestWebKitAPI::Util::run(&didReceiveMessage);
+ EXPECT_FALSE(done);
+}
+
@interface InjectedBundleNodeHandleIsSelectElementDelegate : NSObject <WKUIDelegatePrivate>
@end