Diff
Modified: trunk/Source/WebKit/ChangeLog (258053 => 258054)
--- trunk/Source/WebKit/ChangeLog 2020-03-07 04:32:32 UTC (rev 258053)
+++ trunk/Source/WebKit/ChangeLog 2020-03-07 04:48:50 UTC (rev 258054)
@@ -1,3 +1,64 @@
+2020-03-06 Kate Cheney <[email protected]>
+
+ UIProcess needs mechanism to specify AppBound domains
+ https://bugs.webkit.org/show_bug.cgi?id=208528
+ <rdar://problem/59980340>
+
+ Reviewed by Brent Fulgham.
+
+ Adds functionality to read app-bound domains from the Info.plist on
+ background thread via the WebFramePolicyListenerProxy and report
+ whether a domain is app-bound.
+
+ * UIProcess/API/Cocoa/WKWebsiteDataStore.mm:
+ (-[WKWebsiteDataStore _appBoundDomains:]):
+ * UIProcess/API/Cocoa/WKWebsiteDataStorePrivate.h:
+ Test API call to get appBoundDomains.
+
+ * UIProcess/WebFramePolicyListenerProxy.cpp:
+ (WebKit::WebFramePolicyListenerProxy::WebFramePolicyListenerProxy):
+ (WebKit::WebFramePolicyListenerProxy::didReceiveAppBoundDomainResult):
+ (WebFramePolicyListenerProxy::didReceiveSafeBrowsingResults):
+ (WebFramePolicyListenerProxy::use):
+ (WebFramePolicyListenerProxy::download):
+ (WebFramePolicyListenerProxy::ignore):
+ * UIProcess/WebFramePolicyListenerProxy.h:
+ (WebKit::WebFramePolicyListenerProxy::create):
+ * UIProcess/WebFrameProxy.cpp:
+ (WebKit::WebFrameProxy::setUpPolicyListenerProxy):
+ * UIProcess/WebFrameProxy.h:
+ * UIProcess/WebPageProxy.cpp:
+ Added a new function to WebFramePolicyListenerProxy to wait for the
+ app-bound domains to be read before completing a navigation. Each
+ other function must now check if m_isNavigatingToAppBoundDomain has
+ been set before sending a full reply. Also added an enum class
+ ShouldExpectAppBoundDomainResult to tell the listener not to wait for
+ the results in unecessary cases.
+
+ (WebKit::WebPageProxy::isAppBoundDomain const): Deleted
+ (WebKit::WebPageProxy::setIsNavigatingToAppBoundDomain):
+ (WebKit::WebPageProxy::decidePolicyForNavigationAction):
+ After the listener responds with the results, set the new
+ value in WebPageProxy. We no longer need to check for isAppBound
+ domain now that we have received the value.
+
+ (WebKit::WebPageProxy::decidePolicyForNewWindowAction):
+ (WebKit::WebPageProxy::decidePolicyForResponseShared):
+ No need to listen for app-bound domain response here.
+
+ * UIProcess/WebPageProxy.h:
+ * UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm:
+ (WebKit::appBoundDomains):
+ (WebKit::appBoundDomainQueue):
+ Add a separate static queue for reading app-bound domains to avoid
+ raciness.
+
+ (WebKit::WebsiteDataStore::beginAppBoundDomainCheck):
+ (WebKit::WebsiteDataStore::getAppBoundDomainsForTesting):
+ * UIProcess/WebsiteData/WebsiteDataStore.h:
+ Read the app-bound domain list on the background thread, and once
+ done, call the listener on the main thread.
+
2020-03-06 David Kilzer <[email protected]>
IPC hardening for WebPageProxy::SaveImageToLibrary message
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm (258053 => 258054)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm 2020-03-07 04:32:32 UTC (rev 258053)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm 2020-03-07 04:48:50 UTC (rev 258054)
@@ -600,4 +600,15 @@
return wrapper(_websiteDataStore->configuration().copy());
}
+- (void)_appBoundDomains:(void (^)(NSArray<NSString *> *))completionHandler
+{
+ _websiteDataStore->appBoundDomainsForTesting([completionHandler = makeBlockPtr(completionHandler)](auto& domains) mutable {
+ Vector<RefPtr<API::Object>> apiDomains;
+ apiDomains.reserveInitialCapacity(domains.size());
+ for (auto& domain : domains)
+ apiDomains.uncheckedAppend(API::String::create(domain.string()));
+ completionHandler(wrapper(API::Array::create(WTFMove(apiDomains))));
+ });
+}
+
@end
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStorePrivate.h (258053 => 258054)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStorePrivate.h 2020-03-07 04:32:32 UTC (rev 258053)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStorePrivate.h 2020-03-07 04:48:50 UTC (rev 258054)
@@ -77,6 +77,7 @@
- (void)_clearResourceLoadStatistics:(void (^)(void))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
- (void)_isRegisteredAsSubresourceUnderFirstParty:(NSURL *)firstPartyURL thirdParty:(NSURL *)thirdPartyURL completionHandler:(void (^)(BOOL))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
- (void)_processStatisticsAndDataRecords:(void (^)(void))completionHandler WK_API_AVAILABLE(macos(10.15), ios(13.0));
+- (void)_appBoundDomains:(void (^)(NSArray<NSString *> *))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
@property (nullable, nonatomic, weak) id <_WKWebsiteDataStoreDelegate> _delegate WK_API_AVAILABLE(macos(10.15), ios(13.0));
@property (nonatomic, readonly, copy) _WKWebsiteDataStoreConfiguration *_configuration;
Modified: trunk/Source/WebKit/UIProcess/WebFramePolicyListenerProxy.cpp (258053 => 258054)
--- trunk/Source/WebKit/UIProcess/WebFramePolicyListenerProxy.cpp 2020-03-07 04:32:32 UTC (rev 258053)
+++ trunk/Source/WebKit/UIProcess/WebFramePolicyListenerProxy.cpp 2020-03-07 04:48:50 UTC (rev 258054)
@@ -35,21 +35,36 @@
namespace WebKit {
-WebFramePolicyListenerProxy::WebFramePolicyListenerProxy(Reply&& reply, ShouldExpectSafeBrowsingResult expect)
+WebFramePolicyListenerProxy::WebFramePolicyListenerProxy(Reply&& reply, ShouldExpectSafeBrowsingResult expectSafeBrowsingResult, ShouldExpectAppBoundDomainResult expectAppBoundDomainResult)
: m_reply(WTFMove(reply))
{
- if (expect == ShouldExpectSafeBrowsingResult::No)
+ if (expectSafeBrowsingResult == ShouldExpectSafeBrowsingResult::No)
didReceiveSafeBrowsingResults({ });
+ if (expectAppBoundDomainResult == ShouldExpectAppBoundDomainResult::No)
+ didReceiveAppBoundDomainResult({ });
}
WebFramePolicyListenerProxy::~WebFramePolicyListenerProxy() = default;
+void WebFramePolicyListenerProxy::didReceiveAppBoundDomainResult(bool isNavigatingToAppBoundDomain)
+{
+ ASSERT(RunLoop::isMain());
+
+ auto isAppBound = isNavigatingToAppBoundDomain ? NavigatingToAppBoundDomain::Yes : NavigatingToAppBoundDomain::No;
+ if (m_policyResult && m_safeBrowsingWarning) {
+ if (m_reply)
+ m_reply(WebCore::PolicyAction::Use, m_policyResult->first.get(), m_policyResult->second, WTFMove(*m_safeBrowsingWarning), isAppBound);
+ } else
+ m_isNavigatingToAppBoundDomain = isAppBound;
+}
+
void WebFramePolicyListenerProxy::didReceiveSafeBrowsingResults(RefPtr<SafeBrowsingWarning>&& safeBrowsingWarning)
{
+ ASSERT(isMainThread());
ASSERT(!m_safeBrowsingWarning);
- if (m_policyResult) {
+ if (m_policyResult && m_isNavigatingToAppBoundDomain) {
if (m_reply)
- m_reply(WebCore::PolicyAction::Use, m_policyResult->first.get(), m_policyResult->second, WTFMove(safeBrowsingWarning));
+ m_reply(WebCore::PolicyAction::Use, m_policyResult->first.get(), m_policyResult->second, WTFMove(safeBrowsingWarning), *m_isNavigatingToAppBoundDomain);
} else
m_safeBrowsingWarning = WTFMove(safeBrowsingWarning);
}
@@ -56,9 +71,9 @@
void WebFramePolicyListenerProxy::use(API::WebsitePolicies* policies, ProcessSwapRequestedByClient processSwapRequestedByClient)
{
- if (m_safeBrowsingWarning) {
+ if (m_safeBrowsingWarning && m_isNavigatingToAppBoundDomain) {
if (m_reply)
- m_reply(WebCore::PolicyAction::Use, policies, processSwapRequestedByClient, WTFMove(*m_safeBrowsingWarning));
+ m_reply(WebCore::PolicyAction::Use, policies, processSwapRequestedByClient, WTFMove(*m_safeBrowsingWarning), *m_isNavigatingToAppBoundDomain);
} else if (!m_policyResult)
m_policyResult = {{ policies, processSwapRequestedByClient }};
}
@@ -66,13 +81,13 @@
void WebFramePolicyListenerProxy::download()
{
if (m_reply)
- m_reply(WebCore::PolicyAction::Download, nullptr, ProcessSwapRequestedByClient::No, { });
+ m_reply(WebCore::PolicyAction::Download, nullptr, ProcessSwapRequestedByClient::No, { }, { });
}
void WebFramePolicyListenerProxy::ignore()
{
if (m_reply)
- m_reply(WebCore::PolicyAction::Ignore, nullptr, ProcessSwapRequestedByClient::No, { });
+ m_reply(WebCore::PolicyAction::Ignore, nullptr, ProcessSwapRequestedByClient::No, { }, { });
}
} // namespace WebKit
Modified: trunk/Source/WebKit/UIProcess/WebFramePolicyListenerProxy.h (258053 => 258054)
--- trunk/Source/WebKit/UIProcess/WebFramePolicyListenerProxy.h 2020-03-07 04:32:32 UTC (rev 258053)
+++ trunk/Source/WebKit/UIProcess/WebFramePolicyListenerProxy.h 2020-03-07 04:48:50 UTC (rev 258054)
@@ -26,6 +26,7 @@
#pragma once
#include "APIObject.h"
+#include "PolicyDecision.h"
#include <WebCore/FrameLoaderTypes.h>
#include <wtf/CompletionHandler.h>
#include <wtf/Vector.h>
@@ -38,16 +39,17 @@
class SafeBrowsingWarning;
-enum class ProcessSwapRequestedByClient { No, Yes };
-enum class ShouldExpectSafeBrowsingResult { No, Yes };
+enum class ProcessSwapRequestedByClient : bool { No, Yes };
+enum class ShouldExpectSafeBrowsingResult : bool { No, Yes };
+enum class ShouldExpectAppBoundDomainResult : bool { No, Yes };
class WebFramePolicyListenerProxy : public API::ObjectImpl<API::Object::Type::FramePolicyListener> {
public:
- using Reply = CompletionHandler<void(WebCore::PolicyAction, API::WebsitePolicies*, ProcessSwapRequestedByClient, RefPtr<SafeBrowsingWarning>&&)>;
- static Ref<WebFramePolicyListenerProxy> create(Reply&& reply, ShouldExpectSafeBrowsingResult expect)
+ using Reply = CompletionHandler<void(WebCore::PolicyAction, API::WebsitePolicies*, ProcessSwapRequestedByClient, RefPtr<SafeBrowsingWarning>&&, NavigatingToAppBoundDomain)>;
+ static Ref<WebFramePolicyListenerProxy> create(Reply&& reply, ShouldExpectSafeBrowsingResult expectSafeBrowsingResult, ShouldExpectAppBoundDomainResult expectAppBoundDomainResult)
{
- return adoptRef(*new WebFramePolicyListenerProxy(WTFMove(reply), expect));
+ return adoptRef(*new WebFramePolicyListenerProxy(WTFMove(reply), expectSafeBrowsingResult, expectAppBoundDomainResult));
}
~WebFramePolicyListenerProxy();
@@ -56,12 +58,14 @@
void ignore();
void didReceiveSafeBrowsingResults(RefPtr<SafeBrowsingWarning>&&);
+ void didReceiveAppBoundDomainResult(bool);
private:
- WebFramePolicyListenerProxy(Reply&&, ShouldExpectSafeBrowsingResult);
+ WebFramePolicyListenerProxy(Reply&&, ShouldExpectSafeBrowsingResult, ShouldExpectAppBoundDomainResult);
Optional<std::pair<RefPtr<API::WebsitePolicies>, ProcessSwapRequestedByClient>> m_policyResult;
Optional<RefPtr<SafeBrowsingWarning>> m_safeBrowsingWarning;
+ Optional<NavigatingToAppBoundDomain> m_isNavigatingToAppBoundDomain;
Reply m_reply;
};
Modified: trunk/Source/WebKit/UIProcess/WebFrameProxy.cpp (258053 => 258054)
--- trunk/Source/WebKit/UIProcess/WebFrameProxy.cpp 2020-03-07 04:32:32 UTC (rev 258053)
+++ trunk/Source/WebKit/UIProcess/WebFrameProxy.cpp 2020-03-07 04:48:50 UTC (rev 258054)
@@ -193,14 +193,14 @@
m_title = title;
}
-WebFramePolicyListenerProxy& WebFrameProxy::setUpPolicyListenerProxy(CompletionHandler<void(PolicyAction, API::WebsitePolicies*, ProcessSwapRequestedByClient, RefPtr<SafeBrowsingWarning>&&)>&& completionHandler, ShouldExpectSafeBrowsingResult expect)
+WebFramePolicyListenerProxy& WebFrameProxy::setUpPolicyListenerProxy(CompletionHandler<void(PolicyAction, API::WebsitePolicies*, ProcessSwapRequestedByClient, RefPtr<SafeBrowsingWarning>&&, NavigatingToAppBoundDomain)>&& completionHandler, ShouldExpectSafeBrowsingResult expectSafeBrowsingResult, ShouldExpectAppBoundDomainResult expectAppBoundDomainResult)
{
if (m_activeListener)
m_activeListener->ignore();
- m_activeListener = WebFramePolicyListenerProxy::create([this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)] (PolicyAction action, API::WebsitePolicies* policies, ProcessSwapRequestedByClient processSwapRequestedByClient, RefPtr<SafeBrowsingWarning>&& safeBrowsingWarning) mutable {
- completionHandler(action, policies, processSwapRequestedByClient, WTFMove(safeBrowsingWarning));
+ m_activeListener = WebFramePolicyListenerProxy::create([this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)] (PolicyAction action, API::WebsitePolicies* policies, ProcessSwapRequestedByClient processSwapRequestedByClient, RefPtr<SafeBrowsingWarning>&& safeBrowsingWarning, NavigatingToAppBoundDomain isNavigatingToAppBoundDomain) mutable {
+ completionHandler(action, policies, processSwapRequestedByClient, WTFMove(safeBrowsingWarning), isNavigatingToAppBoundDomain);
m_activeListener = nullptr;
- }, expect);
+ }, expectSafeBrowsingResult, expectAppBoundDomainResult);
return *m_activeListener;
}
Modified: trunk/Source/WebKit/UIProcess/WebFrameProxy.h (258053 => 258054)
--- trunk/Source/WebKit/UIProcess/WebFrameProxy.h 2020-03-07 04:32:32 UTC (rev 258053)
+++ trunk/Source/WebKit/UIProcess/WebFrameProxy.h 2020-03-07 04:48:50 UTC (rev 258054)
@@ -53,8 +53,8 @@
class WebCertificateInfo;
class WebFramePolicyListenerProxy;
class WebsiteDataStore;
-enum class ShouldExpectSafeBrowsingResult;
-enum class ProcessSwapRequestedByClient;
+enum class ShouldExpectSafeBrowsingResult : bool;
+enum class ProcessSwapRequestedByClient : bool;
struct WebsitePoliciesData;
class WebFrameProxy : public API::ObjectImpl<API::Object::Type::Frame> {
@@ -120,7 +120,7 @@
void didSameDocumentNavigation(const URL&); // eg. anchor navigation, session state change.
void didChangeTitle(const String&);
- WebFramePolicyListenerProxy& setUpPolicyListenerProxy(CompletionHandler<void(WebCore::PolicyAction, API::WebsitePolicies*, ProcessSwapRequestedByClient, RefPtr<SafeBrowsingWarning>&&)>&&, ShouldExpectSafeBrowsingResult);
+ WebFramePolicyListenerProxy& setUpPolicyListenerProxy(CompletionHandler<void(WebCore::PolicyAction, API::WebsitePolicies*, ProcessSwapRequestedByClient, RefPtr<SafeBrowsingWarning>&&, NavigatingToAppBoundDomain)>&&, ShouldExpectSafeBrowsingResult, ShouldExpectAppBoundDomainResult);
#if ENABLE(CONTENT_FILTERING)
void contentFilterDidBlockLoad(WebCore::ContentFilterUnblockHandler contentFilterUnblockHandler) { m_contentFilterUnblockHandler = WTFMove(contentFilterUnblockHandler); }
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (258053 => 258054)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2020-03-07 04:32:32 UTC (rev 258053)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2020-03-07 04:48:50 UTC (rev 258054)
@@ -279,7 +279,6 @@
#if USE(APPLE_INTERNAL_SDK)
#include <WebKitAdditions/WebPageProxyAdditions.h>
#else
-#define WEB_PAGE_PROXY_ADDITIONS_ISAPPBOUNDDOMAIN
#define WEB_PAGE_PROXY_ADDITIONS_SETISNAVIGATINGTOAPPBOUNDDOMAIN
#endif
@@ -3095,23 +3094,11 @@
PolicyCheckIdentifier m_identifier;
};
-
-bool WebPageProxy::isAppBoundDomain(const WebCore::RegistrableDomain& domain) const
+void WebPageProxy::setIsNavigatingToAppBoundDomain(bool isMainFrame, const URL& requestURL, NavigatingToAppBoundDomain isNavigatingToAppBoundDomain)
{
- WEB_PAGE_PROXY_ADDITIONS_ISAPPBOUNDDOMAIN
- return true;
-}
-
-bool WebPageProxy::isAppBoundDomain(const URL& url) const
-{
- return isAppBoundDomain(RegistrableDomain(url));
-}
-
-void WebPageProxy::setIsNavigatingToAppBoundDomain(bool isMainFrame, const URL& requestURL)
-{
if (m_preferences->isInAppBrowserPrivacyEnabled() && isMainFrame) {
WEB_PAGE_PROXY_ADDITIONS_SETISNAVIGATINGTOAPPBOUNDDOMAIN
- if (!isAppBoundDomain(requestURL)) {
+ if (isNavigatingToAppBoundDomain == NavigatingToAppBoundDomain::No) {
m_configuration->setWebViewCategory(WebViewCategory::InAppBrowser);
m_isNavigatingToAppBoundDomain = NavigatingToAppBoundDomain::No;
m_hasNavigatedAwayFromAppBoundDomain = NavigatedAwayFromAppBoundDomain::Yes;
@@ -5013,8 +5000,6 @@
if (navigationID && !fromAPI)
m_pageLoadState.clearPendingAPIRequest(transaction);
- setIsNavigatingToAppBoundDomain(frame.isMainFrame(), request.url());
-
if (!checkURLReceivedFromCurrentOrPreviousWebProcess(process, request.url())) {
RELEASE_LOG_ERROR_IF_ALLOWED(Process, "Ignoring request to load this main resource because it is outside the sandbox");
sender->send(PolicyDecision { sender->identifier(), isNavigatingToAppBoundDomain(), hasNavigatedAwayFromAppBoundDomain(), PolicyAction::Ignore, 0, DownloadID(), WTF::nullopt });
@@ -5070,8 +5055,16 @@
if (!m_preferences->safeBrowsingEnabled())
shouldExpectSafeBrowsingResult = ShouldExpectSafeBrowsingResult::No;
- auto listener = makeRef(frame.setUpPolicyListenerProxy([this, protectedThis = makeRef(*this), frame = makeRef(frame), sender = WTFMove(sender), navigation] (PolicyAction policyAction, API::WebsitePolicies* policies, ProcessSwapRequestedByClient processSwapRequestedByClient, RefPtr<SafeBrowsingWarning>&& safeBrowsingWarning) mutable {
+ ShouldExpectAppBoundDomainResult shouldExpectAppBoundDomainResult = ShouldExpectAppBoundDomainResult::No;
+#if PLATFORM(COCOA)
+ shouldExpectAppBoundDomainResult = ShouldExpectAppBoundDomainResult::Yes;
+#endif
+
+ auto listener = makeRef(frame.setUpPolicyListenerProxy([this, protectedThis = makeRef(*this), frame = makeRef(frame), sender = WTFMove(sender), navigation] (PolicyAction policyAction, API::WebsitePolicies* policies, ProcessSwapRequestedByClient processSwapRequestedByClient, RefPtr<SafeBrowsingWarning>&& safeBrowsingWarning, NavigatingToAppBoundDomain isAppBoundDomain) mutable {
+ if (policyAction != PolicyAction::Ignore)
+ setIsNavigatingToAppBoundDomain(frame->isMainFrame(), navigation->currentRequest().url(), isAppBoundDomain);
+
auto completionHandler = [this, protectedThis = protectedThis.copyRef(), frame = frame.copyRef(), sender = WTFMove(sender), navigation, processSwapRequestedByClient, policies = makeRefPtr(policies)] (PolicyAction policyAction) mutable {
if (frame->isMainFrame()) {
if (!policies) {
@@ -5118,10 +5111,12 @@
}
completionHandler(policyAction);
- }, shouldExpectSafeBrowsingResult));
+ }, shouldExpectSafeBrowsingResult, shouldExpectAppBoundDomainResult));
if (shouldExpectSafeBrowsingResult == ShouldExpectSafeBrowsingResult::Yes)
beginSafeBrowsingCheck(request.url(), frame.isMainFrame(), listener);
-
+#if PLATFORM(COCOA)
+ m_websiteDataStore->beginAppBoundDomainCheck(RegistrableDomain { request.url() }, listener);
+#endif
API::Navigation* mainFrameNavigation = frame.isMainFrame() ? navigation.get() : nullptr;
WebFrameProxy* originatingFrame = originatingFrameInfoData.frameID ? process->webFrame(*originatingFrameInfoData.frameID) : nullptr;
@@ -5251,7 +5246,7 @@
MESSAGE_CHECK(m_process, frame);
MESSAGE_CHECK_URL(m_process, request.url());
- auto listener = makeRef(frame->setUpPolicyListenerProxy([this, protectedThis = makeRef(*this), identifier, listenerID, frameID] (PolicyAction policyAction, API::WebsitePolicies*, ProcessSwapRequestedByClient processSwapRequestedByClient, RefPtr<SafeBrowsingWarning>&& safeBrowsingWarning) mutable {
+ auto listener = makeRef(frame->setUpPolicyListenerProxy([this, protectedThis = makeRef(*this), identifier, listenerID, frameID] (PolicyAction policyAction, API::WebsitePolicies*, ProcessSwapRequestedByClient processSwapRequestedByClient, RefPtr<SafeBrowsingWarning>&& safeBrowsingWarning, NavigatingToAppBoundDomain isNavigatingToAppBoundDomain) mutable {
// FIXME: Assert the API::WebsitePolicies* is nullptr here once clients of WKFramePolicyListenerUseWithPolicies go away.
RELEASE_ASSERT(processSwapRequestedByClient == ProcessSwapRequestedByClient::No);
ASSERT_UNUSED(safeBrowsingWarning, !safeBrowsingWarning);
@@ -5261,7 +5256,7 @@
});
receivedPolicyDecision(policyAction, nullptr, WTF::nullopt, WTFMove(sender));
- }, ShouldExpectSafeBrowsingResult::No));
+ }, ShouldExpectSafeBrowsingResult::No, ShouldExpectAppBoundDomainResult::No));
if (m_policyClient)
m_policyClient->decidePolicyForNewWindowAction(*this, *frame, navigationActionData, request, frameName, WTFMove(listener), m_process->transformHandlesToObjects(userData.object()).get());
@@ -5297,10 +5292,9 @@
MESSAGE_CHECK(process, frame);
MESSAGE_CHECK_URL(process, request.url());
MESSAGE_CHECK_URL(process, response.url());
-
RefPtr<API::Navigation> navigation = navigationID ? m_navigationState->navigation(navigationID) : nullptr;
auto listener = makeRef(frame->setUpPolicyListenerProxy([this, protectedThis = makeRef(*this), webPageID, frameID, identifier, listenerID, navigation = WTFMove(navigation),
- process = process.copyRef()] (PolicyAction policyAction, API::WebsitePolicies*, ProcessSwapRequestedByClient processSwapRequestedByClient, RefPtr<SafeBrowsingWarning>&& safeBrowsingWarning) mutable {
+ process = process.copyRef()] (PolicyAction policyAction, API::WebsitePolicies*, ProcessSwapRequestedByClient processSwapRequestedByClient, RefPtr<SafeBrowsingWarning>&& safeBrowsingWarning, NavigatingToAppBoundDomain isNavigatingToAppBoundDomain) mutable {
// FIXME: Assert the API::WebsitePolicies* is nullptr here once clients of WKFramePolicyListenerUseWithPolicies go away.
RELEASE_ASSERT(processSwapRequestedByClient == ProcessSwapRequestedByClient::No);
ASSERT_UNUSED(safeBrowsingWarning, !safeBrowsingWarning);
@@ -5310,8 +5304,7 @@
});
receivedPolicyDecision(policyAction, navigation.get(), WTF::nullopt, WTFMove(sender));
- }, ShouldExpectSafeBrowsingResult::No));
-
+ }, ShouldExpectSafeBrowsingResult::No, ShouldExpectAppBoundDomainResult::No));
if (m_policyClient)
m_policyClient->decidePolicyForResponse(*this, *frame, response, request, canShowMIMEType, WTFMove(listener), process->transformHandlesToObjects(userData.object()).get());
else {
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (258053 => 258054)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.h 2020-03-07 04:32:32 UTC (rev 258053)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h 2020-03-07 04:48:50 UTC (rev 258054)
@@ -345,7 +345,7 @@
struct UserMessage;
enum class NegotiatedLegacyTLS : bool;
-enum class ProcessSwapRequestedByClient;
+enum class ProcessSwapRequestedByClient : bool;
enum class UndoOrRedo : bool;
enum class WebContentMode : uint8_t;
@@ -2265,9 +2265,7 @@
void tryCloseTimedOut();
void makeStorageSpaceRequest(WebCore::FrameIdentifier, const String& originIdentifier, const String& databaseName, const String& displayName, uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage, CompletionHandler<void(uint64_t)>&&);
- bool isAppBoundDomain(const WebCore::RegistrableDomain&) const;
- bool isAppBoundDomain(const URL&) const;
- void setIsNavigatingToAppBoundDomain(bool isMainFrame, const URL&);
+ void setIsNavigatingToAppBoundDomain(bool isMainFrame, const URL&, NavigatingToAppBoundDomain);
NavigatingToAppBoundDomain isNavigatingToAppBoundDomain() const { return m_isNavigatingToAppBoundDomain; }
NavigatedAwayFromAppBoundDomain hasNavigatedAwayFromAppBoundDomain() const { return m_hasNavigatedAwayFromAppBoundDomain; }
Modified: trunk/Source/WebKit/UIProcess/WebProcessPool.h (258053 => 258054)
--- trunk/Source/WebKit/UIProcess/WebProcessPool.h 2020-03-07 04:32:32 UTC (rev 258053)
+++ trunk/Source/WebKit/UIProcess/WebProcessPool.h 2020-03-07 04:48:50 UTC (rev 258054)
@@ -123,7 +123,7 @@
int webProcessThroughputQOS();
#endif
-enum class ProcessSwapRequestedByClient;
+enum class ProcessSwapRequestedByClient : bool;
class WebProcessPool final : public API::ObjectImpl<API::Object::Type::ProcessPool>, public CanMakeWeakPtr<WebProcessPool>, private IPC::MessageReceiver {
public:
Modified: trunk/Source/WebKit/UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm (258053 => 258054)
--- trunk/Source/WebKit/UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm 2020-03-07 04:32:32 UTC (rev 258053)
+++ trunk/Source/WebKit/UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm 2020-03-07 04:48:50 UTC (rev 258054)
@@ -29,6 +29,7 @@
#import "CookieStorageUtilsCF.h"
#import "SandboxUtilities.h"
#import "StorageManager.h"
+#import "WebFramePolicyListenerProxy.h"
#import "WebPreferencesKeys.h"
#import "WebResourceLoadStatisticsStore.h"
#import "WebsiteDataStoreParameters.h"
@@ -44,6 +45,12 @@
#import <wtf/URL.h>
#import <wtf/text/StringBuilder.h>
+#if USE(APPLE_INTERNAL_SDK)
+#include <WebKitAdditions/WebsiteDataStoreAdditions.h>
+#else
+#define WEBSITE_DATA_STORE_ADDITIONS
+#endif
+
#if PLATFORM(IOS_FAMILY)
#import <UIKit/UIApplication.h>
#import <pal/ios/ManagedConfigurationSoftLink.h>
@@ -61,6 +68,14 @@
static NSString * const WebKitNetworkLoadThrottleLatencyMillisecondsDefaultsKey = @"WebKitNetworkLoadThrottleLatencyMilliseconds";
+static WorkQueue& appBoundDomainQueue()
+{
+ static auto& queue = WorkQueue::create("com.apple.WebKit.AppBoundDomains", WorkQueue::Type::Serial).leakRef();
+ return queue;
+}
+
+static std::atomic<bool> hasInitializedAppBoundDomains = false;
+
#if ENABLE(RESOURCE_LOAD_STATISTICS)
WebCore::ThirdPartyCookieBlockingMode WebsiteDataStore::thirdPartyCookieBlockingMode() const
{
@@ -244,6 +259,8 @@
{
ASSERT(!dataStores().contains(this));
dataStores().add(this);
+
+ initializeAppBoundDomains();
}
void WebsiteDataStore::platformDestroy()
@@ -419,4 +436,75 @@
return url.absoluteURL.path.fileSystemRepresentation;
}
+static HashSet<WebCore::RegistrableDomain>& appBoundDomains()
+{
+ ASSERT(RunLoop::isMain());
+ static NeverDestroyed<HashSet<WebCore::RegistrableDomain>> appBoundDomains;
+ return appBoundDomains;
}
+
+void WebsiteDataStore::initializeAppBoundDomains()
+{
+ ASSERT(RunLoop::isMain());
+
+ if (hasInitializedAppBoundDomains)
+ return;
+
+ static const auto maxAppBoundDomainCount = 10;
+
+ appBoundDomainQueue().dispatch([] () mutable {
+ if (hasInitializedAppBoundDomains)
+ return;
+
+ NSArray<NSString *> *domains = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"WKAppBoundDomains"];
+
+ RunLoop::main().dispatch([domains = retainPtr(domains)] {
+ for (NSString *domain in domains.get()) {
+ URL url { URL(), domain };
+ if (!url.isValid())
+ continue;
+ WebCore::RegistrableDomain appBoundDomain { url };
+ if (appBoundDomain.isEmpty())
+ continue;
+ appBoundDomains().add(appBoundDomain);
+ if (appBoundDomains().size() >= maxAppBoundDomainCount)
+ break;
+ }
+ WEBSITE_DATA_STORE_ADDITIONS
+ hasInitializedAppBoundDomains = true;
+ });
+ });
+}
+
+void WebsiteDataStore::ensureAppBoundDomains(CompletionHandler<void(const HashSet<WebCore::RegistrableDomain>&)>&& completionHandler) const
+{
+ if (hasInitializedAppBoundDomains) {
+ completionHandler(appBoundDomains());
+ return;
+ }
+
+ appBoundDomainQueue().dispatch([completionHandler = WTFMove(completionHandler)] () mutable {
+ RunLoop::main().dispatch([completionHandler = WTFMove(completionHandler)] () mutable {
+ ASSERT(hasInitializedAppBoundDomains);
+ completionHandler(appBoundDomains());
+ });
+ });
+}
+
+void WebsiteDataStore::beginAppBoundDomainCheck(WebCore::RegistrableDomain&& domain, WebFramePolicyListenerProxy& listener)
+{
+ ASSERT(RunLoop::isMain());
+
+ ensureAppBoundDomains([domain = WTFMove(domain), listener = makeRef(listener)] (auto& domains) mutable {
+ listener->didReceiveAppBoundDomainResult(domains.contains(domain));
+ });
+}
+
+void WebsiteDataStore::appBoundDomainsForTesting(CompletionHandler<void(const HashSet<WebCore::RegistrableDomain>&)>&& completionHandler) const
+{
+ ensureAppBoundDomains([completionHandler = WTFMove(completionHandler)] (auto& domains) mutable {
+ completionHandler(domains);
+ });
+}
+
+}
Modified: trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h (258053 => 258054)
--- trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h 2020-03-07 04:32:32 UTC (rev 258053)
+++ trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h 2020-03-07 04:48:50 UTC (rev 258054)
@@ -28,6 +28,7 @@
#include "LocalStorageDatabaseTracker.h"
#include "NetworkSessionCreationParameters.h"
#include "WebDeviceOrientationAndMotionAccessController.h"
+#include "WebFramePolicyListenerProxy.h"
#include "WebPageProxyIdentifier.h"
#include "WebResourceLoadStatisticsStore.h"
#include "WebsiteDataStoreClient.h"
@@ -282,7 +283,12 @@
void hasAppBoundSession(CompletionHandler<void(bool)>&&) const;
void setInAppBrowserPrivacyEnabled(bool enabled, CompletionHandler<void()>&&);
+ void beginAppBoundDomainCheck(WebCore::RegistrableDomain&&, WebFramePolicyListenerProxy&);
+ void appBoundDomainsForTesting(CompletionHandler<void(const HashSet<WebCore::RegistrableDomain>&)>&&) const;
+ void ensureAppBoundDomains(CompletionHandler<void(const HashSet<WebCore::RegistrableDomain>&)>&&) const;
+
private:
+ void initializeAppBoundDomains();
void fetchDataAndApply(OptionSet<WebsiteDataType>, OptionSet<WebsiteDataFetchOption>, RefPtr<WorkQueue>&&, Function<void(Vector<WebsiteDataRecord>)>&& apply);
void platformInitialize();
Modified: trunk/Tools/ChangeLog (258053 => 258054)
--- trunk/Tools/ChangeLog 2020-03-07 04:32:32 UTC (rev 258053)
+++ trunk/Tools/ChangeLog 2020-03-07 04:48:50 UTC (rev 258054)
@@ -1,3 +1,18 @@
+2020-03-06 Kate Cheney <[email protected]>
+
+ UIProcess needs mechanism to specify AppBound domains
+ https://bugs.webkit.org/show_bug.cgi?id=208528
+ <rdar://problem/59980340>
+
+ Reviewed by Brent Fulgham.
+
+ Added test app-bound domains to the plist and tested that the domains
+ are properly stored in the website data store after a navigation.
+
+ * TestWebKitAPI/Info.plist:
+ * TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm:
+ (TEST):
+
2020-03-06 Alex Christensen <[email protected]>
Add SPI to disable cross origin access control checks
Modified: trunk/Tools/TestWebKitAPI/Info.plist (258053 => 258054)
--- trunk/Tools/TestWebKitAPI/Info.plist 2020-03-07 04:32:32 UTC (rev 258053)
+++ trunk/Tools/TestWebKitAPI/Info.plist 2020-03-07 04:48:50 UTC (rev 258054)
@@ -2,6 +2,25 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
+ <key>WKAppBoundDomains</key>
+ <array>
+ <string>testDomain1</string>
+ <string>https://sub.domain.webkit.org/road/to/nowhere/</string>
+ <string>https://webkit.org</string>
+ <string>https://localhost:8000</string>
+ <string>http://localhost/road/to/nowhere/</string>
+ <string>file:///some/file</string>
+ <string>127.0.0.1</string>
+ <string></string>
+ <string> </string>
+ <string>https://sub.domain.webkit.org</string>
+ <string>https://www.apple.com/</string>
+ <string>https://webkit.org</string>
+ <string>https://www.apple.com/iphone/</string>
+ <string>http://www.example.com/</string>
+ <string>http://bar.com/</string>
+ <string>http://foo.com/</string>
+ </array>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundleIdentifier</key>
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm (258053 => 258054)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm 2020-03-07 04:32:32 UTC (rev 258053)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm 2020-03-07 04:48:50 UTC (rev 258054)
@@ -29,13 +29,17 @@
#import "TestNavigationDelegate.h"
#import "TestWKWebView.h"
#import "WKWebViewConfigurationExtras.h"
+#import <WebCore/RegistrableDomain.h>
+#import <WebCore/RuntimeApplicationChecks.h>
#import <WebKit/WKPreferencesPrivate.h>
#import <WebKit/WKUserContentControllerPrivate.h>
+#import <WebKit/WKWebsiteDataStorePrivate.h>
#import <wtf/text/WTFString.h>
+static bool isDone;
+
#if USE(APPLE_INTERNAL_SDK)
-static bool isDone;
static NSString * const userScriptSource = @"window.wkUserScriptInjected = true";
@interface TestInAppBrowserScriptMessageHandler : NSObject <WKScriptMessageHandler>
@@ -50,7 +54,7 @@
@end
-TEST(WebKit, NonAppBoundDomainFailedUserScripts)
+TEST(InAppBrowserPrivacy, NonAppBoundDomainFailedUserScripts)
{
auto messageHandler = adoptNS([[TestInAppBrowserScriptMessageHandler alloc] init]);
auto userScript = adoptNS([[WKUserScript alloc] initWithSource:userScriptSource injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:YES]);
@@ -95,7 +99,7 @@
TestWebKitAPI::Util::run(&isDone);
}
-TEST(WebKit, NonAppBoundDomainFailedUserAgentScripts)
+TEST(InAppBrowserPrivacy, NonAppBoundDomainFailedUserAgentScripts)
{
WKWebViewConfiguration *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals" configureJSCForTesting:YES];
[[configuration preferences] _setInAppBrowserPrivacyEnabled:NO];
@@ -132,7 +136,7 @@
TestWebKitAPI::Util::run(&isDone);
}
-TEST(WebKit, SwapBackToAppBoundRejectsUserScript)
+TEST(InAppBrowserPrivacy, SwapBackToAppBoundRejectsUserScript)
{
auto messageHandler = adoptNS([[TestInAppBrowserScriptMessageHandler alloc] init]);
auto userScript = adoptNS([[WKUserScript alloc] initWithSource:userScriptSource injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:YES]);
@@ -176,3 +180,22 @@
}
#endif // USE(APPLE_INTERNAL_SDK)
+
+TEST(InAppBrowserPrivacy, AppBoundDomains)
+{
+ isDone = false;
+ [[WKWebsiteDataStore defaultDataStore] _appBoundDomains:^(NSArray<NSString *> *domains) {
+ NSArray *domainsToCompare = [NSArray arrayWithObjects:@"apple.com", @"bar.com", @"example.com", @"foo.com", @"localhost", @"webkit.org", nil];
+
+ NSArray *sortedDomains = [domains sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
+
+ int length = [sortedDomains count];
+ EXPECT_EQ(length, 6);
+ for (int i = 0; i < length; i++)
+ EXPECT_WK_STREQ([sortedDomains objectAtIndex:i], [domainsToCompare objectAtIndex:i]);
+
+ isDone = true;
+ }];
+ TestWebKitAPI::Util::run(&isDone);
+}
+