Diff
Modified: trunk/Source/WebCore/ChangeLog (261505 => 261506)
--- trunk/Source/WebCore/ChangeLog 2020-05-11 23:46:47 UTC (rev 261505)
+++ trunk/Source/WebCore/ChangeLog 2020-05-11 23:59:40 UTC (rev 261506)
@@ -1,3 +1,28 @@
+2020-05-11 Kate Cheney <[email protected]>
+
+ Fail navigations to non app-bound domains after use of app-bound APIs
+ https://bugs.webkit.org/show_bug.cgi?id=211647
+ <rdar://problem/62978159>
+
+ Reviewed by Brent Fulgham.
+
+ Simplified in-app browser privacy protections check into one, better
+ named function.
+
+ * bindings/js/ScriptController.cpp:
+ (WebCore::ScriptController::executeScriptInWorld):
+ * loader/FrameLoaderClient.h:
+ * page/Frame.cpp:
+ (WebCore::Frame::injectUserScriptImmediately):
+ * page/Page.cpp:
+ (WebCore::Page::injectUserStyleSheet):
+ * page/WebKitNamespace.cpp:
+ (WebCore::WebKitNamespace::messageHandlers):
+ * style/StyleScopeRuleSets.cpp:
+ (WebCore::Style::ScopeRuleSets::initializeUserStyle):
+ Rearranged ordering so the message to WebPageProxy only gets sent to
+ indicate app-bound behavior if user style sheets actually exist.
+
2020-05-11 Peng Liu <[email protected]>
Enable the mock video presentation mode in related layout tests and fix test failures
Modified: trunk/Source/WebCore/bindings/js/ScriptController.cpp (261505 => 261506)
--- trunk/Source/WebCore/bindings/js/ScriptController.cpp 2020-05-11 23:46:47 UTC (rev 261505)
+++ trunk/Source/WebCore/bindings/js/ScriptController.cpp 2020-05-11 23:59:40 UTC (rev 261506)
@@ -579,12 +579,13 @@
ValueOrException ScriptController::executeScriptInWorld(DOMWrapperWorld& world, RunJavaScriptParameters&& parameters)
{
- if (m_frame.loader().client().hasNavigatedAwayFromAppBoundDomain() && !m_frame.loader().client().needsInAppBrowserPrivacyQuirks()) {
+ if (m_frame.loader().client().shouldEnableInAppBrowserPrivacyProtections()) {
if (auto* document = m_frame.document())
document->addConsoleMessage(MessageSource::Security, MessageLevel::Warning, "Ignoring user script injection for non-app bound domain.");
RELEASE_LOG_ERROR_IF_ALLOWED(Loading, "executeScriptInWorld: Ignoring user script injection for non app-bound domain");
return makeUnexpected(ExceptionDetails { "Ignoring user script injection for non-app bound domain"_s });
}
+ m_frame.loader().client().notifyPageOfAppBoundBehavior();
UserGestureIndicator gestureIndicator(parameters.forceUserGesture == ForceUserGesture::Yes ? Optional<ProcessingUserGestureState>(ProcessingUserGesture) : WTF::nullopt);
Modified: trunk/Source/WebCore/loader/FrameLoaderClient.h (261505 => 261506)
--- trunk/Source/WebCore/loader/FrameLoaderClient.h 2020-05-11 23:46:47 UTC (rev 261505)
+++ trunk/Source/WebCore/loader/FrameLoaderClient.h 2020-05-11 23:59:40 UTC (rev 261506)
@@ -379,8 +379,8 @@
virtual AllowsContentJavaScript allowsContentJavaScriptFromMostRecentNavigation() const { return AllowsContentJavaScript::Yes; }
- virtual bool hasNavigatedAwayFromAppBoundDomain() { return false; }
- virtual bool needsInAppBrowserPrivacyQuirks() const { return false; }
+ virtual bool shouldEnableInAppBrowserPrivacyProtections() const { return false; }
+ virtual void notifyPageOfAppBoundBehavior() { }
};
} // namespace WebCore
Modified: trunk/Source/WebCore/page/Frame.cpp (261505 => 261506)
--- trunk/Source/WebCore/page/Frame.cpp 2020-05-11 23:46:47 UTC (rev 261505)
+++ trunk/Source/WebCore/page/Frame.cpp 2020-05-11 23:59:40 UTC (rev 261506)
@@ -651,12 +651,13 @@
void Frame::injectUserScriptImmediately(DOMWrapperWorld& world, const UserScript& script)
{
- if (loader().client().hasNavigatedAwayFromAppBoundDomain() && !loader().client().needsInAppBrowserPrivacyQuirks()) {
+ if (loader().client().shouldEnableInAppBrowserPrivacyProtections()) {
if (auto* document = this->document())
document->addConsoleMessage(MessageSource::Security, MessageLevel::Warning, "Ignoring user script injection for non-app bound domain."_s);
RELEASE_LOG_ERROR_IF_ALLOWED(Loading, "injectUserScriptImmediately: Ignoring user script injection for non app-bound domain");
return;
}
+ loader().client().notifyPageOfAppBoundBehavior();
auto* document = this->document();
if (!document)
Modified: trunk/Source/WebCore/page/Page.cpp (261505 => 261506)
--- trunk/Source/WebCore/page/Page.cpp 2020-05-11 23:46:47 UTC (rev 261505)
+++ trunk/Source/WebCore/page/Page.cpp 2020-05-11 23:59:40 UTC (rev 261506)
@@ -3162,11 +3162,12 @@
void Page::injectUserStyleSheet(UserStyleSheet& userStyleSheet)
{
- if (m_mainFrame->loader().client().hasNavigatedAwayFromAppBoundDomain()) {
+ if (m_mainFrame->loader().client().shouldEnableInAppBrowserPrivacyProtections()) {
if (auto* document = m_mainFrame->document())
document->addConsoleMessage(MessageSource::Security, MessageLevel::Warning, "Ignoring user style sheet for non-app bound domain."_s);
return;
}
+ m_mainFrame->loader().client().notifyPageOfAppBoundBehavior();
// We need to wait until we're no longer displaying the initial empty document before we can inject the stylesheets.
if (m_mainFrame->loader().stateMachine().isDisplayingInitialEmptyDocument()) {
Modified: trunk/Source/WebCore/page/WebKitNamespace.cpp (261505 => 261506)
--- trunk/Source/WebCore/page/WebKitNamespace.cpp 2020-05-11 23:46:47 UTC (rev 261505)
+++ trunk/Source/WebCore/page/WebKitNamespace.cpp 2020-05-11 23:59:40 UTC (rev 261506)
@@ -50,9 +50,12 @@
UserMessageHandlersNamespace* WebKitNamespace::messageHandlers()
{
- if (frame() && frame()->loader().client().hasNavigatedAwayFromAppBoundDomain()) {
- RELEASE_LOG_ERROR_IF_ALLOWED(Loading, "Ignoring messageHandlers() request for non app-bound domain");
- return nullptr;
+ if (frame()) {
+ if (frame()->loader().client().shouldEnableInAppBrowserPrivacyProtections()) {
+ RELEASE_LOG_ERROR_IF_ALLOWED(Loading, "Ignoring messageHandlers() request for non app-bound domain");
+ return nullptr;
+ }
+ frame()->loader().client().notifyPageOfAppBoundBehavior();
}
return &m_messageHandlerNamespace.get();
Modified: trunk/Source/WebCore/style/StyleScopeRuleSets.cpp (261505 => 261506)
--- trunk/Source/WebCore/style/StyleScopeRuleSets.cpp 2020-05-11 23:46:47 UTC (rev 261505)
+++ trunk/Source/WebCore/style/StyleScopeRuleSets.cpp 2020-05-11 23:59:40 UTC (rev 261506)
@@ -92,10 +92,13 @@
if (CSSStyleSheet* pageUserSheet = extensionStyleSheets.pageUserSheet())
tempUserStyle->addRulesFromSheet(pageUserSheet->contents(), nullptr, mediaQueryEvaluator, m_styleResolver);
auto* page = m_styleResolver.document().page();
- if (page && page->mainFrame().loader().client().hasNavigatedAwayFromAppBoundDomain() && !extensionStyleSheets.injectedUserStyleSheets().isEmpty())
+ if (!extensionStyleSheets.injectedUserStyleSheets().isEmpty() && page && page->mainFrame().loader().client().shouldEnableInAppBrowserPrivacyProtections())
m_styleResolver.document().addConsoleMessage(MessageSource::Security, MessageLevel::Warning, "Ignoring user style sheet for non-app bound domain."_s);
- else
+ else {
collectRulesFromUserStyleSheets(extensionStyleSheets.injectedUserStyleSheets(), tempUserStyle.get(), mediaQueryEvaluator);
+ if (page && !extensionStyleSheets.injectedUserStyleSheets().isEmpty())
+ page->mainFrame().loader().client().notifyPageOfAppBoundBehavior();
+ }
collectRulesFromUserStyleSheets(extensionStyleSheets.documentUserStyleSheets(), tempUserStyle.get(), mediaQueryEvaluator);
if (tempUserStyle->ruleCount() > 0 || tempUserStyle->pageRules().size() > 0)
m_userStyle = WTFMove(tempUserStyle);
Modified: trunk/Source/WebKit/ChangeLog (261505 => 261506)
--- trunk/Source/WebKit/ChangeLog 2020-05-11 23:46:47 UTC (rev 261505)
+++ trunk/Source/WebKit/ChangeLog 2020-05-11 23:59:40 UTC (rev 261506)
@@ -1,3 +1,100 @@
+2020-05-11 Kate Cheney <[email protected]>
+
+ Fail navigations to non app-bound domains after use of app-bound APIs
+ https://bugs.webkit.org/show_bug.cgi?id=211647
+ <rdar://problem/62978159>
+
+ Reviewed by Brent Fulgham.
+
+ A lot of this patch is deleting the unnecessary variable/function
+ hasNavigatedAwayFromAppBoundDomain now that navigating away from an
+ app-bound domain is not possible.
+
+ To address the bug, this sets the default isNavigatingToAppBoundDomain
+ value to be WTF::nullopt. This will allow app-bound behaviors until
+ a navigation has been attempted, in which case it will fail or will
+ update isNavigatingToAppBoundDomain to the correct value.
+
+
+ * Shared/LoadParameters.cpp:
+ (WebKit::LoadParameters::encode const):
+ (WebKit::LoadParameters::decode):
+ * Shared/LoadParameters.h:
+ * Shared/PolicyDecision.h:
+ (WebKit::PolicyDecision::encode const):
+ (WebKit::PolicyDecision::decode):
+ * UIProcess/ProvisionalPageProxy.cpp:
+ (WebKit::ProvisionalPageProxy::loadData):
+ (WebKit::ProvisionalPageProxy::loadRequest):
+ (WebKit::ProvisionalPageProxy::decidePolicyForNavigationActionSync):
+ * UIProcess/ProvisionalPageProxy.h:
+ * UIProcess/WebPageProxy.cpp:
+ (WebKit::WebPageProxy::loadRequest):
+ (WebKit::WebPageProxy::loadRequestWithNavigationShared):
+ (WebKit::WebPageProxy::loadData):
+ (WebKit::WebPageProxy::loadDataWithNavigationShared):
+ (WebKit::WebPageProxy::receivedPolicyDecision):
+ (WebKit::WebPageProxy::continueNavigationInNewProcess):
+ (WebKit::WebPageProxy::decidePolicyForNavigationActionSyncShared):
+ (WebKit::WebPageProxy::hasNavigatedAwayFromAppBoundDomain const): Deleted.
+ Remove hasNavigatedAwayFromAppBoundDomain.
+
+ (WebKit::WebPageProxy::setIsNavigatingToAppBoundDomainAndCheckIfPermitted):
+ Check for new m_hasExecutedAppBoundBehaviorBeforeNavigation parameter
+ and fail the navigation if a WebView has used app-bound behavior then
+ tries to navigate to a non app-bound domain.
+
+ (WebKit::WebPageProxy::decidePolicyForNavigationAction):
+ Update error message to be more general now that more than one error
+ can occur.
+
+ * UIProcess/WebPageProxy.h:
+ (WebKit::WebPageProxy::setHasExecutedAppBoundBehaviorBeforeNavigation):
+ * UIProcess/WebPageProxy.messages.in:
+ New parameter to indicate a WebView has used app-bound APIs before
+ navigating.
+
+ * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
+ (WebKit::WebFrameLoaderClient::dispatchDecidePolicyForResponse):
+ (WebKit::WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction):
+ (WebKit::WebFrameLoaderClient::shouldEnableInAppBrowserPrivacyProtections):
+ (WebKit::WebFrameLoaderClient::hasNavigatedAwayFromAppBoundDomain): Deleted.
+ (WebKit::WebFrameLoaderClient::needsInAppBrowserPrivacyQuirks const): Deleted.
+ * WebProcess/WebCoreSupport/WebFrameLoaderClient.h:
+ Combined two functions into a simpler function:
+ shouldEnableInAppBrowserPrivacyProtections().
+
+ * WebProcess/WebPage/WebPage.cpp:
+ (WebKit::m_limitsNavigationsToAppBoundDomains):
+ (WebKit::WebPage::updatePreferences):
+ Store the special app-bound domain flag to gate the service worker
+ API. This should be stored separately from
+ m_isNavigatingToAppBoundDomain, because in the WebPage constructor we
+ don't yet know whether the WKAppBoundDomains key exists.
+
+ (WebKit::WebPage::loadRequest):
+ (WebKit::WebPage::loadDataImpl):
+ (WebKit::WebPage::loadData):
+ (WebKit::WebPage::loadAlternateHTML):
+ (WebKit::WebPage::didReceivePolicyDecision):
+ Remove hasNavigatedAwayFromAppBoundDomain.
+
+ (WebKit::WebPage::runJavaScript):
+ (WebKit::WebPage::setIsNavigatingToAppBoundDomain):
+ (WebKit::WebPage::shouldEnableInAppBrowserPrivacyProtections):
+ If m_needsInAppBrowserPrivacyQuirks are on for testing, don't enable
+ protections. Only notify the WebPageProxy of app-bound behavior if
+ a navigation has not occured and we know the webView is not app-bound
+ (in order to limit IPC).
+
+ (WebKit::m_isNavigatingToAppBoundDomain): Deleted.
+ * WebProcess/WebPage/WebPage.h:
+ (WebKit::WebPage::isNavigatingToAppBoundDomain const):
+ (WebKit::WebPage::setIsNavigatingToAppBoundDomain): Deleted.
+ (WebKit::WebPage::hasNavigatedAwayFromAppBoundDomain const): Deleted.
+ (WebKit::WebPage::setHasNavigatedAwayFromAppBoundDomain): Deleted.
+ (WebKit::WebPage::needsInAppBrowserPrivacyQuirks const): Deleted.
+
2020-05-11 Wenson Hsieh <[email protected]>
Remove some unnecessary indirection when getting Document’s Editor
Modified: trunk/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm (261505 => 261506)
--- trunk/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm 2020-05-11 23:46:47 UTC (rev 261505)
+++ trunk/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm 2020-05-11 23:59:40 UTC (rev 261506)
@@ -62,6 +62,7 @@
#import <WebKitAdditions/NetworkSessionCocoaAdditions.h>
#else
#define NETWORK_SESSION_COCOA_ADDITIONS_1
+#define NETWORK_SESSION_COCOA_ADDITIONS_2 true
#endif
#import "DeviceManagementSoftLink.h"
@@ -1260,6 +1261,8 @@
SessionWrapper& NetworkSessionCocoa::sessionWrapperForTask(const WebCore::ResourceRequest& request, WebCore::StoredCredentialsPolicy storedCredentialsPolicy, Optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain)
{
auto shouldBeConsideredAppBound = isNavigatingToAppBoundDomain ? *isNavigatingToAppBoundDomain : NavigatingToAppBoundDomain::Yes;
+ if (NETWORK_SESSION_COCOA_ADDITIONS_2)
+ shouldBeConsideredAppBound = NavigatingToAppBoundDomain::No;
#if ENABLE(RESOURCE_LOAD_STATISTICS)
if (auto* storageSession = networkStorageSession()) {
auto firstParty = WebCore::RegistrableDomain(request.firstPartyForCookies());
Modified: trunk/Source/WebKit/Shared/LoadParameters.cpp (261505 => 261506)
--- trunk/Source/WebKit/Shared/LoadParameters.cpp 2020-05-11 23:46:47 UTC (rev 261505)
+++ trunk/Source/WebKit/Shared/LoadParameters.cpp 2020-05-11 23:59:40 UTC (rev 261506)
@@ -57,7 +57,6 @@
encoder.encodeEnum(lockBackForwardList);
encoder << clientRedirectSourceForHistory;
encoder << isNavigatingToAppBoundDomain;
- encoder << hasNavigatedAwayFromAppBoundDomain;
platformEncode(encoder);
}
@@ -138,9 +137,6 @@
if (!decoder.decode(data.isNavigatingToAppBoundDomain))
return false;
- if (!decoder.decode(data.hasNavigatedAwayFromAppBoundDomain))
- return false;
-
if (!platformDecode(decoder, data))
return false;
Modified: trunk/Source/WebKit/Shared/LoadParameters.h (261505 => 261506)
--- trunk/Source/WebKit/Shared/LoadParameters.h 2020-05-11 23:46:47 UTC (rev 261505)
+++ trunk/Source/WebKit/Shared/LoadParameters.h 2020-05-11 23:59:40 UTC (rev 261506)
@@ -70,8 +70,7 @@
WebCore::LockHistory lockHistory { WebCore::LockHistory::No };
WebCore::LockBackForwardList lockBackForwardList { WebCore::LockBackForwardList::No };
String clientRedirectSourceForHistory;
- Optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain { NavigatingToAppBoundDomain::No };
- NavigatedAwayFromAppBoundDomain hasNavigatedAwayFromAppBoundDomain { NavigatedAwayFromAppBoundDomain::No };
+ Optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain;
#if PLATFORM(COCOA)
RetainPtr<NSDictionary> dataDetectionContext;
Modified: trunk/Source/WebKit/Shared/PolicyDecision.h (261505 => 261506)
--- trunk/Source/WebKit/Shared/PolicyDecision.h 2020-05-11 23:46:47 UTC (rev 261505)
+++ trunk/Source/WebKit/Shared/PolicyDecision.h 2020-05-11 23:59:40 UTC (rev 261506)
@@ -33,12 +33,9 @@
namespace WebKit {
-enum class NavigatedAwayFromAppBoundDomain : bool { Yes, No};
-
struct PolicyDecision {
WebCore::PolicyCheckIdentifier identifier { };
- Optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain { NavigatingToAppBoundDomain::No };
- NavigatedAwayFromAppBoundDomain hasNavigatedAwayFromAppBoundDomain { NavigatedAwayFromAppBoundDomain::No };
+ Optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain { WTF::nullopt };
WebCore::PolicyAction policyAction { WebCore::PolicyAction::Ignore };
uint64_t navigationID { 0 };
DownloadID downloadID { 0 };
@@ -50,7 +47,6 @@
{
encoder << identifier;
encoder << isNavigatingToAppBoundDomain;
- encoder << hasNavigatedAwayFromAppBoundDomain;
encoder << policyAction;
encoder << navigationID;
encoder << downloadID;
@@ -70,11 +66,6 @@
decoder >> decodedIsNavigatingToAppBoundDomain;
if (!decodedIsNavigatingToAppBoundDomain)
return WTF::nullopt;
-
- Optional<NavigatedAwayFromAppBoundDomain> decodedHasNavigatedAwayFromAppBoundDomain;
- decoder >> decodedHasNavigatedAwayFromAppBoundDomain;
- if (!decodedHasNavigatedAwayFromAppBoundDomain)
- return WTF::nullopt;
Optional<WebCore::PolicyAction> decodedPolicyAction;
decoder >> decodedPolicyAction;
@@ -101,7 +92,7 @@
if (!sandboxExtensionHandle)
return WTF::nullopt;
- return {{ WTFMove(*decodedIdentifier), WTFMove(*decodedIsNavigatingToAppBoundDomain), WTFMove(*decodedHasNavigatedAwayFromAppBoundDomain), WTFMove(*decodedPolicyAction), WTFMove(*decodedNavigationID), WTFMove(*decodedDownloadID), WTFMove(*decodedWebsitePoliciesData), WTFMove(*sandboxExtensionHandle)}};
+ return {{ WTFMove(*decodedIdentifier), WTFMove(*decodedIsNavigatingToAppBoundDomain), WTFMove(*decodedPolicyAction), WTFMove(*decodedNavigationID), WTFMove(*decodedDownloadID), WTFMove(*decodedWebsitePoliciesData), WTFMove(*sandboxExtensionHandle)}};
}
};
Modified: trunk/Source/WebKit/UIProcess/ProvisionalPageProxy.cpp (261505 => 261506)
--- trunk/Source/WebKit/UIProcess/ProvisionalPageProxy.cpp 2020-05-11 23:46:47 UTC (rev 261505)
+++ trunk/Source/WebKit/UIProcess/ProvisionalPageProxy.cpp 2020-05-11 23:59:40 UTC (rev 261506)
@@ -156,14 +156,14 @@
send(Messages::WebPage::FreezeLayerTreeDueToSwipeAnimation());
}
-void ProvisionalPageProxy::loadData(API::Navigation& navigation, const IPC::DataReference& data, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData, Optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain, NavigatedAwayFromAppBoundDomain hasNavigatedAwayFromAppBoundDomain, Optional<WebsitePoliciesData>&& websitePolicies)
+void ProvisionalPageProxy::loadData(API::Navigation& navigation, const IPC::DataReference& data, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData, Optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain, Optional<WebsitePoliciesData>&& websitePolicies)
{
RELEASE_LOG_IF_ALLOWED(ProcessSwapping, "loadData: pageProxyID=%" PRIu64 " webPageID=%" PRIu64, m_page.identifier().toUInt64(), m_webPageID.toUInt64());
- m_page.loadDataWithNavigationShared(m_process.copyRef(), m_webPageID, navigation, data, MIMEType, encoding, baseURL, userData, WebCore::ShouldTreatAsContinuingLoad::Yes, isNavigatingToAppBoundDomain, hasNavigatedAwayFromAppBoundDomain, WTFMove(websitePolicies), navigation.lastNavigationAction().shouldOpenExternalURLsPolicy);
+ m_page.loadDataWithNavigationShared(m_process.copyRef(), m_webPageID, navigation, data, MIMEType, encoding, baseURL, userData, WebCore::ShouldTreatAsContinuingLoad::Yes, isNavigatingToAppBoundDomain, WTFMove(websitePolicies), navigation.lastNavigationAction().shouldOpenExternalURLsPolicy);
}
-void ProvisionalPageProxy::loadRequest(API::Navigation& navigation, WebCore::ResourceRequest&& request, API::Object* userData, Optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain, NavigatedAwayFromAppBoundDomain hasNavigatedAwayFromAppBoundDomain, Optional<WebsitePoliciesData>&& websitePolicies)
+void ProvisionalPageProxy::loadRequest(API::Navigation& navigation, WebCore::ResourceRequest&& request, API::Object* userData, Optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain, Optional<WebsitePoliciesData>&& websitePolicies)
{
RELEASE_LOG_IF_ALLOWED(ProcessSwapping, "loadRequest: pageProxyID=%" PRIu64 " webPageID=%" PRIu64, m_page.identifier().toUInt64(), m_webPageID.toUInt64());
@@ -173,7 +173,7 @@
if (navigation.fromItem() && navigation.lockBackForwardList() == WebCore::LockBackForwardList::Yes)
navigation.fromItem()->setLastProcessIdentifier(m_process->coreProcessIdentifier());
- m_page.loadRequestWithNavigationShared(m_process.copyRef(), m_webPageID, navigation, WTFMove(request), navigation.lastNavigationAction().shouldOpenExternalURLsPolicy, userData, WebCore::ShouldTreatAsContinuingLoad::Yes, isNavigatingToAppBoundDomain, hasNavigatedAwayFromAppBoundDomain, WTFMove(websitePolicies));
+ m_page.loadRequestWithNavigationShared(m_process.copyRef(), m_webPageID, navigation, WTFMove(request), navigation.lastNavigationAction().shouldOpenExternalURLsPolicy, userData, WebCore::ShouldTreatAsContinuingLoad::Yes, isNavigatingToAppBoundDomain, WTFMove(websitePolicies));
}
void ProvisionalPageProxy::goToBackForwardItem(API::Navigation& navigation, WebBackForwardListItem& item, RefPtr<API::WebsitePolicies>&& websitePolicies)
@@ -357,7 +357,7 @@
const UserData& userData, Messages::WebPageProxy::DecidePolicyForNavigationActionSync::DelayedReply&& reply)
{
if (!isMainFrame || (m_mainFrame && m_mainFrame->frameID() != frameID) || navigationID != m_navigationID) {
- reply(PolicyDecision { identifier, NavigatingToAppBoundDomain::No, NavigatedAwayFromAppBoundDomain::No, WebCore::PolicyAction::Ignore, navigationID, DownloadID(), WTF::nullopt });
+ reply(PolicyDecision { identifier, WTF::nullopt, WebCore::PolicyAction::Ignore, navigationID, DownloadID(), WTF::nullopt });
return;
}
Modified: trunk/Source/WebKit/UIProcess/ProvisionalPageProxy.h (261505 => 261506)
--- trunk/Source/WebKit/UIProcess/ProvisionalPageProxy.h 2020-05-11 23:46:47 UTC (rev 261505)
+++ trunk/Source/WebKit/UIProcess/ProvisionalPageProxy.h 2020-05-11 23:59:40 UTC (rev 261506)
@@ -92,8 +92,8 @@
LayerHostingContextID contextIDForVisibilityPropagation() const { return m_contextIDForVisibilityPropagation; }
#endif
- void loadData(API::Navigation&, const IPC::DataReference&, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData, Optional<NavigatingToAppBoundDomain>, NavigatedAwayFromAppBoundDomain, Optional<WebsitePoliciesData>&& = WTF::nullopt);
- void loadRequest(API::Navigation&, WebCore::ResourceRequest&&, API::Object* userData, Optional<NavigatingToAppBoundDomain>, NavigatedAwayFromAppBoundDomain, Optional<WebsitePoliciesData>&& = WTF::nullopt);
+ void loadData(API::Navigation&, const IPC::DataReference&, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData, Optional<NavigatingToAppBoundDomain>, Optional<WebsitePoliciesData>&& = WTF::nullopt);
+ void loadRequest(API::Navigation&, WebCore::ResourceRequest&&, API::Object* userData, Optional<NavigatingToAppBoundDomain>, Optional<WebsitePoliciesData>&& = WTF::nullopt);
void goToBackForwardItem(API::Navigation&, WebBackForwardListItem&, RefPtr<API::WebsitePolicies>&&);
void cancel();
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (261505 => 261506)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2020-05-11 23:46:47 UTC (rev 261505)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2020-05-11 23:59:40 UTC (rev 261506)
@@ -1281,11 +1281,11 @@
if (shouldForceForegroundPriorityForClientNavigation())
navigation->setClientNavigationActivity(process().throttler().foregroundActivity("Client navigation"_s));
- loadRequestWithNavigationShared(m_process.copyRef(), m_webPageID, navigation.get(), WTFMove(request), shouldOpenExternalURLsPolicy, userData, ShouldTreatAsContinuingLoad::No, isNavigatingToAppBoundDomain(), hasNavigatedAwayFromAppBoundDomain());
+ loadRequestWithNavigationShared(m_process.copyRef(), m_webPageID, navigation.get(), WTFMove(request), shouldOpenExternalURLsPolicy, userData, ShouldTreatAsContinuingLoad::No, isNavigatingToAppBoundDomain());
return navigation;
}
-void WebPageProxy::loadRequestWithNavigationShared(Ref<WebProcessProxy>&& process, WebCore::PageIdentifier webPageID, API::Navigation& navigation, ResourceRequest&& request, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy, API::Object* userData, ShouldTreatAsContinuingLoad shouldTreatAsContinuingLoad, Optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain, NavigatedAwayFromAppBoundDomain hasNavigatedAwayFromAppBoundDomain, Optional<WebsitePoliciesData>&& websitePolicies)
+void WebPageProxy::loadRequestWithNavigationShared(Ref<WebProcessProxy>&& process, WebCore::PageIdentifier webPageID, API::Navigation& navigation, ResourceRequest&& request, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy, API::Object* userData, ShouldTreatAsContinuingLoad shouldTreatAsContinuingLoad, Optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain, Optional<WebsitePoliciesData>&& websitePolicies)
{
ASSERT(!m_isClosed);
@@ -1308,7 +1308,6 @@
loadParameters.lockBackForwardList = navigation.lockBackForwardList();
loadParameters.clientRedirectSourceForHistory = navigation.clientRedirectSourceForHistory();
loadParameters.isNavigatingToAppBoundDomain = isNavigatingToAppBoundDomain;
- loadParameters.hasNavigatedAwayFromAppBoundDomain = hasNavigatedAwayFromAppBoundDomain;
maybeInitializeSandboxExtensionHandle(process, url, m_pageLoadState.resourceDirectoryURL(), loadParameters.sandboxExtensionHandle);
addPlatformLoadParameters(loadParameters);
@@ -1405,11 +1404,11 @@
if (shouldForceForegroundPriorityForClientNavigation())
navigation->setClientNavigationActivity(process().throttler().foregroundActivity("Client navigation"_s));
- loadDataWithNavigationShared(m_process.copyRef(), m_webPageID, navigation, data, MIMEType, encoding, baseURL, userData, ShouldTreatAsContinuingLoad::No, isNavigatingToAppBoundDomain(), hasNavigatedAwayFromAppBoundDomain(), WTF::nullopt, shouldOpenExternalURLsPolicy);
+ loadDataWithNavigationShared(m_process.copyRef(), m_webPageID, navigation, data, MIMEType, encoding, baseURL, userData, ShouldTreatAsContinuingLoad::No, isNavigatingToAppBoundDomain(), WTF::nullopt, shouldOpenExternalURLsPolicy);
return navigation;
}
-void WebPageProxy::loadDataWithNavigationShared(Ref<WebProcessProxy>&& process, WebCore::PageIdentifier webPageID, API::Navigation& navigation, const IPC::DataReference& data, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData, ShouldTreatAsContinuingLoad shouldTreatAsContinuingLoad, Optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain, NavigatedAwayFromAppBoundDomain hasNavigatedAwayFromAppBoundDomain, Optional<WebsitePoliciesData>&& websitePolicies, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy)
+void WebPageProxy::loadDataWithNavigationShared(Ref<WebProcessProxy>&& process, WebCore::PageIdentifier webPageID, API::Navigation& navigation, const IPC::DataReference& data, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData, ShouldTreatAsContinuingLoad shouldTreatAsContinuingLoad, Optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain, Optional<WebsitePoliciesData>&& websitePolicies, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy)
{
RELEASE_LOG_IF_ALLOWED(Loading, "loadDataWithNavigation");
@@ -1430,7 +1429,6 @@
loadParameters.websitePolicies = WTFMove(websitePolicies);
loadParameters.shouldOpenExternalURLsPolicy = shouldOpenExternalURLsPolicy;
loadParameters.isNavigatingToAppBoundDomain = isNavigatingToAppBoundDomain;
- loadParameters.hasNavigatedAwayFromAppBoundDomain = hasNavigatedAwayFromAppBoundDomain;
addPlatformLoadParameters(loadParameters);
process->assumeReadAccessToBaseURL(*this, baseURL);
@@ -3131,9 +3129,10 @@
m_configuration->setWebViewCategory(WebViewCategory::AppBoundDomain);
m_isNavigatingToAppBoundDomain = NavigatingToAppBoundDomain::Yes;
} else {
+ if (m_hasExecutedAppBoundBehaviorBeforeNavigation)
+ return false;
m_configuration->setWebViewCategory(WebViewCategory::InAppBrowser);
m_isNavigatingToAppBoundDomain = NavigatingToAppBoundDomain::No;
- m_hasNavigatedAwayFromAppBoundDomain = NavigatedAwayFromAppBoundDomain::Yes;
}
}
#else
@@ -3275,7 +3274,7 @@
void WebPageProxy::receivedPolicyDecision(PolicyAction action, API::Navigation* navigation, RefPtr<API::WebsitePolicies>&& websitePolicies, Ref<PolicyDecisionSender>&& sender, Optional<SandboxExtension::Handle> sandboxExtensionHandle, WillContinueLoadInNewProcess willContinueLoadInNewProcess)
{
if (!hasRunningProcess()) {
- sender->send(PolicyDecision { sender->identifier(), isNavigatingToAppBoundDomain(), hasNavigatedAwayFromAppBoundDomain(), PolicyAction::Ignore, 0, DownloadID(), WTF::nullopt });
+ sender->send(PolicyDecision { sender->identifier(), isNavigatingToAppBoundDomain(), PolicyAction::Ignore, 0, DownloadID(), WTF::nullopt });
return;
}
@@ -3302,7 +3301,7 @@
if (websitePolicies)
websitePoliciesData = websitePolicies->data();
- sender->send(PolicyDecision { sender->identifier(), isNavigatingToAppBoundDomain(), hasNavigatedAwayFromAppBoundDomain(), action, navigation ? navigation->navigationID() : 0, downloadID, WTFMove(websitePoliciesData), WTFMove(sandboxExtensionHandle) });
+ sender->send(PolicyDecision { sender->identifier(), isNavigatingToAppBoundDomain(), action, navigation ? navigation->navigationID() : 0, downloadID, WTFMove(websitePoliciesData), WTFMove(sandboxExtensionHandle) });
}
void WebPageProxy::commitProvisionalPage(FrameIdentifier frameID, FrameInfoData&& frameInfo, ResourceRequest&& request, uint64_t navigationID, const String& mimeType, bool frameHasCustomContentProvider, uint32_t frameLoadType, const WebCore::CertificateInfo& certificateInfo, bool usedLegacyTLS, bool containsPluginDocument, Optional<WebCore::HasInsecureContent> forcedHasInsecureContent, const UserData& userData)
@@ -3383,9 +3382,9 @@
// FIXME: Work out timing of responding with the last policy delegate, etc
ASSERT(!navigation->currentRequest().isEmpty());
if (auto& substituteData = navigation->substituteData())
- m_provisionalPage->loadData(navigation, { substituteData->content.data(), substituteData->content.size() }, substituteData->MIMEType, substituteData->encoding, substituteData->baseURL, substituteData->userData.get(), isNavigatingToAppBoundDomain(), hasNavigatedAwayFromAppBoundDomain(), WTFMove(websitePoliciesData));
+ m_provisionalPage->loadData(navigation, { substituteData->content.data(), substituteData->content.size() }, substituteData->MIMEType, substituteData->encoding, substituteData->baseURL, substituteData->userData.get(), isNavigatingToAppBoundDomain(), WTFMove(websitePoliciesData));
else
- m_provisionalPage->loadRequest(navigation, ResourceRequest { navigation->currentRequest() }, nullptr, isNavigatingToAppBoundDomain(), hasNavigatedAwayFromAppBoundDomain(), WTFMove(websitePoliciesData));
+ m_provisionalPage->loadRequest(navigation, ResourceRequest { navigation->currentRequest() }, nullptr, isNavigatingToAppBoundDomain(), WTFMove(websitePoliciesData));
};
if (m_inspectorController->shouldPauseLoading(*m_provisionalPage))
m_inspectorController->setContinueLoadingCallback(*m_provisionalPage, WTFMove(continuation));
@@ -5107,7 +5106,7 @@
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 });
+ sender->send(PolicyDecision { sender->identifier(), isNavigatingToAppBoundDomain(), PolicyAction::Ignore, 0, DownloadID(), WTF::nullopt });
return;
}
@@ -5181,9 +5180,9 @@
if (policyAction != PolicyAction::Ignore) {
if (!setIsNavigatingToAppBoundDomainAndCheckIfPermitted(frame->isMainFrame(), navigation->currentRequest().url(), isAppBoundDomain)) {
- auto error = ResourceError { String { }, 0, navigation->currentRequest().url(), "Attempted navigation away from app-bound domain"_s };
+ auto error = ResourceError { String { }, 0, navigation->currentRequest().url(), "App-bound domain failure"_s };
m_navigationClient->didFailProvisionalNavigationWithError(*this, FrameInfoData { frameInfo }, navigation.get(), error, userDataObject);
- RELEASE_LOG_ERROR_IF_ALLOWED(Loading, "Ignoring request to load this main resource because it is attempting to navigate away from an app-bound domain");
+ RELEASE_LOG_ERROR_IF_ALLOWED(Loading, "Ignoring request to load this main resource because it is attempting to navigate away from an app-bound domain or navigate after using restricted APIs");
completionHandler(PolicyAction::Ignore);
return;
}
@@ -5355,7 +5354,7 @@
decidePolicyForNavigationAction(WTFMove(process), *frame, WTFMove(frameInfo), navigationID, WTFMove(navigationActionData), WTFMove(originatingFrameInfo), originatingPageID, originalRequest, WTFMove(request), WTFMove(requestBody), WTFMove(redirectResponse), userData, sender.copyRef());
// If the client did not respond synchronously, proceed with the load.
- sender->send(PolicyDecision { sender->identifier(), isNavigatingToAppBoundDomain(), hasNavigatedAwayFromAppBoundDomain(), PolicyAction::Use, navigationID, DownloadID(), WTF::nullopt });
+ sender->send(PolicyDecision { sender->identifier(), isNavigatingToAppBoundDomain(), PolicyAction::Use, navigationID, DownloadID(), WTF::nullopt });
}
void WebPageProxy::decidePolicyForNewWindowAction(FrameIdentifier frameID, FrameInfoData&& frameInfo, PolicyCheckIdentifier identifier, NavigationActionData&& navigationActionData, ResourceRequest&& request, const String& frameName, uint64_t listenerID, const UserData& userData)
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (261505 => 261506)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.h 2020-05-11 23:46:47 UTC (rev 261505)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h 2020-05-11 23:59:40 UTC (rev 261506)
@@ -1650,8 +1650,8 @@
void decidePolicyForNavigationActionAsyncShared(Ref<WebProcessProxy>&&, WebCore::PageIdentifier, WebCore::FrameIdentifier, FrameInfoData&&, WebCore::PolicyCheckIdentifier, uint64_t navigationID, NavigationActionData&&, FrameInfoData&& originatingFrameInfo, Optional<WebPageProxyIdentifier> originatingPageID, const WebCore::ResourceRequest& originalRequest, WebCore::ResourceRequest&&, IPC::FormDataReference&& requestBody, WebCore::ResourceResponse&& redirectResponse, const UserData&, uint64_t listenerID);
void decidePolicyForResponseShared(Ref<WebProcessProxy>&&, WebCore::PageIdentifier, WebCore::FrameIdentifier, FrameInfoData&&, WebCore::PolicyCheckIdentifier, uint64_t navigationID, const WebCore::ResourceResponse&, const WebCore::ResourceRequest&, bool canShowMIMEType, const String& downloadAttribute, uint64_t listenerID, const UserData&);
void startURLSchemeTaskShared(Ref<WebProcessProxy>&&, WebCore::PageIdentifier, URLSchemeTaskParameters&&);
- void loadDataWithNavigationShared(Ref<WebProcessProxy>&&, WebCore::PageIdentifier, API::Navigation&, const IPC::DataReference&, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData, WebCore::ShouldTreatAsContinuingLoad, Optional<NavigatingToAppBoundDomain>, NavigatedAwayFromAppBoundDomain, Optional<WebsitePoliciesData>&& = WTF::nullopt, WebCore::ShouldOpenExternalURLsPolicy = WebCore::ShouldOpenExternalURLsPolicy::ShouldNotAllow);
- void loadRequestWithNavigationShared(Ref<WebProcessProxy>&&, WebCore::PageIdentifier, API::Navigation&, WebCore::ResourceRequest&&, WebCore::ShouldOpenExternalURLsPolicy, API::Object* userData, WebCore::ShouldTreatAsContinuingLoad, Optional<NavigatingToAppBoundDomain>, NavigatedAwayFromAppBoundDomain, Optional<WebsitePoliciesData>&& = WTF::nullopt);
+ void loadDataWithNavigationShared(Ref<WebProcessProxy>&&, WebCore::PageIdentifier, API::Navigation&, const IPC::DataReference&, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData, WebCore::ShouldTreatAsContinuingLoad, Optional<NavigatingToAppBoundDomain>, Optional<WebsitePoliciesData>&& = WTF::nullopt, WebCore::ShouldOpenExternalURLsPolicy = WebCore::ShouldOpenExternalURLsPolicy::ShouldNotAllow);
+ void loadRequestWithNavigationShared(Ref<WebProcessProxy>&&, WebCore::PageIdentifier, API::Navigation&, WebCore::ResourceRequest&&, WebCore::ShouldOpenExternalURLsPolicy, API::Object* userData, WebCore::ShouldTreatAsContinuingLoad, Optional<NavigatingToAppBoundDomain>, Optional<WebsitePoliciesData>&& = WTF::nullopt);
void backForwardGoToItemShared(Ref<WebProcessProxy>&&, const WebCore::BackForwardItemIdentifier&, CompletionHandler<void(const WebBackForwardListCounts&)>&&);
void decidePolicyForNavigationActionSyncShared(Ref<WebProcessProxy>&&, WebCore::FrameIdentifier, bool isMainFrame, FrameInfoData&&, WebCore::PolicyCheckIdentifier, uint64_t navigationID, NavigationActionData&&, FrameInfoData&& originatingFrameInfo, Optional<WebPageProxyIdentifier> originatingPageID, const WebCore::ResourceRequest& originalRequest, WebCore::ResourceRequest&&, IPC::FormDataReference&& requestBody, WebCore::ResourceResponse&& redirectResponse, const UserData&, Messages::WebPageProxy::DecidePolicyForNavigationActionSyncDelayedReply&&);
#if USE(QUICK_LOOK)
@@ -1763,6 +1763,8 @@
void removeMediaUsageManagerSession(WebCore::MediaSessionIdentifier);
#endif
+ void setHasExecutedAppBoundBehaviorBeforeNavigation() { m_hasExecutedAppBoundBehaviorBeforeNavigation = true; }
+
private:
WebPageProxy(PageClient&, WebProcessProxy&, Ref<API::PageConfiguration>&&);
void platformInitialize();
@@ -2317,7 +2319,6 @@
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 setIsNavigatingToAppBoundDomainAndCheckIfPermitted(bool isMainFrame, const URL&, Optional<NavigatingToAppBoundDomain>);
- NavigatedAwayFromAppBoundDomain hasNavigatedAwayFromAppBoundDomain() const { return m_hasNavigatedAwayFromAppBoundDomain; }
const Identifier m_identifier;
WebCore::PageIdentifier m_webPageID;
@@ -2811,11 +2812,11 @@
MonotonicTime m_didFinishDocumentLoadForMainFrameTimestamp;
#endif
- Optional<NavigatingToAppBoundDomain> m_isNavigatingToAppBoundDomain { NavigatingToAppBoundDomain::No };
- NavigatedAwayFromAppBoundDomain m_hasNavigatedAwayFromAppBoundDomain { NavigatedAwayFromAppBoundDomain::No };
+ Optional<NavigatingToAppBoundDomain> m_isNavigatingToAppBoundDomain;
bool m_ignoresAppBoundDomains { false };
bool m_userScriptsNotified { false };
bool m_limitsNavigationsToAppBoundDomains { false };
+ bool m_hasExecutedAppBoundBehaviorBeforeNavigation { false };
#if ENABLE(ROUTING_ARBITRATION)
std::unique_ptr<AudioSessionRoutingArbitratorProxy> m_routingArbitrator;
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in (261505 => 261506)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in 2020-05-11 23:46:47 UTC (rev 261505)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in 2020-05-11 23:59:40 UTC (rev 261506)
@@ -599,4 +599,5 @@
RemoveMediaUsageManagerSession(WebCore::MediaSessionIdentifier identifier);
#endif
+ SetHasExecutedAppBoundBehaviorBeforeNavigation()
}
Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp (261505 => 261506)
--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp 2020-05-11 23:46:47 UTC (rev 261505)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp 2020-05-11 23:59:40 UTC (rev 261506)
@@ -830,7 +830,7 @@
uint64_t listenerID = m_frame->setUpPolicyListener(identifier, WTFMove(function), WebFrame::ForNavigationAction::No);
if (!webPage->send(Messages::WebPageProxy::DecidePolicyForResponse(m_frame->frameID(), m_frame->info(), identifier, navigationID, response, request, canShowResponse, downloadAttribute, listenerID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())))) {
WEBFRAMELOADERCLIENT_RELEASE_LOG(Network, "dispatchDecidePolicyForResponse: ignoring because WebPageProxy::DecidePolicyForResponse failed");
- m_frame->didReceivePolicyDecision(listenerID, PolicyDecision { identifier, NavigatingToAppBoundDomain::No, NavigatedAwayFromAppBoundDomain::No, PolicyAction::Ignore, 0, { }, { } });
+ m_frame->didReceivePolicyDecision(listenerID, PolicyDecision { identifier, WTF::nullopt, PolicyAction::Ignore, 0, { }, { } });
}
}
@@ -992,17 +992,17 @@
PolicyDecision policyDecision;
if (!webPage->sendSync(Messages::WebPageProxy::DecidePolicyForNavigationActionSync(m_frame->frameID(), m_frame->isMainFrame(), m_frame->info(), requestIdentifier, documentLoader->navigationID(), navigationActionData, originatingFrameInfoData, originatingPageID, navigationAction.resourceRequest(), request, IPC::FormDataReference { request.httpBody() }, redirectResponse, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())), Messages::WebPageProxy::DecidePolicyForNavigationActionSync::Reply(policyDecision))) {
- m_frame->didReceivePolicyDecision(listenerID, PolicyDecision { requestIdentifier, NavigatingToAppBoundDomain::No, NavigatedAwayFromAppBoundDomain::No, PolicyAction::Ignore, 0, { }, { } });
+ m_frame->didReceivePolicyDecision(listenerID, PolicyDecision { requestIdentifier, WTF::nullopt, PolicyAction::Ignore, 0, { }, { } });
return;
}
- m_frame->didReceivePolicyDecision(listenerID, PolicyDecision { policyDecision.identifier, policyDecision.isNavigatingToAppBoundDomain, policyDecision.hasNavigatedAwayFromAppBoundDomain, policyDecision.policyAction, 0, policyDecision.downloadID, { }});
+ m_frame->didReceivePolicyDecision(listenerID, PolicyDecision { policyDecision.identifier, policyDecision.isNavigatingToAppBoundDomain, policyDecision.policyAction, 0, policyDecision.downloadID, { }});
return;
}
ASSERT(policyDecisionMode == PolicyDecisionMode::Asynchronous);
if (!webPage->send(Messages::WebPageProxy::DecidePolicyForNavigationActionAsync(m_frame->frameID(), m_frame->info(), requestIdentifier, documentLoader->navigationID(), navigationActionData, originatingFrameInfoData, originatingPageID, navigationAction.resourceRequest(), request, IPC::FormDataReference { request.httpBody() }, redirectResponse, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get()), listenerID)))
- m_frame->didReceivePolicyDecision(listenerID, PolicyDecision { requestIdentifier, NavigatingToAppBoundDomain::No, NavigatedAwayFromAppBoundDomain::No, PolicyAction::Ignore, 0, { }, { } });
+ m_frame->didReceivePolicyDecision(listenerID, PolicyDecision { requestIdentifier, WTF::nullopt, PolicyAction::Ignore, 0, { }, { } });
}
void WebFrameLoaderClient::cancelPolicyCheck()
@@ -1921,7 +1921,7 @@
}
#endif // ENABLE(APPLICATION_MANIFEST)
-bool WebFrameLoaderClient::hasNavigatedAwayFromAppBoundDomain()
+bool WebFrameLoaderClient::shouldEnableInAppBrowserPrivacyProtections() const
{
if (!m_frame->isMainFrame())
return false;
@@ -1929,20 +1929,22 @@
auto* webPage = m_frame->page();
if (!webPage)
return false;
-
- return webPage->hasNavigatedAwayFromAppBoundDomain() == NavigatedAwayFromAppBoundDomain::Yes;
+
+ return webPage->shouldEnableInAppBrowserPrivacyProtections();
}
-bool WebFrameLoaderClient::needsInAppBrowserPrivacyQuirks() const
+void WebFrameLoaderClient::notifyPageOfAppBoundBehavior()
{
+ if (!m_frame->isMainFrame())
+ return;
+
auto* webPage = m_frame->page();
if (!webPage)
- return false;
-
- return webPage->needsInAppBrowserPrivacyQuirks();
+ return;
+
+ webPage->notifyPageOfAppBoundBehavior();
}
-
} // namespace WebKit
#undef PREFIX_PARAMETERS
Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.h (261505 => 261506)
--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.h 2020-05-11 23:46:47 UTC (rev 261505)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.h 2020-05-11 23:59:40 UTC (rev 261506)
@@ -288,8 +288,8 @@
Optional<FrameSpecificStorageAccessIdentifier> m_frameSpecificStorageAccessIdentifier;
#endif
- bool hasNavigatedAwayFromAppBoundDomain() final;
- bool needsInAppBrowserPrivacyQuirks() const final;
+ bool shouldEnableInAppBrowserPrivacyProtections() const final;
+ void notifyPageOfAppBoundBehavior() final;
};
// As long as EmptyFrameLoaderClient exists in WebCore, this can return 0.
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (261505 => 261506)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2020-05-11 23:46:47 UTC (rev 261505)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2020-05-11 23:59:40 UTC (rev 261506)
@@ -475,7 +475,7 @@
#endif
, m_overriddenMediaType(parameters.overriddenMediaType)
, m_processDisplayName(parameters.processDisplayName)
- , m_isNavigatingToAppBoundDomain(parameters.limitsNavigationsToAppBoundDomains ? NavigatingToAppBoundDomain::Yes : NavigatingToAppBoundDomain::No)
+ , m_limitsNavigationsToAppBoundDomains(parameters.limitsNavigationsToAppBoundDomains)
{
ASSERT(m_identifier);
@@ -1527,7 +1527,6 @@
void WebPage::loadRequest(LoadParameters&& loadParameters)
{
setIsNavigatingToAppBoundDomain(loadParameters.isNavigatingToAppBoundDomain);
- setHasNavigatedAwayFromAppBoundDomain(loadParameters.hasNavigatedAwayFromAppBoundDomain);
SendStopResponsivenessTimer stopper;
@@ -1563,10 +1562,9 @@
RELEASE_ASSERT_NOT_REACHED();
}
-void WebPage::loadDataImpl(uint64_t navigationID, bool shouldTreatAsContinuingLoad, Optional<WebsitePoliciesData>&& websitePolicies, Ref<SharedBuffer>&& sharedBuffer, const String& MIMEType, const String& encodingName, const URL& baseURL, const URL& unreachableURL, const UserData& userData, Optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain, NavigatedAwayFromAppBoundDomain hasNavigatedAwayFromAppBoundDomain, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy)
+void WebPage::loadDataImpl(uint64_t navigationID, bool shouldTreatAsContinuingLoad, Optional<WebsitePoliciesData>&& websitePolicies, Ref<SharedBuffer>&& sharedBuffer, const String& MIMEType, const String& encodingName, const URL& baseURL, const URL& unreachableURL, const UserData& userData, Optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy)
{
setIsNavigatingToAppBoundDomain(isNavigatingToAppBoundDomain);
- setHasNavigatedAwayFromAppBoundDomain(hasNavigatedAwayFromAppBoundDomain);
SendStopResponsivenessTimer stopper;
@@ -1595,7 +1593,7 @@
auto sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(loadParameters.data.data()), loadParameters.data.size());
URL baseURL = loadParameters.baseURLString.isEmpty() ? aboutBlankURL() : URL(URL(), loadParameters.baseURLString);
- loadDataImpl(loadParameters.navigationID, loadParameters.shouldTreatAsContinuingLoad, WTFMove(loadParameters.websitePolicies), WTFMove(sharedBuffer), loadParameters.MIMEType, loadParameters.encodingName, baseURL, URL(), loadParameters.userData, loadParameters.isNavigatingToAppBoundDomain, loadParameters.hasNavigatedAwayFromAppBoundDomain, loadParameters.shouldOpenExternalURLsPolicy);
+ loadDataImpl(loadParameters.navigationID, loadParameters.shouldTreatAsContinuingLoad, WTFMove(loadParameters.websitePolicies), WTFMove(sharedBuffer), loadParameters.MIMEType, loadParameters.encodingName, baseURL, URL(), loadParameters.userData, loadParameters.isNavigatingToAppBoundDomain, loadParameters.shouldOpenExternalURLsPolicy);
}
void WebPage::loadAlternateHTML(LoadParameters&& loadParameters)
@@ -1607,7 +1605,7 @@
URL provisionalLoadErrorURL = loadParameters.provisionalLoadErrorURLString.isEmpty() ? URL() : URL(URL(), loadParameters.provisionalLoadErrorURLString);
auto sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(loadParameters.data.data()), loadParameters.data.size());
m_mainFrame->coreFrame()->loader().setProvisionalLoadErrorBeingHandledURL(provisionalLoadErrorURL);
- loadDataImpl(loadParameters.navigationID, loadParameters.shouldTreatAsContinuingLoad, WTFMove(loadParameters.websitePolicies), WTFMove(sharedBuffer), loadParameters.MIMEType, loadParameters.encodingName, baseURL, unreachableURL, loadParameters.userData, loadParameters.isNavigatingToAppBoundDomain, loadParameters.hasNavigatedAwayFromAppBoundDomain);
+ loadDataImpl(loadParameters.navigationID, loadParameters.shouldTreatAsContinuingLoad, WTFMove(loadParameters.websitePolicies), WTFMove(sharedBuffer), loadParameters.MIMEType, loadParameters.encodingName, baseURL, unreachableURL, loadParameters.userData, loadParameters.isNavigatingToAppBoundDomain);
m_mainFrame->coreFrame()->loader().setProvisionalLoadErrorBeingHandledURL({ });
}
@@ -3253,7 +3251,6 @@
void WebPage::didReceivePolicyDecision(FrameIdentifier frameID, uint64_t listenerID, PolicyDecision&& policyDecision)
{
setIsNavigatingToAppBoundDomain(policyDecision.isNavigatingToAppBoundDomain);
- setHasNavigatedAwayFromAppBoundDomain(policyDecision.hasNavigatedAwayFromAppBoundDomain);
WebFrame* frame = WebProcess::singleton().webFrame(frameID);
if (!frame)
@@ -3426,8 +3423,7 @@
send(Messages::WebPageProxy::ScriptValueCallback(dataReference, details, callbackID));
};
-
- if (hasNavigatedAwayFromAppBoundDomain() == NavigatedAwayFromAppBoundDomain::Yes && !m_needsInAppBrowserPrivacyQuirks) {
+ if (shouldEnableInAppBrowserPrivacyProtections()) {
send(Messages::WebPageProxy::ScriptValueCallback({ }, ExceptionDetails { "Unable to execute _javascript_"_s }, callbackID));
if (auto* document = m_page->mainFrame().document())
document->addConsoleMessage(MessageSource::Security, MessageLevel::Warning, "Ignoring user script injection for non-app bound domain.");
@@ -3683,8 +3679,8 @@
disableServiceWorkerEntitlement();
if (store.getBoolValueForKey(WebPreferencesKey::serviceWorkersEnabledKey())) {
- ASSERT(parentProcessHasServiceWorkerEntitlement() || m_isNavigatingToAppBoundDomain);
- if (!parentProcessHasServiceWorkerEntitlement() && !m_isNavigatingToAppBoundDomain)
+ ASSERT(parentProcessHasServiceWorkerEntitlement() || m_limitsNavigationsToAppBoundDomains);
+ if (!parentProcessHasServiceWorkerEntitlement() && !m_limitsNavigationsToAppBoundDomains)
RuntimeEnabledFeatures::sharedFeatures().setServiceWorkerEnabled(false);
}
#endif
@@ -7102,6 +7098,27 @@
#endif
+void WebPage::setIsNavigatingToAppBoundDomain(Optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain)
+{
+ m_isNavigatingToAppBoundDomain = isNavigatingToAppBoundDomain;
+
+ m_navigationHasOccured = true;
+}
+
+void WebPage::notifyPageOfAppBoundBehavior()
+{
+ if (!m_navigationHasOccured && !m_limitsNavigationsToAppBoundDomains)
+ send(Messages::WebPageProxy::SetHasExecutedAppBoundBehaviorBeforeNavigation());
+}
+
+bool WebPage::shouldEnableInAppBrowserPrivacyProtections()
+{
+ if (m_needsInAppBrowserPrivacyQuirks)
+ return false;
+
+ return isNavigatingToAppBoundDomain() && isNavigatingToAppBoundDomain() == NavigatingToAppBoundDomain::No;
+}
+
} // namespace WebKit
#undef RELEASE_LOG_IF_ALLOWED
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.h (261505 => 261506)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2020-05-11 23:46:47 UTC (rev 261505)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2020-05-11 23:59:40 UTC (rev 261506)
@@ -1315,11 +1315,10 @@
void getAllFrames(CompletionHandler<void(FrameTreeNodeData&&)>&&);
- void setIsNavigatingToAppBoundDomain(Optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain) { m_isNavigatingToAppBoundDomain = isNavigatingToAppBoundDomain; }
+ void notifyPageOfAppBoundBehavior();
+ bool shouldEnableInAppBrowserPrivacyProtections();
+ void setIsNavigatingToAppBoundDomain(Optional<NavigatingToAppBoundDomain>);
Optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain() const { return m_isNavigatingToAppBoundDomain; }
- NavigatedAwayFromAppBoundDomain hasNavigatedAwayFromAppBoundDomain() const { return m_hasNavigatedAwayFromAppBoundDomain; }
- void setHasNavigatedAwayFromAppBoundDomain(NavigatedAwayFromAppBoundDomain navigatedAwayFromAppBoundDomain) { m_hasNavigatedAwayFromAppBoundDomain = navigatedAwayFromAppBoundDomain; }
- bool needsInAppBrowserPrivacyQuirks() const { return m_needsInAppBrowserPrivacyQuirks; }
bool shouldUseRemoteRenderingFor(WebCore::RenderingPurpose);
@@ -1419,7 +1418,7 @@
String sourceForFrame(WebFrame*);
- void loadDataImpl(uint64_t navigationID, bool shouldTreatAsContinuingLoad, Optional<WebsitePoliciesData>&&, Ref<WebCore::SharedBuffer>&&, const String& MIMEType, const String& encodingName, const URL& baseURL, const URL& failingURL, const UserData&, Optional<NavigatingToAppBoundDomain>, NavigatedAwayFromAppBoundDomain, WebCore::ShouldOpenExternalURLsPolicy = WebCore::ShouldOpenExternalURLsPolicy::ShouldNotAllow);
+ void loadDataImpl(uint64_t navigationID, bool shouldTreatAsContinuingLoad, Optional<WebsitePoliciesData>&&, Ref<WebCore::SharedBuffer>&&, const String& MIMEType, const String& encodingName, const URL& baseURL, const URL& failingURL, const UserData&, Optional<NavigatingToAppBoundDomain>, WebCore::ShouldOpenExternalURLsPolicy = WebCore::ShouldOpenExternalURLsPolicy::ShouldNotAllow);
// Actions
void tryClose(CompletionHandler<void(bool)>&&);
@@ -2104,8 +2103,9 @@
String m_themeName;
#endif
- Optional<NavigatingToAppBoundDomain> m_isNavigatingToAppBoundDomain { NavigatingToAppBoundDomain::No };
- NavigatedAwayFromAppBoundDomain m_hasNavigatedAwayFromAppBoundDomain { NavigatedAwayFromAppBoundDomain::No };
+ Optional<NavigatingToAppBoundDomain> m_isNavigatingToAppBoundDomain;
+ bool m_limitsNavigationsToAppBoundDomains { false };
+ bool m_navigationHasOccured { false };
};
#if !PLATFORM(IOS_FAMILY)
Modified: trunk/Tools/ChangeLog (261505 => 261506)
--- trunk/Tools/ChangeLog 2020-05-11 23:46:47 UTC (rev 261505)
+++ trunk/Tools/ChangeLog 2020-05-11 23:59:40 UTC (rev 261506)
@@ -1,3 +1,29 @@
+2020-05-11 Kate Cheney <[email protected]>
+
+ Fail navigations to non app-bound domains after use of app-bound APIs
+ https://bugs.webkit.org/show_bug.cgi?id=211647
+ <rdar://problem/62978159>
+
+ Reviewed by Brent Fulgham.
+
+ Added a new test to confirm a non-app bound navigation fails after
+ using script injection.
+
+ This fix also required changing any test which uses a restricted API
+ to confirm behavior of another restricted API. Tests can set
+ _setNeedsInAppBrowserPrivacyQuirks in the configuration to indicate
+ APIs should not be blocked, then toggle it to test actual behavior.
+
+ Also, we can remove any calls to _setInAppBrowserPrivacyEnabled
+ now that this is just an internal test flag.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm:
+ (-[AppBoundDomainDelegate webView:didFinishNavigation:]):
+ (-[AppBoundDomainDelegate webView:didFailProvisionalNavigation:withError:]):
+ (-[AppBoundDomainDelegate waitForDidFinishNavigation]):
+ (-[AppBoundDomainDelegate waitForDidFailProvisionalNavigationError]):
+ (TEST):
+
2020-05-11 Alex Christensen <[email protected]>
Add some logs to diagnose why WebKitLegacy.CrossPartitionFileSchemeAccess API test times out in EWS
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm (261505 => 261506)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm 2020-05-11 23:46:47 UTC (rev 261505)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm 2020-05-11 23:59:40 UTC (rev 261506)
@@ -48,6 +48,40 @@
static bool isDone;
+@interface AppBoundDomainDelegate : NSObject <WKNavigationDelegate>
+- (void)waitForDidFinishNavigation;
+- (NSError *)waitForDidFailProvisionalNavigationError;
+@end
+
+@implementation AppBoundDomainDelegate {
+ bool _navigationFinished;
+ RetainPtr<NSError> _provisionalNavigationFailedError;
+}
+
+- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
+{
+ _navigationFinished = true;
+}
+
+- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error
+{
+ _provisionalNavigationFailedError = error;
+}
+
+- (void)waitForDidFinishNavigation
+{
+ TestWebKitAPI::Util::run(&_navigationFinished);
+}
+
+- (NSError *)waitForDidFailProvisionalNavigationError
+{
+ while (!_provisionalNavigationFailedError)
+ TestWebKitAPI::Util::spinRunLoop();
+ return _provisionalNavigationFailedError.autorelease();
+}
+
+@end
+
static NSString * const userScriptSource = @"window.wkUserScriptInjected = true";
@interface InAppBrowserSchemeHandler : NSObject <WKURLSchemeHandler>
@@ -103,8 +137,6 @@
auto schemeHandler = adoptNS([[InAppBrowserSchemeHandler alloc] init]);
[configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"in-app-browser"];
[configuration.userContentController addUserScript:userScript.get()];
- [[configuration preferences] _setNeedsInAppBrowserPrivacyQuirks:NO];
- [[configuration preferences] _setInAppBrowserPrivacyEnabled:YES];
auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration]);
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"in-app-browser:///in-app-browser-privacy-test-user-script"]];
@@ -121,8 +153,7 @@
isDone = false;
TestWebKitAPI::Util::run(&isDone);
- // Turn back on In-App Browser Privacy quirks to check that original attempt to set this variable was rejected.
- isDone = false;
+ // Disable script injection blocking to check that original attempt to set this variable was rejected.
[[[webView configuration] preferences] _setNeedsInAppBrowserPrivacyQuirks:YES];
[webView evaluateJavaScript:@"window.wkUserScriptInjected" completionHandler:^(id _Nullable result, NSError * _Nullable error) {
EXPECT_EQ(NO, [result boolValue]);
@@ -145,8 +176,6 @@
auto schemeHandler = adoptNS([[InAppBrowserSchemeHandler alloc] init]);
[configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"in-app-browser"];
[configuration.userContentController addUserScript:userScript.get()];
- [[configuration preferences] _setNeedsInAppBrowserPrivacyQuirks:NO];
- [[configuration preferences] _setInAppBrowserPrivacyEnabled:YES];
auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration]);
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"in-app-browser:///in-app-browser-privacy-test-user-script"]];
@@ -163,8 +192,7 @@
isDone = false;
TestWebKitAPI::Util::run(&isDone);
- // Turn back on In-App Browser Privacy quirks to check that original attempt to set this variable was rejected.
- isDone = false;
+ // Disable script injection blocking to check that original attempt to set this variable was rejected.
[[[webView configuration] preferences] _setNeedsInAppBrowserPrivacyQuirks:YES];
[webView evaluateJavaScript:@"window.wkUserScriptInjected" completionHandler:^(id _Nullable result, NSError * _Nullable error) {
EXPECT_EQ(NO, [result boolValue]);
@@ -179,9 +207,11 @@
TEST(InAppBrowserPrivacy, NonAppBoundDomainFailedUserAgentScripts)
{
+ initializeInAppBrowserPrivacyTestSettings();
+
WKWebViewConfiguration *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals" configureJSCForTesting:YES];
+ // Disable blocking of restricted APIs for test setup.
[[configuration preferences] _setNeedsInAppBrowserPrivacyQuirks:YES];
- [[configuration preferences] _setInAppBrowserPrivacyEnabled:NO];
auto schemeHandler = adoptNS([[InAppBrowserSchemeHandler alloc] init]);
[configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"in-app-browser"];
@@ -198,13 +228,11 @@
isDone = false;
TestWebKitAPI::Util::run(&isDone);
-
- initializeInAppBrowserPrivacyTestSettings();
+
+ // Enable blocking of restricted APIs.
[[configuration preferences] _setNeedsInAppBrowserPrivacyQuirks:NO];
- [[configuration preferences] _setInAppBrowserPrivacyEnabled:YES];
auto webView2 = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration]);
-
isDone = false;
[webView2 loadRequest:request];
[webView2 _test_waitForDidFinishNavigation];
@@ -244,7 +272,6 @@
{
initializeInAppBrowserPrivacyTestSettings();
auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
- [[configuration preferences] _setInAppBrowserPrivacyEnabled:YES];
[configuration setLimitsNavigationsToAppBoundDomains:YES];
auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration.get()]);
@@ -265,7 +292,6 @@
{
initializeInAppBrowserPrivacyTestSettings();
auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
- [[configuration preferences] _setInAppBrowserPrivacyEnabled:YES];
[configuration setLimitsNavigationsToAppBoundDomains:YES];
auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration.get()]);
@@ -285,7 +311,6 @@
{
initializeInAppBrowserPrivacyTestSettings();
auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
- [[configuration preferences] _setInAppBrowserPrivacyEnabled:YES];
[configuration setLimitsNavigationsToAppBoundDomains:YES];
auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration.get()]);
@@ -303,7 +328,6 @@
static NSString *styleSheetSource = @"body { background-color: green !important; }";
static NSString *backgroundColorScript = @"window.getComputedStyle(document.body, null).getPropertyValue('background-color')";
-static NSString *frameBackgroundColorScript = @"window.getComputedStyle(document.getElementsByTagName('iframe')[0].contentDocument.body, null).getPropertyValue('background-color')";
static const char* redInRGB = "rgb(255, 0, 0)";
static const char* blackInRGB = "rgba(0, 0, 0, 0)";
@@ -329,19 +353,19 @@
auto schemeHandler = adoptNS([[InAppBrowserSchemeHandler alloc] init]);
[configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"in-app-browser"];
- [[configuration preferences] _setInAppBrowserPrivacyEnabled:YES];
- [[configuration preferences] _setNeedsInAppBrowserPrivacyQuirks:YES];
+ RetainPtr<_WKUserContentWorld> world = [_WKUserContentWorld worldWithName:@"TestWorld"];
auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration.get()]);
- NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"in-app-browser:///in-app-browser-privacy-test-user-style-sheets"]];
- [webView loadRequest:request];
- [webView _test_waitForDidFinishNavigation];
-
- RetainPtr<_WKUserContentWorld> world = [_WKUserContentWorld worldWithName:@"TestWorld"];
RetainPtr<_WKUserStyleSheet> styleSheet = adoptNS([[_WKUserStyleSheet alloc] initWithSource:styleSheetSource forWKWebView:webView.get() forMainFrameOnly:YES level:_WKUserStyleUserLevel userContentWorld:world.get()]);
[[configuration userContentController] _addUserStyleSheet:styleSheet.get()];
- expectScriptEvaluatesToColor(webView.get(), backgroundColorScript, redInRGB);
+ auto delegate = adoptNS([AppBoundDomainDelegate new]);
+ [webView setNavigationDelegate:delegate.get()];
+
+ NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"in-app-browser:///in-app-browser-privacy-test-user-style-sheets"]];
+ [webView loadRequest:request];
+ NSError *error = [delegate waitForDidFailProvisionalNavigationError];
+ EXPECT_WK_STREQ(error.localizedDescription, @"App-bound domain failure");
cleanUpInAppBrowserPrivacyTestSettings();
}
@@ -353,18 +377,18 @@
auto schemeHandler = adoptNS([[InAppBrowserSchemeHandler alloc] init]);
[configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"in-app-browser"];
- [[configuration preferences] _setInAppBrowserPrivacyEnabled:YES];
- [[configuration preferences] _setNeedsInAppBrowserPrivacyQuirks:YES];
+
+ RetainPtr<_WKUserStyleSheet> styleSheet = adoptNS([[_WKUserStyleSheet alloc] initWithSource:styleSheetSource forMainFrameOnly:YES]);
+ [[configuration userContentController] _addUserStyleSheet:styleSheet.get()];
+
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration.get()]);
+ auto delegate = adoptNS([AppBoundDomainDelegate new]);
+ [webView setNavigationDelegate:delegate.get()];
- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration.get()]);
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"in-app-browser:///in-app-browser-privacy-test-user-style-sheets"]];
[webView loadRequest:request];
- [webView _test_waitForDidFinishNavigation];
-
- RetainPtr<_WKUserStyleSheet> styleSheet = adoptNS([[_WKUserStyleSheet alloc] initWithSource:styleSheetSource forMainFrameOnly:YES]);
- [[configuration userContentController] _addUserStyleSheet:styleSheet.get()];
-
- expectScriptEvaluatesToColor(webView.get(), backgroundColorScript, redInRGB);
+ NSError *error = [delegate waitForDidFailProvisionalNavigationError];
+ EXPECT_WK_STREQ(error.localizedDescription, @"App-bound domain failure");
cleanUpInAppBrowserPrivacyTestSettings();
}
@@ -376,22 +400,17 @@
auto schemeHandler = adoptNS([[InAppBrowserSchemeHandler alloc] init]);
[configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"in-app-browser"];
- [[configuration preferences] _setInAppBrowserPrivacyEnabled:YES];
- [[configuration preferences] _setNeedsInAppBrowserPrivacyQuirks:YES];
+ RetainPtr<_WKUserStyleSheet> styleSheet = adoptNS([[_WKUserStyleSheet alloc] initWithSource:styleSheetSource forMainFrameOnly:NO]);
+ [[configuration userContentController] _addUserStyleSheet:styleSheet.get()];
auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration.get()]);
+ auto delegate = adoptNS([AppBoundDomainDelegate new]);
+ [webView setNavigationDelegate:delegate.get()];
+
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"in-app-browser:///in-app-browser-privacy-test-user-style-sheets-iframe"]];
[webView loadRequest:request];
- [webView _test_waitForDidFinishNavigation];
-
- RetainPtr<_WKUserStyleSheet> styleSheet = adoptNS([[_WKUserStyleSheet alloc] initWithSource:styleSheetSource forMainFrameOnly:NO]);
- [[configuration userContentController] _addUserStyleSheet:styleSheet.get()];
-
- // The main frame should be affected.
- expectScriptEvaluatesToColor(webView.get(), backgroundColorScript, redInRGB);
-
- // The subframe should also be affected.
- expectScriptEvaluatesToColor(webView.get(), frameBackgroundColorScript, redInRGB);
+ NSError *error = [delegate waitForDidFailProvisionalNavigationError];
+ EXPECT_WK_STREQ(error.localizedDescription, @"App-bound domain failure");
cleanUpInAppBrowserPrivacyTestSettings();
}
@@ -404,8 +423,6 @@
auto schemeHandler = adoptNS([[InAppBrowserSchemeHandler alloc] init]);
[configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"in-app-browser"];
- [[configuration preferences] _setInAppBrowserPrivacyEnabled:YES];
- [[configuration preferences] _setNeedsInAppBrowserPrivacyQuirks:YES];
auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration.get()]);
@@ -416,6 +433,10 @@
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"in-app-browser:///in-app-browser-privacy-test-message-handler"]];
[webView loadRequest:request];
[webView _test_waitForDidFinishNavigation];
+
+ // Disable script injection blocking to check that the request for message
+ // handlers returned null.
+ [[configuration preferences] _setNeedsInAppBrowserPrivacyQuirks:YES];
// Set the background color to red if message handlers returned null so we can
// check without needing a message handler.
@@ -432,7 +453,6 @@
auto schemeHandler = adoptNS([[InAppBrowserSchemeHandler alloc] init]);
[configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"in-app-browser"];
- [[configuration preferences] _setInAppBrowserPrivacyEnabled:YES];
[configuration setLimitsNavigationsToAppBoundDomains:YES];
auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration.get()]);
@@ -833,40 +853,6 @@
isDone = false;
}
-@interface AppBoundDomainDelegate : NSObject <WKNavigationDelegate>
-- (void)waitForDidFinishNavigation;
-- (NSError *)waitForDidFailProvisionalNavigationError;
-@end
-
-@implementation AppBoundDomainDelegate {
- bool _navigationFinished;
- RetainPtr<NSError> _provisionalNavigationFailedError;
-}
-
-- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
-{
- _navigationFinished = true;
-}
-
-- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error
-{
- _provisionalNavigationFailedError = error;
-}
-
-- (void)waitForDidFinishNavigation
-{
- TestWebKitAPI::Util::run(&_navigationFinished);
-}
-
-- (NSError *)waitForDidFailProvisionalNavigationError
-{
- while (!_provisionalNavigationFailedError)
- TestWebKitAPI::Util::spinRunLoop();
- return _provisionalNavigationFailedError.autorelease();
-}
-
-@end
-
TEST(InAppBrowserPrivacy, AppBoundFlagForNonAppBoundDomainFails)
{
initializeInAppBrowserPrivacyTestSettings();
@@ -885,7 +871,7 @@
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"in-app-browser:///in-app-browser-privacy-test-user-style-sheets"]];
[webView loadRequest:request];
NSError *error = [delegate waitForDidFailProvisionalNavigationError];
- EXPECT_WK_STREQ(error.localizedDescription, @"Attempted navigation away from app-bound domain");
+ EXPECT_WK_STREQ(error.localizedDescription, @"App-bound domain failure");
// Make sure the load didn't complete by checking the background color.
// Red would indicate it finished loading.
@@ -916,7 +902,7 @@
request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"in-app-browser:///in-app-browser-privacy-test-user-style-sheets"]];
[webView loadRequest:request];
NSError *error = [delegate waitForDidFailProvisionalNavigationError];
- EXPECT_WK_STREQ(error.localizedDescription, @"Attempted navigation away from app-bound domain");
+ EXPECT_WK_STREQ(error.localizedDescription, @"App-bound domain failure");
// Make sure the load didn't complete by checking the background color.
// Red would indicate it finished loading.
@@ -991,11 +977,14 @@
TestWebKitAPI::Util::run(&isDone);
// Navigation should be successful, but this WebView should not get app-bound domain
- // privileges like user style sheets. Set quirks to true so we can evaluate script
- // to check.
- [[[webView configuration] preferences] _setNeedsInAppBrowserPrivacyQuirks:YES];
- expectScriptEvaluatesToColor(webView.get(), backgroundColorScript, blackInRGB);
- cleanUpInAppBrowserPrivacyTestSettings();
+ // privileges like script injection.
+ isDone = false;
+ [webView evaluateJavaScript:@"window.wkUserScriptInjected" completionHandler:^(id _Nullable result, NSError * _Nullable error) {
+ EXPECT_TRUE(!!error);
+ isDone = true;
+ }];
+
+ TestWebKitAPI::Util::run(&isDone);
}
TEST(InAppBrowserPrivacy, WebViewCannotUpdateAppBoundFlagOnceSet)
@@ -1029,11 +1018,42 @@
request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"in-app-browser:///in-app-browser-privacy-test-user-style-sheets"]];
[webView loadRequest:request];
NSError *error = [delegate waitForDidFailProvisionalNavigationError];
- EXPECT_WK_STREQ(error.localizedDescription, @"Attempted navigation away from app-bound domain");
+ EXPECT_WK_STREQ(error.localizedDescription, @"App-bound domain failure");
cleanUpInAppBrowserPrivacyTestSettings();
}
+TEST(InAppBrowserPrivacy, InjectScriptThenNavigateToNonAppBoundDomainFails)
+{
+ isDone = false;
+ initializeInAppBrowserPrivacyTestSettings();
+ auto userScript = adoptNS([[WKUserScript alloc] initWithSource:userScriptSource injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:YES]);
+
+ WKWebViewConfiguration *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals" configureJSCForTesting:YES];
+ auto schemeHandler = adoptNS([[InAppBrowserSchemeHandler alloc] init]);
+ [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"in-app-browser"];
+ [configuration.userContentController addUserScript:userScript.get()];
+ [[configuration preferences] _setNeedsInAppBrowserPrivacyQuirks:NO];
+
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration]);
+ auto delegate = adoptNS([AppBoundDomainDelegate new]);
+ [webView setNavigationDelegate:delegate.get()];
+
+ isDone = false;
+ [webView evaluateJavaScript:@"window.wkUserScriptInjected" completionHandler:^(id _Nullable result, NSError * _Nullable error) {
+ EXPECT_FALSE(!!error);
+ isDone = true;
+ }];
+
+ TestWebKitAPI::Util::run(&isDone);
+
+ // Load a non-app bound domain.
+ NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"in-app-browser:///in-app-browser-privacy-test-user-agent-script"]];
+ [webView loadRequest:request];
+ NSError *error = [delegate waitForDidFailProvisionalNavigationError];
+ EXPECT_WK_STREQ(error.localizedDescription, @"App-bound domain failure");
+}
+
TEST(InAppBrowserPrivacy, WebViewCategory)
{
initializeInAppBrowserPrivacyTestSettings();