Changeset 261506 in webkit


Ignore:
Timestamp:
May 11, 2020 4:59:40 PM (4 years ago)
Author:
Kate Cheney
Message:

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.

Source/WebCore:

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.

Source/WebKit:

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.

Tools:

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):

Location:
trunk
Files:
23 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r261501 r261506  
     12020-05-11  Kate Cheney  <katherine_cheney@apple.com>
     2
     3        Fail navigations to non app-bound domains after use of app-bound APIs
     4        https://bugs.webkit.org/show_bug.cgi?id=211647
     5        <rdar://problem/62978159>
     6
     7        Reviewed by Brent Fulgham.
     8
     9        Simplified in-app browser privacy protections check into one, better
     10        named function.
     11
     12        * bindings/js/ScriptController.cpp:
     13        (WebCore::ScriptController::executeScriptInWorld):
     14        * loader/FrameLoaderClient.h:
     15        * page/Frame.cpp:
     16        (WebCore::Frame::injectUserScriptImmediately):
     17        * page/Page.cpp:
     18        (WebCore::Page::injectUserStyleSheet):
     19        * page/WebKitNamespace.cpp:
     20        (WebCore::WebKitNamespace::messageHandlers):
     21        * style/StyleScopeRuleSets.cpp:
     22        (WebCore::Style::ScopeRuleSets::initializeUserStyle):
     23        Rearranged ordering so the message to WebPageProxy only gets sent to
     24        indicate app-bound behavior if user style sheets actually exist.
     25
    1262020-05-11  Peng Liu  <peng.liu6@apple.com>
    227
  • trunk/Source/WebCore/bindings/js/ScriptController.cpp

    r260848 r261506  
    580580ValueOrException ScriptController::executeScriptInWorld(DOMWrapperWorld& world, RunJavaScriptParameters&& parameters)
    581581{
    582     if (m_frame.loader().client().hasNavigatedAwayFromAppBoundDomain() && !m_frame.loader().client().needsInAppBrowserPrivacyQuirks()) {
     582    if (m_frame.loader().client().shouldEnableInAppBrowserPrivacyProtections()) {
    583583        if (auto* document = m_frame.document())
    584584            document->addConsoleMessage(MessageSource::Security, MessageLevel::Warning, "Ignoring user script injection for non-app bound domain.");
     
    586586        return makeUnexpected(ExceptionDetails { "Ignoring user script injection for non-app bound domain"_s });
    587587    }
     588    m_frame.loader().client().notifyPageOfAppBoundBehavior();
    588589
    589590    UserGestureIndicator gestureIndicator(parameters.forceUserGesture == ForceUserGesture::Yes ? Optional<ProcessingUserGestureState>(ProcessingUserGesture) : WTF::nullopt);
  • trunk/Source/WebCore/loader/FrameLoaderClient.h

    r260751 r261506  
    380380    virtual AllowsContentJavaScript allowsContentJavaScriptFromMostRecentNavigation() const { return AllowsContentJavaScript::Yes; }
    381381
    382     virtual bool hasNavigatedAwayFromAppBoundDomain() { return false; }
    383     virtual bool needsInAppBrowserPrivacyQuirks() const { return false; }
     382    virtual bool shouldEnableInAppBrowserPrivacyProtections() const { return false; }
     383    virtual void notifyPageOfAppBoundBehavior() { }
    384384};
    385385
  • trunk/Source/WebCore/page/Frame.cpp

    r261336 r261506  
    652652void Frame::injectUserScriptImmediately(DOMWrapperWorld& world, const UserScript& script)
    653653{
    654     if (loader().client().hasNavigatedAwayFromAppBoundDomain() && !loader().client().needsInAppBrowserPrivacyQuirks()) {
     654    if (loader().client().shouldEnableInAppBrowserPrivacyProtections()) {
    655655        if (auto* document = this->document())
    656656            document->addConsoleMessage(MessageSource::Security, MessageLevel::Warning, "Ignoring user script injection for non-app bound domain."_s);
     
    658658        return;
    659659    }
     660    loader().client().notifyPageOfAppBoundBehavior();
    660661
    661662    auto* document = this->document();
  • trunk/Source/WebCore/page/Page.cpp

    r261336 r261506  
    31633163void Page::injectUserStyleSheet(UserStyleSheet& userStyleSheet)
    31643164{
    3165     if (m_mainFrame->loader().client().hasNavigatedAwayFromAppBoundDomain()) {
     3165    if (m_mainFrame->loader().client().shouldEnableInAppBrowserPrivacyProtections()) {
    31663166        if (auto* document = m_mainFrame->document())
    31673167            document->addConsoleMessage(MessageSource::Security, MessageLevel::Warning, "Ignoring user style sheet for non-app bound domain."_s);
    31683168        return;
    31693169    }
     3170    m_mainFrame->loader().client().notifyPageOfAppBoundBehavior();
    31703171
    31713172    // We need to wait until we're no longer displaying the initial empty document before we can inject the stylesheets.
  • trunk/Source/WebCore/page/WebKitNamespace.cpp

    r259331 r261506  
    5151UserMessageHandlersNamespace* WebKitNamespace::messageHandlers()
    5252{
    53     if (frame() && frame()->loader().client().hasNavigatedAwayFromAppBoundDomain()) {
    54         RELEASE_LOG_ERROR_IF_ALLOWED(Loading, "Ignoring messageHandlers() request for non app-bound domain");
    55         return nullptr;
     53    if (frame()) {
     54        if (frame()->loader().client().shouldEnableInAppBrowserPrivacyProtections()) {
     55            RELEASE_LOG_ERROR_IF_ALLOWED(Loading, "Ignoring messageHandlers() request for non app-bound domain");
     56            return nullptr;
     57        }
     58        frame()->loader().client().notifyPageOfAppBoundBehavior();
    5659    }
    5760
  • trunk/Source/WebCore/style/StyleScopeRuleSets.cpp

    r259062 r261506  
    9393        tempUserStyle->addRulesFromSheet(pageUserSheet->contents(), nullptr, mediaQueryEvaluator, m_styleResolver);
    9494    auto* page = m_styleResolver.document().page();
    95     if (page && page->mainFrame().loader().client().hasNavigatedAwayFromAppBoundDomain() && !extensionStyleSheets.injectedUserStyleSheets().isEmpty())
     95    if (!extensionStyleSheets.injectedUserStyleSheets().isEmpty() && page && page->mainFrame().loader().client().shouldEnableInAppBrowserPrivacyProtections())
    9696        m_styleResolver.document().addConsoleMessage(MessageSource::Security, MessageLevel::Warning, "Ignoring user style sheet for non-app bound domain."_s);
    97     else
     97    else {
    9898        collectRulesFromUserStyleSheets(extensionStyleSheets.injectedUserStyleSheets(), tempUserStyle.get(), mediaQueryEvaluator);
     99        if (page && !extensionStyleSheets.injectedUserStyleSheets().isEmpty())
     100            page->mainFrame().loader().client().notifyPageOfAppBoundBehavior();
     101    }
    99102    collectRulesFromUserStyleSheets(extensionStyleSheets.documentUserStyleSheets(), tempUserStyle.get(), mediaQueryEvaluator);
    100103    if (tempUserStyle->ruleCount() > 0 || tempUserStyle->pageRules().size() > 0)
  • trunk/Source/WebKit/ChangeLog

    r261500 r261506  
     12020-05-11  Kate Cheney  <katherine_cheney@apple.com>
     2
     3        Fail navigations to non app-bound domains after use of app-bound APIs
     4        https://bugs.webkit.org/show_bug.cgi?id=211647
     5        <rdar://problem/62978159>
     6
     7        Reviewed by Brent Fulgham.
     8
     9        A lot of this patch is deleting the unnecessary variable/function
     10        hasNavigatedAwayFromAppBoundDomain now that navigating away from an
     11        app-bound domain is not possible.
     12       
     13        To address the bug, this sets the default isNavigatingToAppBoundDomain
     14        value to be WTF::nullopt. This will allow app-bound behaviors until
     15        a navigation has been attempted, in which case it will fail or will
     16        update isNavigatingToAppBoundDomain to the correct value.
     17
     18
     19        * Shared/LoadParameters.cpp:
     20        (WebKit::LoadParameters::encode const):
     21        (WebKit::LoadParameters::decode):
     22        * Shared/LoadParameters.h:
     23        * Shared/PolicyDecision.h:
     24        (WebKit::PolicyDecision::encode const):
     25        (WebKit::PolicyDecision::decode):
     26        * UIProcess/ProvisionalPageProxy.cpp:
     27        (WebKit::ProvisionalPageProxy::loadData):
     28        (WebKit::ProvisionalPageProxy::loadRequest):
     29        (WebKit::ProvisionalPageProxy::decidePolicyForNavigationActionSync):
     30        * UIProcess/ProvisionalPageProxy.h:
     31        * UIProcess/WebPageProxy.cpp:
     32        (WebKit::WebPageProxy::loadRequest):
     33        (WebKit::WebPageProxy::loadRequestWithNavigationShared):
     34        (WebKit::WebPageProxy::loadData):
     35        (WebKit::WebPageProxy::loadDataWithNavigationShared):
     36        (WebKit::WebPageProxy::receivedPolicyDecision):
     37        (WebKit::WebPageProxy::continueNavigationInNewProcess):
     38        (WebKit::WebPageProxy::decidePolicyForNavigationActionSyncShared):
     39        (WebKit::WebPageProxy::hasNavigatedAwayFromAppBoundDomain const): Deleted.
     40        Remove hasNavigatedAwayFromAppBoundDomain.
     41
     42        (WebKit::WebPageProxy::setIsNavigatingToAppBoundDomainAndCheckIfPermitted):
     43        Check for new m_hasExecutedAppBoundBehaviorBeforeNavigation parameter
     44        and fail the navigation if a WebView has used app-bound behavior then
     45        tries to navigate to a non app-bound domain.
     46
     47        (WebKit::WebPageProxy::decidePolicyForNavigationAction):
     48        Update error message to be more general now that more than one error
     49        can occur.
     50
     51        * UIProcess/WebPageProxy.h:
     52        (WebKit::WebPageProxy::setHasExecutedAppBoundBehaviorBeforeNavigation):
     53        * UIProcess/WebPageProxy.messages.in:
     54        New parameter to indicate a WebView has used app-bound APIs before
     55        navigating.
     56
     57        * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
     58        (WebKit::WebFrameLoaderClient::dispatchDecidePolicyForResponse):
     59        (WebKit::WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction):
     60        (WebKit::WebFrameLoaderClient::shouldEnableInAppBrowserPrivacyProtections):
     61        (WebKit::WebFrameLoaderClient::hasNavigatedAwayFromAppBoundDomain): Deleted.
     62        (WebKit::WebFrameLoaderClient::needsInAppBrowserPrivacyQuirks const): Deleted.
     63        * WebProcess/WebCoreSupport/WebFrameLoaderClient.h:
     64        Combined two functions into a simpler function:
     65        shouldEnableInAppBrowserPrivacyProtections().
     66
     67        * WebProcess/WebPage/WebPage.cpp:
     68        (WebKit::m_limitsNavigationsToAppBoundDomains):
     69        (WebKit::WebPage::updatePreferences):
     70        Store the special app-bound domain flag to gate the service worker
     71        API. This should be stored separately from
     72        m_isNavigatingToAppBoundDomain, because in the WebPage constructor we
     73        don't yet know whether the WKAppBoundDomains key exists.
     74
     75        (WebKit::WebPage::loadRequest):
     76        (WebKit::WebPage::loadDataImpl):
     77        (WebKit::WebPage::loadData):
     78        (WebKit::WebPage::loadAlternateHTML):
     79        (WebKit::WebPage::didReceivePolicyDecision):
     80        Remove hasNavigatedAwayFromAppBoundDomain.
     81
     82        (WebKit::WebPage::runJavaScript):
     83        (WebKit::WebPage::setIsNavigatingToAppBoundDomain):
     84        (WebKit::WebPage::shouldEnableInAppBrowserPrivacyProtections):
     85        If m_needsInAppBrowserPrivacyQuirks are on for testing, don't enable
     86        protections. Only notify the WebPageProxy of app-bound behavior if
     87        a navigation has not occured and we know the webView is not app-bound
     88        (in order to limit IPC).
     89
     90        (WebKit::m_isNavigatingToAppBoundDomain): Deleted.
     91        * WebProcess/WebPage/WebPage.h:
     92        (WebKit::WebPage::isNavigatingToAppBoundDomain const):
     93        (WebKit::WebPage::setIsNavigatingToAppBoundDomain): Deleted.
     94        (WebKit::WebPage::hasNavigatedAwayFromAppBoundDomain const): Deleted.
     95        (WebKit::WebPage::setHasNavigatedAwayFromAppBoundDomain): Deleted.
     96        (WebKit::WebPage::needsInAppBrowserPrivacyQuirks const): Deleted.
     97
    1982020-05-11  Wenson Hsieh  <wenson_hsieh@apple.com>
    299
  • trunk/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm

    r261242 r261506  
    6363#else
    6464#define NETWORK_SESSION_COCOA_ADDITIONS_1
     65#define NETWORK_SESSION_COCOA_ADDITIONS_2 true
    6566#endif
    6667
     
    12611262{
    12621263    auto shouldBeConsideredAppBound = isNavigatingToAppBoundDomain ? *isNavigatingToAppBoundDomain : NavigatingToAppBoundDomain::Yes;
     1264    if (NETWORK_SESSION_COCOA_ADDITIONS_2)
     1265        shouldBeConsideredAppBound = NavigatingToAppBoundDomain::No;
    12631266#if ENABLE(RESOURCE_LOAD_STATISTICS)
    12641267    if (auto* storageSession = networkStorageSession()) {
  • trunk/Source/WebKit/Shared/LoadParameters.cpp

    r257780 r261506  
    5858    encoder << clientRedirectSourceForHistory;
    5959    encoder << isNavigatingToAppBoundDomain;
    60     encoder << hasNavigatedAwayFromAppBoundDomain;
    6160
    6261    platformEncode(encoder);
     
    139138        return false;
    140139   
    141     if (!decoder.decode(data.hasNavigatedAwayFromAppBoundDomain))
    142         return false;
    143    
    144140    if (!platformDecode(decoder, data))
    145141        return false;
  • trunk/Source/WebKit/Shared/LoadParameters.h

    r260031 r261506  
    7171    WebCore::LockBackForwardList lockBackForwardList { WebCore::LockBackForwardList::No };
    7272    String clientRedirectSourceForHistory;
    73     Optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain { NavigatingToAppBoundDomain::No };
    74     NavigatedAwayFromAppBoundDomain hasNavigatedAwayFromAppBoundDomain { NavigatedAwayFromAppBoundDomain::No };
     73    Optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain;
    7574
    7675#if PLATFORM(COCOA)
  • trunk/Source/WebKit/Shared/PolicyDecision.h

    r260295 r261506  
    3434namespace WebKit {
    3535
    36 enum class NavigatedAwayFromAppBoundDomain : bool { Yes, No};
    37 
    3836struct PolicyDecision {
    3937    WebCore::PolicyCheckIdentifier identifier { };
    40     Optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain { NavigatingToAppBoundDomain::No };
    41     NavigatedAwayFromAppBoundDomain hasNavigatedAwayFromAppBoundDomain { NavigatedAwayFromAppBoundDomain::No };
     38    Optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain { WTF::nullopt };
    4239    WebCore::PolicyAction policyAction { WebCore::PolicyAction::Ignore };
    4340    uint64_t navigationID { 0 };
     
    5148        encoder << identifier;
    5249        encoder << isNavigatingToAppBoundDomain;
    53         encoder << hasNavigatedAwayFromAppBoundDomain;
    5450        encoder << policyAction;
    5551        encoder << navigationID;
     
    7066        decoder >> decodedIsNavigatingToAppBoundDomain;
    7167        if (!decodedIsNavigatingToAppBoundDomain)
    72             return WTF::nullopt;
    73        
    74         Optional<NavigatedAwayFromAppBoundDomain> decodedHasNavigatedAwayFromAppBoundDomain;
    75         decoder >> decodedHasNavigatedAwayFromAppBoundDomain;
    76         if (!decodedHasNavigatedAwayFromAppBoundDomain)
    7768            return WTF::nullopt;
    7869
     
    10293            return WTF::nullopt;
    10394
    104         return {{ WTFMove(*decodedIdentifier), WTFMove(*decodedIsNavigatingToAppBoundDomain), WTFMove(*decodedHasNavigatedAwayFromAppBoundDomain), WTFMove(*decodedPolicyAction), WTFMove(*decodedNavigationID), WTFMove(*decodedDownloadID), WTFMove(*decodedWebsitePoliciesData), WTFMove(*sandboxExtensionHandle)}};
     95        return {{ WTFMove(*decodedIdentifier), WTFMove(*decodedIsNavigatingToAppBoundDomain), WTFMove(*decodedPolicyAction), WTFMove(*decodedNavigationID), WTFMove(*decodedDownloadID), WTFMove(*decodedWebsitePoliciesData), WTFMove(*sandboxExtensionHandle)}};
    10596    }
    10697};
  • trunk/Source/WebKit/UIProcess/ProvisionalPageProxy.cpp

    r261254 r261506  
    157157}
    158158
    159 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)
     159void 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)
    160160{
    161161    RELEASE_LOG_IF_ALLOWED(ProcessSwapping, "loadData: pageProxyID=%" PRIu64 " webPageID=%" PRIu64, m_page.identifier().toUInt64(), m_webPageID.toUInt64());
    162162
    163     m_page.loadDataWithNavigationShared(m_process.copyRef(), m_webPageID, navigation, data, MIMEType, encoding, baseURL, userData, WebCore::ShouldTreatAsContinuingLoad::Yes, isNavigatingToAppBoundDomain, hasNavigatedAwayFromAppBoundDomain, WTFMove(websitePolicies), navigation.lastNavigationAction().shouldOpenExternalURLsPolicy);
    164 }
    165 
    166 void ProvisionalPageProxy::loadRequest(API::Navigation& navigation, WebCore::ResourceRequest&& request, API::Object* userData, Optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain, NavigatedAwayFromAppBoundDomain hasNavigatedAwayFromAppBoundDomain, Optional<WebsitePoliciesData>&& websitePolicies)
     163    m_page.loadDataWithNavigationShared(m_process.copyRef(), m_webPageID, navigation, data, MIMEType, encoding, baseURL, userData, WebCore::ShouldTreatAsContinuingLoad::Yes, isNavigatingToAppBoundDomain, WTFMove(websitePolicies), navigation.lastNavigationAction().shouldOpenExternalURLsPolicy);
     164}
     165
     166void ProvisionalPageProxy::loadRequest(API::Navigation& navigation, WebCore::ResourceRequest&& request, API::Object* userData, Optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain, Optional<WebsitePoliciesData>&& websitePolicies)
    167167{
    168168    RELEASE_LOG_IF_ALLOWED(ProcessSwapping, "loadRequest: pageProxyID=%" PRIu64 " webPageID=%" PRIu64, m_page.identifier().toUInt64(), m_webPageID.toUInt64());
     
    174174        navigation.fromItem()->setLastProcessIdentifier(m_process->coreProcessIdentifier());
    175175
    176     m_page.loadRequestWithNavigationShared(m_process.copyRef(), m_webPageID, navigation, WTFMove(request), navigation.lastNavigationAction().shouldOpenExternalURLsPolicy, userData, WebCore::ShouldTreatAsContinuingLoad::Yes, isNavigatingToAppBoundDomain, hasNavigatedAwayFromAppBoundDomain, WTFMove(websitePolicies));
     176    m_page.loadRequestWithNavigationShared(m_process.copyRef(), m_webPageID, navigation, WTFMove(request), navigation.lastNavigationAction().shouldOpenExternalURLsPolicy, userData, WebCore::ShouldTreatAsContinuingLoad::Yes, isNavigatingToAppBoundDomain, WTFMove(websitePolicies));
    177177}
    178178
     
    358358{
    359359    if (!isMainFrame || (m_mainFrame && m_mainFrame->frameID() != frameID) || navigationID != m_navigationID) {
    360         reply(PolicyDecision { identifier, NavigatingToAppBoundDomain::No, NavigatedAwayFromAppBoundDomain::No, WebCore::PolicyAction::Ignore, navigationID, DownloadID(), WTF::nullopt });
     360        reply(PolicyDecision { identifier, WTF::nullopt, WebCore::PolicyAction::Ignore, navigationID, DownloadID(), WTF::nullopt });
    361361        return;
    362362    }
  • trunk/Source/WebKit/UIProcess/ProvisionalPageProxy.h

    r260295 r261506  
    9393#endif
    9494
    95     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);
    96     void loadRequest(API::Navigation&, WebCore::ResourceRequest&&, API::Object* userData, Optional<NavigatingToAppBoundDomain>, NavigatedAwayFromAppBoundDomain, Optional<WebsitePoliciesData>&& = WTF::nullopt);
     95    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);
     96    void loadRequest(API::Navigation&, WebCore::ResourceRequest&&, API::Object* userData, Optional<NavigatingToAppBoundDomain>, Optional<WebsitePoliciesData>&& = WTF::nullopt);
    9797    void goToBackForwardItem(API::Navigation&, WebBackForwardListItem&, RefPtr<API::WebsitePolicies>&&);
    9898    void cancel();
  • trunk/Source/WebKit/UIProcess/WebPageProxy.cpp

    r261489 r261506  
    12821282        navigation->setClientNavigationActivity(process().throttler().foregroundActivity("Client navigation"_s));
    12831283
    1284     loadRequestWithNavigationShared(m_process.copyRef(), m_webPageID, navigation.get(), WTFMove(request), shouldOpenExternalURLsPolicy, userData, ShouldTreatAsContinuingLoad::No, isNavigatingToAppBoundDomain(), hasNavigatedAwayFromAppBoundDomain());
     1284    loadRequestWithNavigationShared(m_process.copyRef(), m_webPageID, navigation.get(), WTFMove(request), shouldOpenExternalURLsPolicy, userData, ShouldTreatAsContinuingLoad::No, isNavigatingToAppBoundDomain());
    12851285    return navigation;
    12861286}
    12871287
    1288 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)
     1288void 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)
    12891289{
    12901290    ASSERT(!m_isClosed);
     
    13091309    loadParameters.clientRedirectSourceForHistory = navigation.clientRedirectSourceForHistory();
    13101310    loadParameters.isNavigatingToAppBoundDomain = isNavigatingToAppBoundDomain;
    1311     loadParameters.hasNavigatedAwayFromAppBoundDomain = hasNavigatedAwayFromAppBoundDomain;
    13121311    maybeInitializeSandboxExtensionHandle(process, url, m_pageLoadState.resourceDirectoryURL(), loadParameters.sandboxExtensionHandle);
    13131312
     
    14061405        navigation->setClientNavigationActivity(process().throttler().foregroundActivity("Client navigation"_s));
    14071406
    1408     loadDataWithNavigationShared(m_process.copyRef(), m_webPageID, navigation, data, MIMEType, encoding, baseURL, userData, ShouldTreatAsContinuingLoad::No, isNavigatingToAppBoundDomain(), hasNavigatedAwayFromAppBoundDomain(), WTF::nullopt, shouldOpenExternalURLsPolicy);
     1407    loadDataWithNavigationShared(m_process.copyRef(), m_webPageID, navigation, data, MIMEType, encoding, baseURL, userData, ShouldTreatAsContinuingLoad::No, isNavigatingToAppBoundDomain(), WTF::nullopt, shouldOpenExternalURLsPolicy);
    14091408    return navigation;
    14101409}
    14111410
    1412 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)
     1411void 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)
    14131412{
    14141413    RELEASE_LOG_IF_ALLOWED(Loading, "loadDataWithNavigation");
     
    14311430    loadParameters.shouldOpenExternalURLsPolicy = shouldOpenExternalURLsPolicy;
    14321431    loadParameters.isNavigatingToAppBoundDomain = isNavigatingToAppBoundDomain;
    1433     loadParameters.hasNavigatedAwayFromAppBoundDomain = hasNavigatedAwayFromAppBoundDomain;
    14341432    addPlatformLoadParameters(loadParameters);
    14351433
     
    31323130            m_isNavigatingToAppBoundDomain = NavigatingToAppBoundDomain::Yes;
    31333131        } else {
     3132            if (m_hasExecutedAppBoundBehaviorBeforeNavigation)
     3133                return false;
    31343134            m_configuration->setWebViewCategory(WebViewCategory::InAppBrowser);
    31353135            m_isNavigatingToAppBoundDomain = NavigatingToAppBoundDomain::No;
    3136             m_hasNavigatedAwayFromAppBoundDomain = NavigatedAwayFromAppBoundDomain::Yes;
    31373136        }
    31383137    }
     
    32763275{
    32773276    if (!hasRunningProcess()) {
    3278         sender->send(PolicyDecision { sender->identifier(), isNavigatingToAppBoundDomain(), hasNavigatedAwayFromAppBoundDomain(), PolicyAction::Ignore, 0, DownloadID(), WTF::nullopt });
     3277        sender->send(PolicyDecision { sender->identifier(), isNavigatingToAppBoundDomain(), PolicyAction::Ignore, 0, DownloadID(), WTF::nullopt });
    32793278        return;
    32803279    }
     
    33033302        websitePoliciesData = websitePolicies->data();
    33043303
    3305     sender->send(PolicyDecision { sender->identifier(), isNavigatingToAppBoundDomain(), hasNavigatedAwayFromAppBoundDomain(), action, navigation ? navigation->navigationID() : 0, downloadID, WTFMove(websitePoliciesData), WTFMove(sandboxExtensionHandle) });
     3304    sender->send(PolicyDecision { sender->identifier(), isNavigatingToAppBoundDomain(), action, navigation ? navigation->navigationID() : 0, downloadID, WTFMove(websitePoliciesData), WTFMove(sandboxExtensionHandle) });
    33063305}
    33073306
     
    33843383        ASSERT(!navigation->currentRequest().isEmpty());
    33853384        if (auto& substituteData = navigation->substituteData())
    3386             m_provisionalPage->loadData(navigation, { substituteData->content.data(), substituteData->content.size() }, substituteData->MIMEType, substituteData->encoding, substituteData->baseURL, substituteData->userData.get(), isNavigatingToAppBoundDomain(), hasNavigatedAwayFromAppBoundDomain(), WTFMove(websitePoliciesData));
     3385            m_provisionalPage->loadData(navigation, { substituteData->content.data(), substituteData->content.size() }, substituteData->MIMEType, substituteData->encoding, substituteData->baseURL, substituteData->userData.get(), isNavigatingToAppBoundDomain(), WTFMove(websitePoliciesData));
    33873386        else
    3388             m_provisionalPage->loadRequest(navigation, ResourceRequest { navigation->currentRequest() }, nullptr, isNavigatingToAppBoundDomain(), hasNavigatedAwayFromAppBoundDomain(), WTFMove(websitePoliciesData));
     3387            m_provisionalPage->loadRequest(navigation, ResourceRequest { navigation->currentRequest() }, nullptr, isNavigatingToAppBoundDomain(), WTFMove(websitePoliciesData));
    33893388    };
    33903389    if (m_inspectorController->shouldPauseLoading(*m_provisionalPage))
     
    51085107    if (!checkURLReceivedFromCurrentOrPreviousWebProcess(process, request.url())) {
    51095108        RELEASE_LOG_ERROR_IF_ALLOWED(Process, "Ignoring request to load this main resource because it is outside the sandbox");
    5110         sender->send(PolicyDecision { sender->identifier(), isNavigatingToAppBoundDomain(), hasNavigatedAwayFromAppBoundDomain(), PolicyAction::Ignore, 0, DownloadID(), WTF::nullopt });
     5109        sender->send(PolicyDecision { sender->identifier(), isNavigatingToAppBoundDomain(), PolicyAction::Ignore, 0, DownloadID(), WTF::nullopt });
    51115110        return;
    51125111    }
     
    51825181        if (policyAction != PolicyAction::Ignore) {
    51835182            if (!setIsNavigatingToAppBoundDomainAndCheckIfPermitted(frame->isMainFrame(), navigation->currentRequest().url(), isAppBoundDomain)) {
    5184                 auto error = ResourceError { String { }, 0, navigation->currentRequest().url(), "Attempted navigation away from app-bound domain"_s };
     5183                auto error = ResourceError { String { }, 0, navigation->currentRequest().url(), "App-bound domain failure"_s };
    51855184                m_navigationClient->didFailProvisionalNavigationWithError(*this, FrameInfoData { frameInfo }, navigation.get(), error, userDataObject);
    5186                 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");
     5185                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");
    51875186                completionHandler(PolicyAction::Ignore);
    51885187                return;
     
    53565355
    53575356    // If the client did not respond synchronously, proceed with the load.
    5358     sender->send(PolicyDecision { sender->identifier(), isNavigatingToAppBoundDomain(), hasNavigatedAwayFromAppBoundDomain(), PolicyAction::Use, navigationID, DownloadID(), WTF::nullopt });
     5357    sender->send(PolicyDecision { sender->identifier(), isNavigatingToAppBoundDomain(), PolicyAction::Use, navigationID, DownloadID(), WTF::nullopt });
    53595358}
    53605359
  • trunk/Source/WebKit/UIProcess/WebPageProxy.h

    r261457 r261506  
    16511651    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&);
    16521652    void startURLSchemeTaskShared(Ref<WebProcessProxy>&&, WebCore::PageIdentifier, URLSchemeTaskParameters&&);
    1653     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);
    1654     void loadRequestWithNavigationShared(Ref<WebProcessProxy>&&, WebCore::PageIdentifier, API::Navigation&, WebCore::ResourceRequest&&, WebCore::ShouldOpenExternalURLsPolicy, API::Object* userData, WebCore::ShouldTreatAsContinuingLoad, Optional<NavigatingToAppBoundDomain>, NavigatedAwayFromAppBoundDomain, Optional<WebsitePoliciesData>&& = WTF::nullopt);
     1653    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);
     1654    void loadRequestWithNavigationShared(Ref<WebProcessProxy>&&, WebCore::PageIdentifier, API::Navigation&, WebCore::ResourceRequest&&, WebCore::ShouldOpenExternalURLsPolicy, API::Object* userData, WebCore::ShouldTreatAsContinuingLoad, Optional<NavigatingToAppBoundDomain>, Optional<WebsitePoliciesData>&& = WTF::nullopt);
    16551655    void backForwardGoToItemShared(Ref<WebProcessProxy>&&, const WebCore::BackForwardItemIdentifier&, CompletionHandler<void(const WebBackForwardListCounts&)>&&);
    16561656    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&&);
     
    17641764#endif
    17651765
     1766    void setHasExecutedAppBoundBehaviorBeforeNavigation() { m_hasExecutedAppBoundBehaviorBeforeNavigation = true; }
     1767       
    17661768private:
    17671769    WebPageProxy(PageClient&, WebProcessProxy&, Ref<API::PageConfiguration>&&);
     
    23182320       
    23192321    bool setIsNavigatingToAppBoundDomainAndCheckIfPermitted(bool isMainFrame, const URL&, Optional<NavigatingToAppBoundDomain>);
    2320     NavigatedAwayFromAppBoundDomain hasNavigatedAwayFromAppBoundDomain() const { return m_hasNavigatedAwayFromAppBoundDomain; }
    23212322       
    23222323    const Identifier m_identifier;
     
    28122813#endif
    28132814       
    2814     Optional<NavigatingToAppBoundDomain> m_isNavigatingToAppBoundDomain { NavigatingToAppBoundDomain::No };
    2815     NavigatedAwayFromAppBoundDomain m_hasNavigatedAwayFromAppBoundDomain { NavigatedAwayFromAppBoundDomain::No };
     2815    Optional<NavigatingToAppBoundDomain> m_isNavigatingToAppBoundDomain;
    28162816    bool m_ignoresAppBoundDomains { false };
    28172817    bool m_userScriptsNotified { false };
    28182818    bool m_limitsNavigationsToAppBoundDomains { false };
     2819    bool m_hasExecutedAppBoundBehaviorBeforeNavigation { false };
    28192820
    28202821#if ENABLE(ROUTING_ARBITRATION)
  • trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in

    r261457 r261506  
    600600#endif
    601601
     602    SetHasExecutedAppBoundBehaviorBeforeNavigation()
    602603}
  • trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp

    r261323 r261506  
    831831    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())))) {
    832832        WEBFRAMELOADERCLIENT_RELEASE_LOG(Network, "dispatchDecidePolicyForResponse: ignoring because WebPageProxy::DecidePolicyForResponse failed");
    833         m_frame->didReceivePolicyDecision(listenerID, PolicyDecision { identifier, NavigatingToAppBoundDomain::No, NavigatedAwayFromAppBoundDomain::No, PolicyAction::Ignore, 0, { }, { } });
     833        m_frame->didReceivePolicyDecision(listenerID, PolicyDecision { identifier, WTF::nullopt, PolicyAction::Ignore, 0, { }, { } });
    834834    }
    835835}
     
    993993
    994994        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))) {
    995             m_frame->didReceivePolicyDecision(listenerID, PolicyDecision { requestIdentifier, NavigatingToAppBoundDomain::No, NavigatedAwayFromAppBoundDomain::No, PolicyAction::Ignore, 0, { }, { } });
     995            m_frame->didReceivePolicyDecision(listenerID, PolicyDecision { requestIdentifier, WTF::nullopt, PolicyAction::Ignore, 0, { }, { } });
    996996            return;
    997997        }
    998998
    999         m_frame->didReceivePolicyDecision(listenerID, PolicyDecision { policyDecision.identifier, policyDecision.isNavigatingToAppBoundDomain, policyDecision.hasNavigatedAwayFromAppBoundDomain, policyDecision.policyAction, 0, policyDecision.downloadID, { }});
     999        m_frame->didReceivePolicyDecision(listenerID, PolicyDecision { policyDecision.identifier, policyDecision.isNavigatingToAppBoundDomain, policyDecision.policyAction, 0, policyDecision.downloadID, { }});
    10001000        return;
    10011001    }
     
    10031003    ASSERT(policyDecisionMode == PolicyDecisionMode::Asynchronous);
    10041004    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)))
    1005         m_frame->didReceivePolicyDecision(listenerID, PolicyDecision { requestIdentifier, NavigatingToAppBoundDomain::No, NavigatedAwayFromAppBoundDomain::No, PolicyAction::Ignore, 0, { }, { } });
     1005        m_frame->didReceivePolicyDecision(listenerID, PolicyDecision { requestIdentifier, WTF::nullopt, PolicyAction::Ignore, 0, { }, { } });
    10061006}
    10071007
     
    19221922#endif // ENABLE(APPLICATION_MANIFEST)
    19231923
    1924 bool WebFrameLoaderClient::hasNavigatedAwayFromAppBoundDomain()
     1924bool WebFrameLoaderClient::shouldEnableInAppBrowserPrivacyProtections() const
    19251925{
    19261926    if (!m_frame->isMainFrame())
     
    19301930    if (!webPage)
    19311931        return false;
    1932    
    1933     return webPage->hasNavigatedAwayFromAppBoundDomain() == NavigatedAwayFromAppBoundDomain::Yes;
    1934 }
    1935 
    1936 bool WebFrameLoaderClient::needsInAppBrowserPrivacyQuirks() const
    1937 {
     1932
     1933    return webPage->shouldEnableInAppBrowserPrivacyProtections();
     1934}
     1935
     1936void WebFrameLoaderClient::notifyPageOfAppBoundBehavior()
     1937{
     1938    if (!m_frame->isMainFrame())
     1939        return;
     1940
    19381941    auto* webPage = m_frame->page();
    19391942    if (!webPage)
    1940         return false;
    1941    
    1942     return webPage->needsInAppBrowserPrivacyQuirks();
    1943 }
    1944 
     1943        return;
     1944
     1945    webPage->notifyPageOfAppBoundBehavior();
     1946}
    19451947
    19461948} // namespace WebKit
  • trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.h

    r260751 r261506  
    289289#endif
    290290
    291     bool hasNavigatedAwayFromAppBoundDomain() final;
    292     bool needsInAppBrowserPrivacyQuirks() const final;
     291    bool shouldEnableInAppBrowserPrivacyProtections() const final;
     292    void notifyPageOfAppBoundBehavior() final;
    293293};
    294294
  • trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp

    r261398 r261506  
    476476    , m_overriddenMediaType(parameters.overriddenMediaType)
    477477    , m_processDisplayName(parameters.processDisplayName)
    478     , m_isNavigatingToAppBoundDomain(parameters.limitsNavigationsToAppBoundDomains ? NavigatingToAppBoundDomain::Yes : NavigatingToAppBoundDomain::No)
     478    , m_limitsNavigationsToAppBoundDomains(parameters.limitsNavigationsToAppBoundDomains)
    479479{
    480480    ASSERT(m_identifier);
     
    15281528{
    15291529    setIsNavigatingToAppBoundDomain(loadParameters.isNavigatingToAppBoundDomain);
    1530     setHasNavigatedAwayFromAppBoundDomain(loadParameters.hasNavigatedAwayFromAppBoundDomain);
    15311530
    15321531    SendStopResponsivenessTimer stopper;
     
    15641563}
    15651564
    1566 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)
     1565void 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)
    15671566{
    15681567    setIsNavigatingToAppBoundDomain(isNavigatingToAppBoundDomain);
    1569     setHasNavigatedAwayFromAppBoundDomain(hasNavigatedAwayFromAppBoundDomain);
    15701568
    15711569    SendStopResponsivenessTimer stopper;
     
    15961594    auto sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(loadParameters.data.data()), loadParameters.data.size());
    15971595    URL baseURL = loadParameters.baseURLString.isEmpty() ? aboutBlankURL() : URL(URL(), loadParameters.baseURLString);
    1598     loadDataImpl(loadParameters.navigationID, loadParameters.shouldTreatAsContinuingLoad, WTFMove(loadParameters.websitePolicies), WTFMove(sharedBuffer), loadParameters.MIMEType, loadParameters.encodingName, baseURL, URL(), loadParameters.userData, loadParameters.isNavigatingToAppBoundDomain, loadParameters.hasNavigatedAwayFromAppBoundDomain, loadParameters.shouldOpenExternalURLsPolicy);
     1596    loadDataImpl(loadParameters.navigationID, loadParameters.shouldTreatAsContinuingLoad, WTFMove(loadParameters.websitePolicies), WTFMove(sharedBuffer), loadParameters.MIMEType, loadParameters.encodingName, baseURL, URL(), loadParameters.userData, loadParameters.isNavigatingToAppBoundDomain, loadParameters.shouldOpenExternalURLsPolicy);
    15991597}
    16001598
     
    16081606    auto sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(loadParameters.data.data()), loadParameters.data.size());
    16091607    m_mainFrame->coreFrame()->loader().setProvisionalLoadErrorBeingHandledURL(provisionalLoadErrorURL);   
    1610     loadDataImpl(loadParameters.navigationID, loadParameters.shouldTreatAsContinuingLoad, WTFMove(loadParameters.websitePolicies), WTFMove(sharedBuffer), loadParameters.MIMEType, loadParameters.encodingName, baseURL, unreachableURL, loadParameters.userData, loadParameters.isNavigatingToAppBoundDomain, loadParameters.hasNavigatedAwayFromAppBoundDomain);
     1608    loadDataImpl(loadParameters.navigationID, loadParameters.shouldTreatAsContinuingLoad, WTFMove(loadParameters.websitePolicies), WTFMove(sharedBuffer), loadParameters.MIMEType, loadParameters.encodingName, baseURL, unreachableURL, loadParameters.userData, loadParameters.isNavigatingToAppBoundDomain);
    16111609    m_mainFrame->coreFrame()->loader().setProvisionalLoadErrorBeingHandledURL({ });
    16121610}
     
    32543252{
    32553253    setIsNavigatingToAppBoundDomain(policyDecision.isNavigatingToAppBoundDomain);
    3256     setHasNavigatedAwayFromAppBoundDomain(policyDecision.hasNavigatedAwayFromAppBoundDomain);
    32573254
    32583255    WebFrame* frame = WebProcess::singleton().webFrame(frameID);
     
    34273424        send(Messages::WebPageProxy::ScriptValueCallback(dataReference, details, callbackID));
    34283425    };
    3429    
    3430     if (hasNavigatedAwayFromAppBoundDomain() == NavigatedAwayFromAppBoundDomain::Yes && !m_needsInAppBrowserPrivacyQuirks) {
     3426    if (shouldEnableInAppBrowserPrivacyProtections()) {
    34313427        send(Messages::WebPageProxy::ScriptValueCallback({ }, ExceptionDetails { "Unable to execute JavaScript"_s }, callbackID));
    34323428        if (auto* document = m_page->mainFrame().document())
     
    36843680
    36853681    if (store.getBoolValueForKey(WebPreferencesKey::serviceWorkersEnabledKey())) {
    3686         ASSERT(parentProcessHasServiceWorkerEntitlement() || m_isNavigatingToAppBoundDomain);
    3687         if (!parentProcessHasServiceWorkerEntitlement() && !m_isNavigatingToAppBoundDomain)
     3682        ASSERT(parentProcessHasServiceWorkerEntitlement() || m_limitsNavigationsToAppBoundDomains);
     3683        if (!parentProcessHasServiceWorkerEntitlement() && !m_limitsNavigationsToAppBoundDomains)
    36883684            RuntimeEnabledFeatures::sharedFeatures().setServiceWorkerEnabled(false);
    36893685    }
     
    71037099#endif
    71047100
     7101void WebPage::setIsNavigatingToAppBoundDomain(Optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain)
     7102{
     7103    m_isNavigatingToAppBoundDomain = isNavigatingToAppBoundDomain;
     7104   
     7105    m_navigationHasOccured = true;
     7106}
     7107
     7108void WebPage::notifyPageOfAppBoundBehavior()
     7109{
     7110    if (!m_navigationHasOccured && !m_limitsNavigationsToAppBoundDomains)
     7111        send(Messages::WebPageProxy::SetHasExecutedAppBoundBehaviorBeforeNavigation());
     7112}
     7113
     7114bool WebPage::shouldEnableInAppBrowserPrivacyProtections()
     7115{
     7116    if (m_needsInAppBrowserPrivacyQuirks)
     7117        return false;
     7118
     7119    return isNavigatingToAppBoundDomain() && isNavigatingToAppBoundDomain() == NavigatingToAppBoundDomain::No;
     7120}
     7121
    71057122} // namespace WebKit
    71067123
  • trunk/Source/WebKit/WebProcess/WebPage/WebPage.h

    r261457 r261506  
    13161316    void getAllFrames(CompletionHandler<void(FrameTreeNodeData&&)>&&);
    13171317
    1318     void setIsNavigatingToAppBoundDomain(Optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain) { m_isNavigatingToAppBoundDomain = isNavigatingToAppBoundDomain; }
     1318    void notifyPageOfAppBoundBehavior();
     1319    bool shouldEnableInAppBrowserPrivacyProtections();
     1320    void setIsNavigatingToAppBoundDomain(Optional<NavigatingToAppBoundDomain>);
    13191321    Optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain() const { return m_isNavigatingToAppBoundDomain; }
    1320     NavigatedAwayFromAppBoundDomain hasNavigatedAwayFromAppBoundDomain() const { return m_hasNavigatedAwayFromAppBoundDomain; }
    1321     void setHasNavigatedAwayFromAppBoundDomain(NavigatedAwayFromAppBoundDomain navigatedAwayFromAppBoundDomain) { m_hasNavigatedAwayFromAppBoundDomain = navigatedAwayFromAppBoundDomain; }
    1322     bool needsInAppBrowserPrivacyQuirks() const { return m_needsInAppBrowserPrivacyQuirks; }
    13231322   
    13241323    bool shouldUseRemoteRenderingFor(WebCore::RenderingPurpose);
     
    14201419    String sourceForFrame(WebFrame*);
    14211420
    1422     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);
     1421    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);
    14231422
    14241423    // Actions
     
    21052104#endif
    21062105   
    2107     Optional<NavigatingToAppBoundDomain> m_isNavigatingToAppBoundDomain { NavigatingToAppBoundDomain::No };
    2108     NavigatedAwayFromAppBoundDomain m_hasNavigatedAwayFromAppBoundDomain { NavigatedAwayFromAppBoundDomain::No };
     2106    Optional<NavigatingToAppBoundDomain> m_isNavigatingToAppBoundDomain;
     2107    bool m_limitsNavigationsToAppBoundDomains { false };
     2108    bool m_navigationHasOccured { false };
    21092109};
    21102110
  • trunk/Tools/ChangeLog

    r261496 r261506  
     12020-05-11  Kate Cheney  <katherine_cheney@apple.com>
     2
     3        Fail navigations to non app-bound domains after use of app-bound APIs
     4        https://bugs.webkit.org/show_bug.cgi?id=211647
     5        <rdar://problem/62978159>
     6
     7        Reviewed by Brent Fulgham.
     8
     9        Added a new test to confirm a non-app bound navigation fails after
     10        using script injection.
     11
     12        This fix also required changing any test which uses a restricted API
     13        to confirm behavior of another restricted API. Tests can set
     14        _setNeedsInAppBrowserPrivacyQuirks in the configuration to indicate
     15        APIs should not be blocked, then toggle it to test actual behavior.
     16
     17        Also, we can remove any calls to _setInAppBrowserPrivacyEnabled
     18        now that this is just an internal test flag.
     19
     20        * TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm:
     21        (-[AppBoundDomainDelegate webView:didFinishNavigation:]):
     22        (-[AppBoundDomainDelegate webView:didFailProvisionalNavigation:withError:]):
     23        (-[AppBoundDomainDelegate waitForDidFinishNavigation]):
     24        (-[AppBoundDomainDelegate waitForDidFailProvisionalNavigationError]):
     25        (TEST):
     26
    1272020-05-11  Alex Christensen  <achristensen@webkit.org>
    228
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm

    r260968 r261506  
    4949static bool isDone;
    5050
     51@interface AppBoundDomainDelegate : NSObject <WKNavigationDelegate>
     52- (void)waitForDidFinishNavigation;
     53- (NSError *)waitForDidFailProvisionalNavigationError;
     54@end
     55
     56@implementation AppBoundDomainDelegate {
     57    bool _navigationFinished;
     58    RetainPtr<NSError> _provisionalNavigationFailedError;
     59}
     60
     61- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
     62{
     63    _navigationFinished = true;
     64}
     65
     66- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error
     67{
     68    _provisionalNavigationFailedError = error;
     69}
     70
     71- (void)waitForDidFinishNavigation
     72{
     73    TestWebKitAPI::Util::run(&_navigationFinished);
     74}
     75
     76- (NSError *)waitForDidFailProvisionalNavigationError
     77{
     78    while (!_provisionalNavigationFailedError)
     79        TestWebKitAPI::Util::spinRunLoop();
     80    return _provisionalNavigationFailedError.autorelease();
     81}
     82
     83@end
     84
    5185static NSString * const userScriptSource = @"window.wkUserScriptInjected = true";
    5286
     
    104138    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"in-app-browser"];
    105139    [configuration.userContentController addUserScript:userScript.get()];
    106     [[configuration preferences] _setNeedsInAppBrowserPrivacyQuirks:NO];
    107     [[configuration preferences] _setInAppBrowserPrivacyEnabled:YES];
    108140
    109141    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration]);
     
    122154    TestWebKitAPI::Util::run(&isDone);
    123155
    124     // Turn back on In-App Browser Privacy quirks to check that original attempt to set this variable was rejected.
    125     isDone = false;
     156    // Disable script injection blocking to check that original attempt to set this variable was rejected.
    126157    [[[webView configuration] preferences] _setNeedsInAppBrowserPrivacyQuirks:YES];
    127158    [webView evaluateJavaScript:@"window.wkUserScriptInjected" completionHandler:^(id _Nullable result, NSError * _Nullable error) {
     
    146177    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"in-app-browser"];
    147178    [configuration.userContentController addUserScript:userScript.get()];
    148     [[configuration preferences] _setNeedsInAppBrowserPrivacyQuirks:NO];
    149     [[configuration preferences] _setInAppBrowserPrivacyEnabled:YES];
    150179
    151180    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration]);
     
    164193    TestWebKitAPI::Util::run(&isDone);
    165194
    166     // Turn back on In-App Browser Privacy quirks to check that original attempt to set this variable was rejected.
    167     isDone = false;
     195    // Disable script injection blocking to check that original attempt to set this variable was rejected.
    168196    [[[webView configuration] preferences] _setNeedsInAppBrowserPrivacyQuirks:YES];
    169197    [webView evaluateJavaScript:@"window.wkUserScriptInjected" completionHandler:^(id _Nullable result, NSError * _Nullable error) {
     
    180208TEST(InAppBrowserPrivacy, NonAppBoundDomainFailedUserAgentScripts)
    181209{
     210    initializeInAppBrowserPrivacyTestSettings();
     211
    182212    WKWebViewConfiguration *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals" configureJSCForTesting:YES];
     213    // Disable blocking of restricted APIs for test setup.
    183214    [[configuration preferences] _setNeedsInAppBrowserPrivacyQuirks:YES];
    184     [[configuration preferences] _setInAppBrowserPrivacyEnabled:NO];
    185215
    186216    auto schemeHandler = adoptNS([[InAppBrowserSchemeHandler alloc] init]);
     
    199229    isDone = false;
    200230    TestWebKitAPI::Util::run(&isDone);
    201 
    202     initializeInAppBrowserPrivacyTestSettings();
     231   
     232    // Enable blocking of restricted APIs.
    203233    [[configuration preferences] _setNeedsInAppBrowserPrivacyQuirks:NO];
    204     [[configuration preferences] _setInAppBrowserPrivacyEnabled:YES];
    205234
    206235    auto webView2 = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration]);
    207 
    208236    isDone = false;
    209237    [webView2 loadRequest:request];
     
    245273    initializeInAppBrowserPrivacyTestSettings();
    246274    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    247     [[configuration preferences] _setInAppBrowserPrivacyEnabled:YES];
    248275    [configuration setLimitsNavigationsToAppBoundDomains:YES];
    249276
     
    266293    initializeInAppBrowserPrivacyTestSettings();
    267294    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    268     [[configuration preferences] _setInAppBrowserPrivacyEnabled:YES];
    269295    [configuration setLimitsNavigationsToAppBoundDomains:YES];
    270296
     
    286312    initializeInAppBrowserPrivacyTestSettings();
    287313    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    288     [[configuration preferences] _setInAppBrowserPrivacyEnabled:YES];
    289314    [configuration setLimitsNavigationsToAppBoundDomains:YES];
    290315
     
    304329static NSString *styleSheetSource = @"body { background-color: green !important; }";
    305330static NSString *backgroundColorScript = @"window.getComputedStyle(document.body, null).getPropertyValue('background-color')";
    306 static NSString *frameBackgroundColorScript = @"window.getComputedStyle(document.getElementsByTagName('iframe')[0].contentDocument.body, null).getPropertyValue('background-color')";
    307331static const char* redInRGB = "rgb(255, 0, 0)";
    308332static const char* blackInRGB = "rgba(0, 0, 0, 0)";
     
    330354    auto schemeHandler = adoptNS([[InAppBrowserSchemeHandler alloc] init]);
    331355    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"in-app-browser"];
    332     [[configuration preferences] _setInAppBrowserPrivacyEnabled:YES];
    333     [[configuration preferences] _setNeedsInAppBrowserPrivacyQuirks:YES];
     356    RetainPtr<_WKUserContentWorld> world = [_WKUserContentWorld worldWithName:@"TestWorld"];
    334357
    335358    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration.get()]);
    336     NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"in-app-browser:///in-app-browser-privacy-test-user-style-sheets"]];
    337     [webView loadRequest:request];
    338     [webView _test_waitForDidFinishNavigation];
    339 
    340     RetainPtr<_WKUserContentWorld> world = [_WKUserContentWorld worldWithName:@"TestWorld"];
    341359    RetainPtr<_WKUserStyleSheet> styleSheet = adoptNS([[_WKUserStyleSheet alloc] initWithSource:styleSheetSource forWKWebView:webView.get() forMainFrameOnly:YES level:_WKUserStyleUserLevel userContentWorld:world.get()]);
    342360    [[configuration userContentController] _addUserStyleSheet:styleSheet.get()];
    343361
    344     expectScriptEvaluatesToColor(webView.get(), backgroundColorScript, redInRGB);
     362    auto delegate = adoptNS([AppBoundDomainDelegate new]);
     363    [webView setNavigationDelegate:delegate.get()];
     364
     365    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"in-app-browser:///in-app-browser-privacy-test-user-style-sheets"]];
     366    [webView loadRequest:request];
     367    NSError *error = [delegate waitForDidFailProvisionalNavigationError];
     368    EXPECT_WK_STREQ(error.localizedDescription, @"App-bound domain failure");
    345369    cleanUpInAppBrowserPrivacyTestSettings();
    346370}
     
    354378    auto schemeHandler = adoptNS([[InAppBrowserSchemeHandler alloc] init]);
    355379    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"in-app-browser"];
    356     [[configuration preferences] _setInAppBrowserPrivacyEnabled:YES];
    357     [[configuration preferences] _setNeedsInAppBrowserPrivacyQuirks:YES];
    358 
    359     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration.get()]);
    360     NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"in-app-browser:///in-app-browser-privacy-test-user-style-sheets"]];
    361     [webView loadRequest:request];
    362     [webView _test_waitForDidFinishNavigation];
    363 
     380   
    364381    RetainPtr<_WKUserStyleSheet> styleSheet = adoptNS([[_WKUserStyleSheet alloc] initWithSource:styleSheetSource forMainFrameOnly:YES]);
    365382    [[configuration userContentController] _addUserStyleSheet:styleSheet.get()];
    366 
    367     expectScriptEvaluatesToColor(webView.get(), backgroundColorScript, redInRGB);
     383   
     384    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration.get()]);
     385    auto delegate = adoptNS([AppBoundDomainDelegate new]);
     386    [webView setNavigationDelegate:delegate.get()];
     387
     388    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"in-app-browser:///in-app-browser-privacy-test-user-style-sheets"]];
     389    [webView loadRequest:request];
     390    NSError *error = [delegate waitForDidFailProvisionalNavigationError];
     391    EXPECT_WK_STREQ(error.localizedDescription, @"App-bound domain failure");
    368392    cleanUpInAppBrowserPrivacyTestSettings();
    369393}
     
    377401    auto schemeHandler = adoptNS([[InAppBrowserSchemeHandler alloc] init]);
    378402    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"in-app-browser"];
    379     [[configuration preferences] _setInAppBrowserPrivacyEnabled:YES];
    380     [[configuration preferences] _setNeedsInAppBrowserPrivacyQuirks:YES];
    381 
    382     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration.get()]);
    383     NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"in-app-browser:///in-app-browser-privacy-test-user-style-sheets-iframe"]];
    384     [webView loadRequest:request];
    385     [webView _test_waitForDidFinishNavigation];
    386 
    387403    RetainPtr<_WKUserStyleSheet> styleSheet = adoptNS([[_WKUserStyleSheet alloc] initWithSource:styleSheetSource forMainFrameOnly:NO]);
    388404    [[configuration userContentController] _addUserStyleSheet:styleSheet.get()];
    389405
    390     // The main frame should be affected.
    391     expectScriptEvaluatesToColor(webView.get(), backgroundColorScript, redInRGB);
    392 
    393     // The subframe should also be affected.
    394     expectScriptEvaluatesToColor(webView.get(), frameBackgroundColorScript, redInRGB);
     406    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration.get()]);
     407    auto delegate = adoptNS([AppBoundDomainDelegate new]);
     408    [webView setNavigationDelegate:delegate.get()];
     409
     410    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"in-app-browser:///in-app-browser-privacy-test-user-style-sheets-iframe"]];
     411    [webView loadRequest:request];
     412    NSError *error = [delegate waitForDidFailProvisionalNavigationError];
     413    EXPECT_WK_STREQ(error.localizedDescription, @"App-bound domain failure");
    395414    cleanUpInAppBrowserPrivacyTestSettings();
    396415}
     
    405424    auto schemeHandler = adoptNS([[InAppBrowserSchemeHandler alloc] init]);
    406425    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"in-app-browser"];
    407     [[configuration preferences] _setInAppBrowserPrivacyEnabled:YES];
    408     [[configuration preferences] _setNeedsInAppBrowserPrivacyQuirks:YES];
    409426
    410427    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration.get()]);
     
    417434    [webView loadRequest:request];
    418435    [webView _test_waitForDidFinishNavigation];
     436   
     437    // Disable script injection blocking to check that the request for message
     438    // handlers returned null.
     439    [[configuration preferences] _setNeedsInAppBrowserPrivacyQuirks:YES];
    419440
    420441    // Set the background color to red if message handlers returned null so we can
     
    433454    auto schemeHandler = adoptNS([[InAppBrowserSchemeHandler alloc] init]);
    434455    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"in-app-browser"];
    435     [[configuration preferences] _setInAppBrowserPrivacyEnabled:YES];
    436456    [configuration setLimitsNavigationsToAppBoundDomains:YES];
    437457
     
    834854}
    835855
    836 @interface AppBoundDomainDelegate : NSObject <WKNavigationDelegate>
    837 - (void)waitForDidFinishNavigation;
    838 - (NSError *)waitForDidFailProvisionalNavigationError;
    839 @end
    840 
    841 @implementation AppBoundDomainDelegate {
    842     bool _navigationFinished;
    843     RetainPtr<NSError> _provisionalNavigationFailedError;
    844 }
    845 
    846 - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
    847 {
    848     _navigationFinished = true;
    849 }
    850 
    851 - (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error
    852 {
    853     _provisionalNavigationFailedError = error;
    854 }
    855 
    856 - (void)waitForDidFinishNavigation
    857 {
    858     TestWebKitAPI::Util::run(&_navigationFinished);
    859 }
    860 
    861 - (NSError *)waitForDidFailProvisionalNavigationError
    862 {
    863     while (!_provisionalNavigationFailedError)
    864         TestWebKitAPI::Util::spinRunLoop();
    865     return _provisionalNavigationFailedError.autorelease();
    866 }
    867 
    868 @end
    869 
    870856TEST(InAppBrowserPrivacy, AppBoundFlagForNonAppBoundDomainFails)
    871857{
     
    886872    [webView loadRequest:request];
    887873    NSError *error = [delegate waitForDidFailProvisionalNavigationError];
    888     EXPECT_WK_STREQ(error.localizedDescription, @"Attempted navigation away from app-bound domain");
     874    EXPECT_WK_STREQ(error.localizedDescription, @"App-bound domain failure");
    889875
    890876    // Make sure the load didn't complete by checking the background color.
     
    917903    [webView loadRequest:request];
    918904    NSError *error = [delegate waitForDidFailProvisionalNavigationError];
    919     EXPECT_WK_STREQ(error.localizedDescription, @"Attempted navigation away from app-bound domain");
     905    EXPECT_WK_STREQ(error.localizedDescription, @"App-bound domain failure");
    920906
    921907    // Make sure the load didn't complete by checking the background color.
     
    992978
    993979    // Navigation should be successful, but this WebView should not get app-bound domain
    994     // privileges like user style sheets. Set quirks to true so we can evaluate script
    995     // to check.
    996     [[[webView configuration] preferences] _setNeedsInAppBrowserPrivacyQuirks:YES];
    997     expectScriptEvaluatesToColor(webView.get(), backgroundColorScript, blackInRGB);
    998     cleanUpInAppBrowserPrivacyTestSettings();
     980    // privileges like script injection.
     981    isDone = false;
     982    [webView evaluateJavaScript:@"window.wkUserScriptInjected" completionHandler:^(id _Nullable result, NSError * _Nullable error) {
     983        EXPECT_TRUE(!!error);
     984        isDone = true;
     985    }];
     986
     987    TestWebKitAPI::Util::run(&isDone);
    999988}
    1000989
     
    10301019    [webView loadRequest:request];
    10311020    NSError *error = [delegate waitForDidFailProvisionalNavigationError];
    1032     EXPECT_WK_STREQ(error.localizedDescription, @"Attempted navigation away from app-bound domain");
     1021    EXPECT_WK_STREQ(error.localizedDescription, @"App-bound domain failure");
    10331022
    10341023    cleanUpInAppBrowserPrivacyTestSettings();
     1024}
     1025
     1026TEST(InAppBrowserPrivacy, InjectScriptThenNavigateToNonAppBoundDomainFails)
     1027{
     1028    isDone = false;
     1029    initializeInAppBrowserPrivacyTestSettings();
     1030    auto userScript = adoptNS([[WKUserScript alloc] initWithSource:userScriptSource injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:YES]);
     1031
     1032    WKWebViewConfiguration *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals" configureJSCForTesting:YES];
     1033    auto schemeHandler = adoptNS([[InAppBrowserSchemeHandler alloc] init]);
     1034    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"in-app-browser"];
     1035    [configuration.userContentController addUserScript:userScript.get()];
     1036    [[configuration preferences] _setNeedsInAppBrowserPrivacyQuirks:NO];
     1037
     1038    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration]);
     1039    auto delegate = adoptNS([AppBoundDomainDelegate new]);
     1040    [webView setNavigationDelegate:delegate.get()];
     1041
     1042    isDone = false;
     1043    [webView evaluateJavaScript:@"window.wkUserScriptInjected" completionHandler:^(id _Nullable result, NSError * _Nullable error) {
     1044        EXPECT_FALSE(!!error);
     1045        isDone = true;
     1046    }];
     1047
     1048    TestWebKitAPI::Util::run(&isDone);
     1049   
     1050    // Load a non-app bound domain.
     1051    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"in-app-browser:///in-app-browser-privacy-test-user-agent-script"]];
     1052    [webView loadRequest:request];
     1053    NSError *error = [delegate waitForDidFailProvisionalNavigationError];
     1054    EXPECT_WK_STREQ(error.localizedDescription, @"App-bound domain failure");
    10351055}
    10361056
Note: See TracChangeset for help on using the changeset viewer.