Changeset 259520 in webkit


Ignore:
Timestamp:
Apr 3, 2020 4:39:06 PM (4 years ago)
Author:
Kate Cheney
Message:

Prevent non app-bound domain cookies from being read or set using API calls
https://bugs.webkit.org/show_bug.cgi?id=209926
<rdar://problem/61071428>

Reviewed by Brady Eidson.

Source/WebKit:

This patch filters out setting and fetching of cookies via API call
to only set or return app-bound cookies.

  • UIProcess/API/APIHTTPCookieStore.cpp:

(API::HTTPCookieStore::filterAppBoundCookies):
This function queries the websiteDataStore for the WKAppBoundDomains
entries and filters out non app-bound domains.

(API::HTTPCookieStore::cookies):
(API::HTTPCookieStore::cookiesForURL):
(API::HTTPCookieStore::setCookies):
These functions were updated to set/return the cookies after they've
been filtered through the WKAppBoundDomains.

  • UIProcess/API/APIHTTPCookieStore.h:
  • UIProcess/API/Cocoa/WKWebsiteDataStore.mm:

(-[WKWebsiteDataStore _appBoundDomains:]):

  • UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm:

(WebKit::WebsiteDataStore::getAppBoundDomains const):
(WebKit::WebsiteDataStore::appBoundDomainsForTesting const): Deleted.
Utilize a function formerly used for testing only to be used in the
HTTPCookieStore.

  • UIProcess/WebsiteData/WebsiteDataStore.h:

Tools:

Added 3 new API tests to test that non app-bound cookies are not being
set or returned via API calls. Also added a function to reset state
between tests for internal debugging.

  • TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm:

(setUpCookieTest):
(TEST):

Location:
trunk
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r259518 r259520  
     12020-04-03  Kate Cheney  <katherine_cheney@apple.com>
     2
     3        Prevent non app-bound domain cookies from being read or set using API calls
     4        https://bugs.webkit.org/show_bug.cgi?id=209926
     5        <rdar://problem/61071428>
     6
     7        Reviewed by Brady Eidson.
     8
     9        This patch filters out setting and fetching of cookies via API call
     10        to only set or return app-bound cookies.
     11
     12        * UIProcess/API/APIHTTPCookieStore.cpp:
     13        (API::HTTPCookieStore::filterAppBoundCookies):
     14        This function queries the websiteDataStore for the WKAppBoundDomains
     15        entries and filters out non app-bound domains.
     16
     17        (API::HTTPCookieStore::cookies):
     18        (API::HTTPCookieStore::cookiesForURL):
     19        (API::HTTPCookieStore::setCookies):
     20        These functions were updated to set/return the cookies after they've
     21        been filtered through the WKAppBoundDomains.
     22
     23        * UIProcess/API/APIHTTPCookieStore.h:
     24        * UIProcess/API/Cocoa/WKWebsiteDataStore.mm:
     25        (-[WKWebsiteDataStore _appBoundDomains:]):
     26        * UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm:
     27        (WebKit::WebsiteDataStore::getAppBoundDomains const):
     28        (WebKit::WebsiteDataStore::appBoundDomainsForTesting const): Deleted.
     29        Utilize a function formerly used for testing only to be used in the
     30        HTTPCookieStore.
     31
     32        * UIProcess/WebsiteData/WebsiteDataStore.h:
     33
    1342020-04-03  Wenson Hsieh  <wenson_hsieh@apple.com>
    235
  • trunk/Source/WebKit/UIProcess/API/APIHTTPCookieStore.cpp

    r256315 r259520  
    3030#include "WebProcessPool.h"
    3131#include "WebsiteDataStore.h"
     32#include "WebsiteDataStoreParameters.h"
    3233#include <WebCore/Cookie.h>
    3334#include <WebCore/CookieStorage.h>
     
    3536#include <WebCore/NetworkStorageSession.h>
    3637
     38#if USE(APPLE_INTERNAL_SDK)
     39#include <WebKitAdditions/HTTPCookieStoreAdditions.h>
     40#else
     41#define IN_APP_BROWSER_PRIVACY_ENABLED false
     42#define IMPLEMENT_IN_APP_BROWSER_PRIVACY_ENABLED
     43#endif
     44
    3745using namespace WebKit;
    3846
     
    5361
    5462    unregisterForNewProcessPoolNotifications();
     63}
     64
     65void HTTPCookieStore::filterAppBoundCookies(const Vector<WebCore::Cookie>& cookies, CompletionHandler<void(Vector<WebCore::Cookie>&&)>&& completionHandler)
     66{
     67    Vector<WebCore::Cookie> appBoundCookies;
     68#if PLATFORM(IOS_FAMILY)
     69    m_owningDataStore->getAppBoundDomains([this, protectedThis = makeRef(*this), cookies, appBoundCookies = WTFMove(appBoundCookies), completionHandler = WTFMove(completionHandler)] (auto& domains) mutable {
     70        if (m_owningDataStore->parameters().networkSessionParameters.isInAppBrowserPrivacyEnabled || IN_APP_BROWSER_PRIVACY_ENABLED) {
     71            IMPLEMENT_IN_APP_BROWSER_PRIVACY_ENABLED
     72            for (auto& cookie : cookies) {
     73                if (domains.contains(WebCore::RegistrableDomain::uncheckedCreateFromHost(cookie.domain)))
     74                    appBoundCookies.append(cookie);
     75            }
     76        } else
     77            appBoundCookies = cookies;
     78        completionHandler(WTFMove(appBoundCookies));
     79    });
     80#else
     81    appBoundCookies = cookies;
     82    completionHandler(WTFMove(appBoundCookies));
     83#endif
    5584}
    5685
     
    6493        allCookies.appendVector(m_owningDataStore->pendingCookies());
    6594
    66         RunLoop::main().dispatch([completionHandler = WTFMove(completionHandler), allCookies] () mutable {
    67             completionHandler(allCookies);
     95        RunLoop::main().dispatch([this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler), allCookies] () mutable {
     96            filterAppBoundCookies(allCookies, WTFMove(completionHandler));
    6897        });
    6998        return;
     
    71100
    72101    auto* cookieManager = pool->supplement<WebKit::WebCookieManagerProxy>();
    73     cookieManager->getAllCookies(m_owningDataStore->sessionID(), [pool = WTFMove(pool), completionHandler = WTFMove(completionHandler)] (const Vector<WebCore::Cookie>& cookies) mutable {
    74         completionHandler(cookies);
     102    cookieManager->getAllCookies(m_owningDataStore->sessionID(), [this, protectedThis = makeRef(*this), pool = WTFMove(pool), completionHandler = WTFMove(completionHandler)] (const Vector<WebCore::Cookie>& cookies) mutable {
     103        filterAppBoundCookies(cookies, WTFMove(completionHandler));
    75104    });
    76105}
     
    83112
    84113    auto* cookieManager = pool->supplement<WebKit::WebCookieManagerProxy>();
    85     cookieManager->getCookies(m_owningDataStore->sessionID(), url, [completionHandler = WTFMove(completionHandler)] (Vector<WebCore::Cookie>&& cookies) mutable {
    86         completionHandler(WTFMove(cookies));
     114    cookieManager->getCookies(m_owningDataStore->sessionID(), url, [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)] (Vector<WebCore::Cookie>&& cookies) mutable {
     115        filterAppBoundCookies(cookies, WTFMove(completionHandler));
    87116    });
    88117}
     
    90119void HTTPCookieStore::setCookies(const Vector<WebCore::Cookie>& cookies, CompletionHandler<void()>&& completionHandler)
    91120{
    92     auto* pool = m_owningDataStore->processPoolForCookieStorageOperations();
    93     if (!pool) {
    94         for (auto& cookie : cookies) {
    95             // FIXME: pendingCookies used for defaultSession because session cookies cannot be propagated to Network Process with uiProcessCookieStorageIdentifier.
    96             if (m_owningDataStore->sessionID() == PAL::SessionID::defaultSessionID() && !cookie.session)
    97                 setCookieInDefaultUIProcessCookieStore(cookie);
    98             else
    99                 m_owningDataStore->addPendingCookie(cookie);
     121    filterAppBoundCookies(cookies, [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)] (auto&& appBoundCookies) mutable {
     122        auto* pool = m_owningDataStore->processPoolForCookieStorageOperations();
     123        if (!pool) {
     124            for (auto& cookie : appBoundCookies) {
     125                // FIXME: pendingCookies used for defaultSession because session cookies cannot be propagated to Network Process with uiProcessCookieStorageIdentifier.
     126                if (m_owningDataStore->sessionID() == PAL::SessionID::defaultSessionID() && !cookie.session)
     127                    setCookieInDefaultUIProcessCookieStore(cookie);
     128                else
     129                    m_owningDataStore->addPendingCookie(cookie);
     130            }
     131
     132            RunLoop::main().dispatch(WTFMove(completionHandler));
     133            return;
    100134        }
    101135
    102         RunLoop::main().dispatch(WTFMove(completionHandler));
    103         return;
    104     }
    105 
    106     auto* cookieManager = pool->supplement<WebKit::WebCookieManagerProxy>();
    107     cookieManager->setCookies(m_owningDataStore->sessionID(), cookies, [pool = WTFMove(pool), completionHandler = WTFMove(completionHandler)] () mutable {
    108         completionHandler();
     136        auto* cookieManager = pool->supplement<WebKit::WebCookieManagerProxy>();
     137        cookieManager->setCookies(m_owningDataStore->sessionID(), appBoundCookies, [pool = WTFMove(pool), completionHandler = WTFMove(completionHandler)] () mutable {
     138            completionHandler();
     139        });
    109140    });
    110141}
  • trunk/Source/WebKit/UIProcess/API/APIHTTPCookieStore.h

    r256315 r259520  
    7878    void cookieManagerDestroyed();
    7979
     80    void filterAppBoundCookies(const Vector<WebCore::Cookie>&, CompletionHandler<void(Vector<WebCore::Cookie>&&)>&&);
     81
    8082private:
    8183    HTTPCookieStore(WebKit::WebsiteDataStore&);
  • trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm

    r258914 r259520  
    614614- (void)_appBoundDomains:(void (^)(NSArray<NSString *> *))completionHandler
    615615{
    616     _websiteDataStore->appBoundDomainsForTesting([completionHandler = makeBlockPtr(completionHandler)](auto& domains) mutable {
     616    _websiteDataStore->getAppBoundDomains([completionHandler = makeBlockPtr(completionHandler)](auto& domains) mutable {
    617617        Vector<RefPtr<API::Object>> apiDomains;
    618618        apiDomains.reserveInitialCapacity(domains.size());
  • trunk/Source/WebKit/UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm

    r259516 r259520  
    467467}
    468468
    469 void WebsiteDataStore::appBoundDomainsForTesting(CompletionHandler<void(const HashSet<WebCore::RegistrableDomain>&)>&& completionHandler) const
    470 {
     469void WebsiteDataStore::getAppBoundDomains(CompletionHandler<void(const HashSet<WebCore::RegistrableDomain>&)>&& completionHandler) const
     470{
     471    ASSERT(RunLoop::isMain());
     472
    471473    ensureAppBoundDomains([completionHandler = WTFMove(completionHandler)] (auto& domains) mutable {
    472474        completionHandler(domains);
  • trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h

    r259323 r259520  
    288288
    289289    void beginAppBoundDomainCheck(const URL&, WebFramePolicyListenerProxy&);
    290     void appBoundDomainsForTesting(CompletionHandler<void(const HashSet<WebCore::RegistrableDomain>&)>&&) const;
     290    void getAppBoundDomains(CompletionHandler<void(const HashSet<WebCore::RegistrableDomain>&)>&&) const;
    291291    void ensureAppBoundDomains(CompletionHandler<void(const HashSet<WebCore::RegistrableDomain>&)>&&) const;
    292292    void reinitializeAppBoundDomains();
  • trunk/Tools/ChangeLog

    r259518 r259520  
     12020-04-03  Kate Cheney  <katherine_cheney@apple.com>
     2
     3        Prevent non app-bound domain cookies from being read or set using API calls
     4        https://bugs.webkit.org/show_bug.cgi?id=209926
     5        <rdar://problem/61071428>
     6
     7        Reviewed by Brady Eidson.
     8
     9        Added 3 new API tests to test that non app-bound cookies are not being
     10        set or returned via API calls. Also added a function to reset state
     11        between tests for internal debugging.
     12
     13        * TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm:
     14        (setUpCookieTest):
     15        (TEST):
     16
    1172020-04-03  Wenson Hsieh  <wenson_hsieh@apple.com>
    218
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm

    r259507 r259520  
    3232#import <WebCore/RegistrableDomain.h>
    3333#import <WebCore/RuntimeApplicationChecks.h>
     34#import <WebKit/WKHTTPCookieStorePrivate.h>
    3435#import <WebKit/WKPreferencesPrivate.h>
    3536#import <WebKit/WKUserContentControllerPrivate.h>
     
    7980@end
    8081
     82static void cleanUpInAppBrowserPrivacyTestSettings()
     83{
     84    IN_APP_BROWSER_PRIVACY_ADDITIONS_2
     85}
     86
    8187static void initializeInAppBrowserPrivacyTestSettings()
    8288{
     
    120126        EXPECT_EQ(NO, [result boolValue]);
    121127        EXPECT_FALSE(!!error);
     128        cleanUpInAppBrowserPrivacyTestSettings();
    122129        isDone = true;
    123130    }];
     
    161168        EXPECT_EQ(NO, [result boolValue]);
    162169        EXPECT_FALSE(!!error);
     170        cleanUpInAppBrowserPrivacyTestSettings();
    163171        isDone = true;
    164172    }];
     
    203211        EXPECT_FALSE(result);
    204212        EXPECT_TRUE(!!error);
     213        cleanUpInAppBrowserPrivacyTestSettings();
    205214        isDone = true;
    206215    }];
     
    246255        EXPECT_FALSE(result);
    247256        EXPECT_TRUE(!!error);
     257        cleanUpInAppBrowserPrivacyTestSettings();
    248258        isDone = true;
    249259    }];
     
    266276            EXPECT_WK_STREQ([sortedDomains objectAtIndex:i], [domainsToCompare objectAtIndex:i]);
    267277
     278        cleanUpInAppBrowserPrivacyTestSettings();
    268279        isDone = true;
    269280    }];
     
    285296    [webView _isNavigatingToAppBoundDomain:^(BOOL isAppBound) {
    286297        EXPECT_TRUE(isAppBound);
     298        cleanUpInAppBrowserPrivacyTestSettings();
    287299        isDone = true;
    288300    }];
     
    303315    [webView _isNavigatingToAppBoundDomain:^(BOOL isAppBound) {
    304316        EXPECT_TRUE(isAppBound);
     317        cleanUpInAppBrowserPrivacyTestSettings();
    305318        isDone = true;
    306319    }];
     
    321334    [webView _isNavigatingToAppBoundDomain:^(BOOL isAppBound) {
    322335        EXPECT_TRUE(isAppBound);
     336        cleanUpInAppBrowserPrivacyTestSettings();
    323337        isDone = true;
    324338    }];
     
    365379
    366380    expectScriptEvaluatesToColor(webView.get(), backgroundColorScript, redInRGB);
     381    cleanUpInAppBrowserPrivacyTestSettings();
    367382}
    368383
     
    386401
    387402    expectScriptEvaluatesToColor(webView.get(), backgroundColorScript, redInRGB);
     403    cleanUpInAppBrowserPrivacyTestSettings();
    388404}
    389405
     
    411427    // The subframe should also be affected.
    412428    expectScriptEvaluatesToColor(webView.get(), frameBackgroundColorScript, redInRGB);
     429    cleanUpInAppBrowserPrivacyTestSettings();
    413430}
    414431
     
    437454    // check without needing a message handler.
    438455    expectScriptEvaluatesToColor(webView.get(), backgroundColorScript, redInRGB);
     456    cleanUpInAppBrowserPrivacyTestSettings();
    439457}
    440458
     
    475493    // check without needing a message handler.
    476494    expectScriptEvaluatesToColor(webView.get(), backgroundColorScript, redInRGB);
     495    cleanUpInAppBrowserPrivacyTestSettings();
     496}
     497
     498static RetainPtr<WKHTTPCookieStore> globalCookieStore;
     499static bool gotFlag = false;
     500
     501static void setUpCookieTest()
     502{
     503    globalCookieStore = [[WKWebsiteDataStore defaultDataStore] httpCookieStore];
     504    NSArray<NSHTTPCookie *> *cookies = nil;
     505    [globalCookieStore getAllCookies:[cookiesPtr = &cookies](NSArray<NSHTTPCookie *> *nsCookies) {
     506        *cookiesPtr = [nsCookies retain];
     507        gotFlag = true;
     508    }];
     509
     510    TestWebKitAPI::Util::run(&gotFlag);
     511
     512    for (id cookie in cookies) {
     513        gotFlag = false;
     514        [globalCookieStore deleteCookie:cookie completionHandler:[]() {
     515            gotFlag = true;
     516        }];
     517        TestWebKitAPI::Util::run(&gotFlag);
     518    }
     519
     520    cookies = nil;
     521    gotFlag = false;
     522    [globalCookieStore getAllCookies:[cookiesPtr = &cookies](NSArray<NSHTTPCookie *> *nsCookies) {
     523        *cookiesPtr = [nsCookies retain];
     524        gotFlag = true;
     525    }];
     526
     527    TestWebKitAPI::Util::run(&gotFlag);
     528
     529    // Make sure the cookie store starts out empty.
     530    ASSERT_EQ(cookies.count, 0u);
     531    [cookies release];
     532
     533    gotFlag = false;
     534}
     535
     536TEST(InAppBrowserPrivacy, SetCookieForNonAppBoundDomainFails)
     537{
     538    initializeInAppBrowserPrivacyTestSettings();
     539    [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"WebKitDebugIsInAppBrowserPrivacyEnabled"];
     540
     541    auto dataStore = [WKWebsiteDataStore defaultDataStore];
     542    auto webView = adoptNS([TestWKWebView new]);
     543    [webView loadHTMLString:@"Oh hello" baseURL:[NSURL URLWithString:@"http://webkit.org"]];
     544    [webView _test_waitForDidFinishNavigation];
     545
     546    setUpCookieTest();
     547    globalCookieStore = [dataStore httpCookieStore];
     548
     549    NSArray<NSHTTPCookie *> *cookies = nil;
     550
     551    // Non app-bound cookie.
     552    RetainPtr<NSHTTPCookie> nonAppBoundCookie = [NSHTTPCookie cookieWithProperties:@{
     553        NSHTTPCookiePath: @"/",
     554        NSHTTPCookieName: @"nonAppBoundName",
     555        NSHTTPCookieValue: @"nonAppBoundValue",
     556        NSHTTPCookieDomain: @"nonAppBoundDomain.com",
     557    }];
     558
     559    // App-bound cookie.
     560    RetainPtr<NSHTTPCookie> appBoundCookie = [NSHTTPCookie cookieWithProperties:@{
     561        NSHTTPCookiePath: @"/",
     562        NSHTTPCookieName: @"webKitName",
     563        NSHTTPCookieValue: @"webKitValue",
     564        NSHTTPCookieDomain: @"www.webkit.org",
     565    }];
     566
     567    gotFlag = false;
     568    // This should not actually set a cookie.
     569    [globalCookieStore setCookie:nonAppBoundCookie.get() completionHandler:[]() {
     570        gotFlag = true;
     571    }];
     572
     573    TestWebKitAPI::Util::run(&gotFlag);
     574    gotFlag = false;
     575
     576    // This should successfully set a cookie.
     577    [globalCookieStore setCookie:appBoundCookie.get() completionHandler:[]() {
     578        gotFlag = true;
     579    }];
     580
     581    TestWebKitAPI::Util::run(&gotFlag);
     582
     583    cleanUpInAppBrowserPrivacyTestSettings();
     584    [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"WebKitDebugIsInAppBrowserPrivacyEnabled"];
     585    gotFlag = false;
     586
     587    // Check the cookie store to make sure only one cookie was set.
     588    [globalCookieStore getAllCookies:[cookiesPtr = &cookies](NSArray<NSHTTPCookie *> *nsCookies) {
     589        *cookiesPtr = [nsCookies retain];
     590        gotFlag = true;
     591    }];
     592
     593    TestWebKitAPI::Util::run(&gotFlag);
     594
     595    ASSERT_EQ(cookies.count, 1u);
     596
     597    [cookies release];
     598    gotFlag = false;
     599    [globalCookieStore deleteCookie:appBoundCookie.get() completionHandler:[]() {
     600        gotFlag = true;
     601    }];
     602
     603    TestWebKitAPI::Util::run(&gotFlag);
     604}
     605
     606TEST(InAppBrowserPrivacy, GetCookieForNonAppBoundDomainFails)
     607{
     608    // Since we can't set non-app-bound cookies with In-App Browser privacy protections on,
     609    // we can turn the protections off to set a cookie we will then try to get with protections enabled.
     610    [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"WebKitDebugIsInAppBrowserPrivacyEnabled"];
     611
     612    setUpCookieTest();
     613    globalCookieStore = [[WKWebsiteDataStore defaultDataStore] httpCookieStore];
     614    NSArray<NSHTTPCookie *> *cookies = nil;
     615
     616    // Non app-bound cookie.
     617    RetainPtr<NSHTTPCookie> nonAppBoundCookie = [NSHTTPCookie cookieWithProperties:@{
     618        NSHTTPCookiePath: @"/",
     619        NSHTTPCookieName: @"CookieName",
     620        NSHTTPCookieValue: @"CookieValue",
     621        NSHTTPCookieDomain: @"nonAppBoundDomain.com",
     622    }];
     623
     624    // App-bound cookie.
     625    RetainPtr<NSHTTPCookie> appBoundCookie = [NSHTTPCookie cookieWithProperties:@{
     626        NSHTTPCookiePath: @"/",
     627        NSHTTPCookieName: @"OtherCookieName",
     628        NSHTTPCookieValue: @"OtherCookieValue",
     629        NSHTTPCookieDomain: @"www.webkit.org",
     630    }];
     631
     632    auto webView = adoptNS([TestWKWebView new]);
     633    [webView synchronouslyLoadHTMLString:@"start network process"];
     634
     635    // This should successfully set a cookie because protections are off.
     636    [globalCookieStore setCookie:nonAppBoundCookie.get() completionHandler:[]() {
     637        gotFlag = true;
     638    }];
     639
     640    TestWebKitAPI::Util::run(&gotFlag);
     641    gotFlag = false;
     642
     643    [globalCookieStore setCookie:appBoundCookie.get() completionHandler:[]() {
     644        gotFlag = true;
     645    }];
     646
     647    TestWebKitAPI::Util::run(&gotFlag);
     648
     649    gotFlag = false;
     650    [globalCookieStore getAllCookies:[cookiesPtr = &cookies](NSArray<NSHTTPCookie *> *nsCookies) {
     651        *cookiesPtr = [nsCookies retain];
     652        gotFlag = true;
     653    }];
     654
     655    TestWebKitAPI::Util::run(&gotFlag);
     656
     657    // Confirm both cookies are in the store.
     658    ASSERT_EQ(cookies.count, 2u);
     659
     660    // Now enable protections and ensure we can only retrieve the app-bound cookies.
     661    [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"WebKitDebugIsInAppBrowserPrivacyEnabled"];
     662    initializeInAppBrowserPrivacyTestSettings();
     663
     664    gotFlag = false;
     665    [globalCookieStore getAllCookies:[cookiesPtr = &cookies](NSArray<NSHTTPCookie *> *nsCookies) {
     666        *cookiesPtr = [nsCookies retain];
     667        gotFlag = true;
     668    }];
     669
     670    TestWebKitAPI::Util::run(&gotFlag);
     671
     672    ASSERT_EQ(cookies.count, 1u);
     673
     674    [cookies release];
     675
     676    gotFlag = false;
     677    [globalCookieStore deleteCookie:nonAppBoundCookie.get() completionHandler:[]() {
     678        gotFlag = true;
     679    }];
     680
     681    TestWebKitAPI::Util::run(&gotFlag);
     682
     683    gotFlag = false;
     684    [globalCookieStore deleteCookie:appBoundCookie.get() completionHandler:[]() {
     685        // Reset flag.
     686        [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"WebKitDebugIsInAppBrowserPrivacyEnabled"];
     687        cleanUpInAppBrowserPrivacyTestSettings();
     688        gotFlag = true;
     689    }];
     690
     691    TestWebKitAPI::Util::run(&gotFlag);
     692}
     693
     694TEST(InAppBrowserPrivacy, GetCookieForURLFails)
     695{
     696    // Since we can't set non-app-bound cookies with In-App Browser privacy protections on,
     697    // we can turn the protections off to set a cookie we will then try to get with protections enabled.
     698    [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"WebKitDebugIsInAppBrowserPrivacyEnabled"];
     699    setUpCookieTest();
     700
     701    globalCookieStore = [[WKWebsiteDataStore defaultDataStore] httpCookieStore];
     702    NSHTTPCookie *nonAppBoundCookie = [NSHTTPCookie cookieWithProperties:@{
     703        NSHTTPCookiePath: @"/",
     704        NSHTTPCookieName: @"nonAppBoundName",
     705        NSHTTPCookieValue: @"nonAppBoundValue",
     706        NSHTTPCookieDomain: @"nonAppBoundDomain.com",
     707    }];
     708   
     709    NSHTTPCookie *appBoundCookie = [NSHTTPCookie cookieWithProperties:@{
     710        NSHTTPCookiePath: @"/",
     711        NSHTTPCookieName: @"webKitName",
     712        NSHTTPCookieValue: @"webKitValue",
     713        NSHTTPCookieDomain: @"webkit.org",
     714    }];
     715
     716    __block bool done = false;
     717    auto webView = adoptNS([TestWKWebView new]);
     718    [webView synchronouslyLoadHTMLString:@"start network process"];
     719    [globalCookieStore setCookie:nonAppBoundCookie completionHandler:^{
     720        [globalCookieStore setCookie:appBoundCookie completionHandler:^{
     721
     722            // Now enable protections and ensure we can only retrieve the app-bound cookies.
     723            [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"WebKitDebugIsInAppBrowserPrivacyEnabled"];
     724            initializeInAppBrowserPrivacyTestSettings();
     725
     726            [globalCookieStore _getCookiesForURL:[NSURL URLWithString:@"https://webkit.org/"] completionHandler:^(NSArray<NSHTTPCookie *> *cookies) {
     727                EXPECT_EQ(cookies.count, 1ull);
     728                EXPECT_WK_STREQ(cookies[0].name, "webKitName");
     729                [globalCookieStore _getCookiesForURL:[NSURL URLWithString:@"https://nonAppBoundDomain.com/"] completionHandler:^(NSArray<NSHTTPCookie *> *cookies) {
     730                    EXPECT_EQ(cookies.count, 0u);
     731                    [globalCookieStore deleteCookie:nonAppBoundCookie completionHandler:^{
     732                        [globalCookieStore deleteCookie:appBoundCookie completionHandler:^{
     733                            [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"WebKitDebugIsInAppBrowserPrivacyEnabled"];
     734                            cleanUpInAppBrowserPrivacyTestSettings();
     735                            done = true;
     736                        }];
     737                    }];
     738                }];
     739            }];
     740        }];
     741    }];
     742    TestWebKitAPI::Util::run(&done);
    477743}
    478744
Note: See TracChangeset for help on using the changeset viewer.