Changeset 265389 in webkit


Ignore:
Timestamp:
Aug 7, 2020 1:40:32 PM (4 years ago)
Author:
wilander@apple.com
Message:

Experimental: Cap the expiry of persistent cookies set in 3rd-party CNAME cloaked HTTP responses
https://bugs.webkit.org/show_bug.cgi?id=215201
<rdar://problem/57454633>

Reviewed by Brent Fulgham. Also reviewed and commented on by Chris Dumez, Jiten Mehta, Sam Weinig, and Alex Christensen.

Source/WebCore:

Tests: http/tests/resourceLoadStatistics/cname-cloaking-top-cname-sub-1p-cname.html

http/tests/resourceLoadStatistics/cname-cloaking-top-cname-sub-3p-cname.html
http/tests/resourceLoadStatistics/cname-cloaking-top-cname-sub-matching-cname.html
http/tests/resourceLoadStatistics/cname-cloaking-top-cname-sub-no-cname.html
http/tests/resourceLoadStatistics/cname-cloaking-top-no-cname-sub-1p-cname.html
http/tests/resourceLoadStatistics/cname-cloaking-top-no-cname-sub-3p-cname.html
http/tests/resourceLoadStatistics/cname-cloaking-top-no-cname-sub-no-cname.html

  • page/Settings.yaml:

Added the off-by-default flag isCNAMECloakingMitigationEnabled.

  • platform/network/NetworkStorageSession.cpp:

(WebCore::NetworkStorageSession::resourceLoadStatisticsEnabled const):

New getter for the ITP setting.

  • platform/network/NetworkStorageSession.h:
  • platform/network/cocoa/NetworkStorageSessionCocoa.mm:

(WebCore::NetworkStorageSession::capExpiryOfPersistentCookie):

Broke this function out so that it can be reused.

(WebCore::parseDOMCookie):

Here's from where the function above was broken out.
The existing functionality has a test case.

Source/WebCore/PAL:

  • pal/spi/cf/CFNetworkSPI.h:

This change declares two new properties on NSURLSessionTask:

  • _cookieTransformCallback
  • _resolvedCNAMEChain

Source/WebKit:

This experimental feature is off by default.

CNAME cloaking means a host resolves to a a different domain, potentially a
third-party domain, as part of DNS resolution.

This patch makes WebKit::NetworkDataTaskCocoa capture any CNAME cloaking for
the first party host and stores it in a table in the WebKit::NetworkSession.
It then checks first party subresource loads to see if they resolve to a
different domain and if so, compare that domain to both the first party
domain and its CNAME cloaking domain, if there is one. If there's a
mismatch, it's deemed a case of third-party CNAME cloaking and any cookies
set in the response of the cloaked subresource load will have their expiry
capped to 7 days.

The cases for capping expiry look like this (and are backed by test cases):

First-party host | First-party subdomain | Capped expiry


No CNAME cloaking | No CNAME cloaking | No
No CNAME cloaking | First-party CNAME cloaking | No
No CNAME cloaking | Third-party CNAME cloaking | Yes
CNAME cloaking | No CNAME cloaking | No
CNAME cloaking | Matching CNAME cloaking | No
CNAME cloaking | First-party CNAME cloaking | No
CNAME cloaking | Third-party CNAME cloaking | Yes

This patch makes use of two new CFNetwork SPIs on NSURLSessionTask:

  • _cookieTransformCallback
  • _resolvedCNAMEChain
  • NetworkProcess/NetworkProcess.cpp:

(WebKit::NetworkProcess::resetParametersToDefaultValues):

This reset now covers the new CNAME cloaking member variables.

(WebKit::NetworkProcess::setIsRunningResourceLoadStatisticsTest):

This function now also enables the CNAME cloaking code.

(WebKit::NetworkProcess::setFirstPartyHostCNAMEDomainForTesting):
(WebKit::NetworkProcess::setThirdPartyCNAMEDomainForTesting):

  • NetworkProcess/NetworkProcess.h:
  • NetworkProcess/NetworkProcess.messages.in:

New IPC to forward test configuration.

  • NetworkProcess/NetworkSession.cpp:

(WebKit::NetworkSession::NetworkSession):

Now picks up the flag for this feature.

(WebKit::NetworkSession::setFirstPartyHostCNAMEDomain):

This is called from NetworkDataTaskCocoa::updateFirstPartyInfoForTaskAndSession()
when there is CNAME cloaking for the first party host. This is done to make it
possible to not cap the expiry of cookies if subsequent subresource loads have
CNAME cloaking that matches the first-party host's CNAME cloaking. This happens
when whole websites are hosted on edge networks.
This function is also used by the test infrastructure to mock the DNS resolution
for a first-party host.

(WebKit::NetworkSession::firstPartyHostCNAMEDomain):

This returns any captured CNAME cloaking for a host, if there is one.

(WebKit::NetworkSession::resetCNAMEDomainData):

  • NetworkProcess/NetworkSession.h:

(WebKit::NetworkSession::setCNAMECloakingMitigationEnabled):
(WebKit::NetworkSession::cnameCloakingMitigationEnabled const):
(WebKit::NetworkSession::setThirdPartyCNAMEDomainForTesting):

This test functions allows us to mock the DNS resolution for a subresource.

(WebKit::NetworkSession::thirdPartyCNAMEDomainForTesting const):

  • NetworkProcess/cocoa/NetworkDataTaskCocoa.h:
  • NetworkProcess/cocoa/NetworkDataTaskCocoa.mm:

(WebKit::hasCNAMEAndCookieTransformSPI):
(WebKit::lastCNAMEDomain):
(WebKit::NetworkDataTaskCocoa::updateFirstPartyInfoForSession):

This is called by NetworkDataTaskCocoa::didReceiveResponse() to capture any
CNAME cloaking for the first-party host.

(WebKit::NetworkDataTaskCocoa::applyCookiePolicyForThirdPartyCNAMECloaking):

This is called in the NetworkDataTaskCocoa constructor and in
NetworkDataTaskCocoa::willPerformHTTPRedirection() and sets the new
_cookieTransformCallback SPI property on the task which will check the
response for any third-party CNAME cloaking and cap the expiry of incoming
cookies accordingly.

(WebKit::NetworkDataTaskCocoa::NetworkDataTaskCocoa):

This now calls
NetworkDataTaskCocoa::applyCookiePolicyForThirdPartyCNAMECloaking().

(WebKit::NetworkDataTaskCocoa::didReceiveResponse):

This now calls
NetworkDataTaskCocoa::updateFirstPartyInfoForTaskAndSession().

(WebKit::NetworkDataTaskCocoa::willPerformHTTPRedirection):

This now calls
NetworkDataTaskCocoa::applyCookiePolicyForThirdPartyCNAMECloaking().

  • Shared/ResourceLoadStatisticsParameters.h:

Now holds a WebCore::CNAMECloakingMitigationEnabled flag.

(WebKit::ResourceLoadStatisticsParameters::encode const):
(WebKit::ResourceLoadStatisticsParameters::decode):

  • Shared/WebPreferences.yaml:
  • UIProcess/API/C/WKWebsiteDataStoreRef.cpp:

(WKWebsiteDataStoreSetResourceLoadStatisticsFirstPartyHostCNAMEDomainForTesting):

Used to mock CNAME resolution data.

(WKWebsiteDataStoreSetResourceLoadStatisticsThirdPartyCNAMEDomainForTesting):

Used to mock CNAME resolution data.

  • UIProcess/API/C/WKWebsiteDataStoreRef.h:
  • UIProcess/Network/NetworkProcessProxy.cpp:

(WebKit::NetworkProcessProxy::setFirstPartyHostCNAMEDomainForTesting):
(WebKit::NetworkProcessProxy::setThirdPartyCNAMEDomainForTesting):

  • UIProcess/Network/NetworkProcessProxy.h:
  • UIProcess/WebProcessPool.cpp:

(WebKit::WebProcessPool::ensureNetworkProcess):

Now handles the WebCore::CNAMECloakingMitigationEnabled flag.

  • UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm:

(WebKit::WebsiteDataStore::platformSetNetworkParameters):

Now handles the WebCore::CNAMECloakingMitigationEnabled flag.

  • UIProcess/WebsiteData/WebsiteDataStore.cpp:

(WebKit::WebsiteDataStore::setResourceLoadStatisticsFirstPartyHostCNAMEDomainForTesting):
(WebKit::WebsiteDataStore::setResourceLoadStatisticsThirdPartyCNAMEDomainForTesting):
(WebKit::WebsiteDataStore::parameters):

  • UIProcess/WebsiteData/WebsiteDataStore.h:

Source/WTF:

This change defines HAVE_CFNETWORK_CNAME_AND_COOKIE_TRANSFORM_SPI.

  • wtf/PlatformHave.h:

Tools:

This patch adds two TestRunner functions which allows for testing
with data that would otherwise come from DNS resolution:

  • statisticsSetFirstPartyHostCNAMEDomain()
  • statisticsSetThirdPartyCNAMEDomain()
  • WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
  • WebKitTestRunner/InjectedBundle/InjectedBundle.cpp:

(WTR::InjectedBundle::didReceiveMessageToPage):

  • WebKitTestRunner/InjectedBundle/TestRunner.cpp:

(WTR::TestRunner::statisticsSetFirstPartyHostCNAMEDomain):
(WTR::TestRunner::statisticsCallDidSetFirstPartyHostCNAMEDomainCallback):
(WTR::TestRunner::statisticsSetThirdPartyCNAMEDomain):
(WTR::TestRunner::statisticsCallDidSetThirdPartyCNAMEDomainCallback):

  • WebKitTestRunner/InjectedBundle/TestRunner.h:
  • WebKitTestRunner/TestController.cpp:

(WTR::TestController::setStatisticsFirstPartyHostCNAMEDomain):
(WTR::TestController::setStatisticsThirdPartyCNAMEDomain):

  • WebKitTestRunner/TestController.h:
  • WebKitTestRunner/TestInvocation.cpp:

(WTR::TestInvocation::didReceiveMessageFromInjectedBundle):
(WTR::TestInvocation::didSetFirstPartyHostCNAMEDomain):
(WTR::TestInvocation::didSetThirdPartyCNAMEDomain):

  • WebKitTestRunner/TestInvocation.h:

LayoutTests:

  • http/tests/resourceLoadStatistics/cname-cloaking-top-cname-sub-1p-cname-expected.txt: Added.
  • http/tests/resourceLoadStatistics/cname-cloaking-top-cname-sub-1p-cname.html: Added.
  • http/tests/resourceLoadStatistics/cname-cloaking-top-cname-sub-3p-cname-expected.txt: Added.
  • http/tests/resourceLoadStatistics/cname-cloaking-top-cname-sub-3p-cname.html: Added.
  • http/tests/resourceLoadStatistics/cname-cloaking-top-cname-sub-matching-cname-expected.txt: Added.
  • http/tests/resourceLoadStatistics/cname-cloaking-top-cname-sub-matching-cname.html: Added.
  • http/tests/resourceLoadStatistics/cname-cloaking-top-cname-sub-no-cname-expected.txt: Added.
  • http/tests/resourceLoadStatistics/cname-cloaking-top-cname-sub-no-cname.html: Added.
  • http/tests/resourceLoadStatistics/cname-cloaking-top-no-cname-sub-1p-cname-expected.txt: Added.
  • http/tests/resourceLoadStatistics/cname-cloaking-top-no-cname-sub-1p-cname.html: Added.
  • http/tests/resourceLoadStatistics/cname-cloaking-top-no-cname-sub-3p-cname-expected.txt: Added.
  • http/tests/resourceLoadStatistics/cname-cloaking-top-no-cname-sub-3p-cname.html: Added.
  • http/tests/resourceLoadStatistics/cname-cloaking-top-no-cname-sub-no-cname-expected.txt: Added.
  • http/tests/resourceLoadStatistics/cname-cloaking-top-no-cname-sub-no-cname.html: Added.
  • platform/ios-13/TestExpectations:

New tests marked as [ Skip ].

  • platform/ios-wk2/TestExpectations:

New tests marked as [ Pass ] in general.

  • platform/mac-wk2/TestExpectations:

New tests marked as [ Pass ] for BigSur+.

  • platform/wk2/TestExpectations:

New tests marked as [ Skip ] in general.

Location:
trunk
Files:
14 added
41 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r265388 r265389  
     12020-08-07  John Wilander  <wilander@apple.com>
     2
     3        Experimental: Cap the expiry of persistent cookies set in 3rd-party CNAME cloaked HTTP responses
     4        https://bugs.webkit.org/show_bug.cgi?id=215201
     5        <rdar://problem/57454633>
     6
     7        Reviewed by Brent Fulgham. Also reviewed and commented on by Chris Dumez, Jiten Mehta, Sam Weinig, and Alex Christensen.
     8
     9        * http/tests/resourceLoadStatistics/cname-cloaking-top-cname-sub-1p-cname-expected.txt: Added.
     10        * http/tests/resourceLoadStatistics/cname-cloaking-top-cname-sub-1p-cname.html: Added.
     11        * http/tests/resourceLoadStatistics/cname-cloaking-top-cname-sub-3p-cname-expected.txt: Added.
     12        * http/tests/resourceLoadStatistics/cname-cloaking-top-cname-sub-3p-cname.html: Added.
     13        * http/tests/resourceLoadStatistics/cname-cloaking-top-cname-sub-matching-cname-expected.txt: Added.
     14        * http/tests/resourceLoadStatistics/cname-cloaking-top-cname-sub-matching-cname.html: Added.
     15        * http/tests/resourceLoadStatistics/cname-cloaking-top-cname-sub-no-cname-expected.txt: Added.
     16        * http/tests/resourceLoadStatistics/cname-cloaking-top-cname-sub-no-cname.html: Added.
     17        * http/tests/resourceLoadStatistics/cname-cloaking-top-no-cname-sub-1p-cname-expected.txt: Added.
     18        * http/tests/resourceLoadStatistics/cname-cloaking-top-no-cname-sub-1p-cname.html: Added.
     19        * http/tests/resourceLoadStatistics/cname-cloaking-top-no-cname-sub-3p-cname-expected.txt: Added.
     20        * http/tests/resourceLoadStatistics/cname-cloaking-top-no-cname-sub-3p-cname.html: Added.
     21        * http/tests/resourceLoadStatistics/cname-cloaking-top-no-cname-sub-no-cname-expected.txt: Added.
     22        * http/tests/resourceLoadStatistics/cname-cloaking-top-no-cname-sub-no-cname.html: Added.
     23        * platform/ios-13/TestExpectations:
     24            New tests marked as [ Skip ].
     25        * platform/ios-wk2/TestExpectations:
     26            New tests marked as [ Pass ] in general.
     27        * platform/mac-wk2/TestExpectations:
     28            New tests marked as [ Pass ] for BigSur+.
     29        * platform/wk2/TestExpectations:
     30            New tests marked as [ Skip ] in general.
     31
    1322020-08-07  Chris Dumez  <cdumez@apple.com>
    233
  • trunk/LayoutTests/platform/ios-13/TestExpectations

    r264950 r265389  
    22webkit.org/b/209692 platform/ios/fast/text/text-security-disc-bullet-pua-ios-new.html [ ImageOnlyFailure ]
    33webkit.org/b/209692 fast/text/text-security-disc-bullet-pua.html [ ImageOnlyFailure ]
     4
     5# The CNAME and cookie transform SPIs are only available in iOS 14 and above.
     6http/tests/resourceLoadStatistics/cname-cloaking-top-cname-sub-1p-cname.html [ Skip ]
     7http/tests/resourceLoadStatistics/cname-cloaking-top-cname-sub-3p-cname.html [ Skip ]
     8http/tests/resourceLoadStatistics/cname-cloaking-top-cname-sub-matching-cname.html [ Skip ]
     9http/tests/resourceLoadStatistics/cname-cloaking-top-cname-sub-no-cname.html [ Skip ]
     10http/tests/resourceLoadStatistics/cname-cloaking-top-no-cname-sub-1p-cname.html [ Skip ]
     11http/tests/resourceLoadStatistics/cname-cloaking-top-no-cname-sub-3p-cname.html [ Skip ]
     12http/tests/resourceLoadStatistics/cname-cloaking-top-no-cname-sub-no-cname.html [ Skip ]
  • trunk/LayoutTests/platform/ios-wk2/TestExpectations

    r265385 r265389  
    8282http/tests/resourceLoadStatistics/strip-referrer-to-origin-for-third-party-redirects.html [ Pass ]
    8383http/tests/resourceLoadStatistics/strip-referrer-to-origin-for-third-party-requests.html [ Pass ]
     84
     85# The CNAME and cookie transform SPIs are only available in iOS 14 and above.
     86http/tests/resourceLoadStatistics/cname-cloaking-top-cname-sub-1p-cname.html [ Pass ]
     87http/tests/resourceLoadStatistics/cname-cloaking-top-cname-sub-3p-cname.html [ Pass ]
     88http/tests/resourceLoadStatistics/cname-cloaking-top-cname-sub-matching-cname.html [ Pass ]
     89http/tests/resourceLoadStatistics/cname-cloaking-top-cname-sub-no-cname.html [ Pass ]
     90http/tests/resourceLoadStatistics/cname-cloaking-top-no-cname-sub-1p-cname.html [ Pass ]
     91http/tests/resourceLoadStatistics/cname-cloaking-top-no-cname-sub-3p-cname.html [ Pass ]
     92http/tests/resourceLoadStatistics/cname-cloaking-top-no-cname-sub-no-cname.html [ Pass ]
    8493
    8594#//////////////////////////////////////////////////////////////////////////////////////////
  • trunk/LayoutTests/platform/mac-wk2/TestExpectations

    r265351 r265389  
    714714[ Catalina+ ] http/tests/resourceLoadStatistics/enforce-samesite-strict-based-on-top-frame-unique-redirects-to-database.html [ Pass ]
    715715
     716# The CNAME and cookie transform SPIs are only available in macOS Big Sur and above.
     717[ BigSur+ ] http/tests/resourceLoadStatistics/cname-cloaking-top-cname-sub-1p-cname.html [ Pass ]
     718[ BigSur+ ] http/tests/resourceLoadStatistics/cname-cloaking-top-cname-sub-3p-cname.html [ Pass ]
     719[ BigSur+ ] http/tests/resourceLoadStatistics/cname-cloaking-top-cname-sub-matching-cname.html [ Pass ]
     720[ BigSur+ ] http/tests/resourceLoadStatistics/cname-cloaking-top-cname-sub-no-cname.html [ Pass ]
     721[ BigSur+ ] http/tests/resourceLoadStatistics/cname-cloaking-top-no-cname-sub-1p-cname.html [ Pass ]
     722[ BigSur+ ] http/tests/resourceLoadStatistics/cname-cloaking-top-no-cname-sub-3p-cname.html [ Pass ]
     723[ BigSur+ ] http/tests/resourceLoadStatistics/cname-cloaking-top-no-cname-sub-no-cname.html [ Pass ]
     724
    716725# Skipped in general expectations since they only work on iOS and Mac, WK2.
    717726media/deactivate-audio-session.html [ Pass ]
  • trunk/LayoutTests/platform/wk2/TestExpectations

    r265169 r265389  
    731731http/tests/resourceLoadStatistics/enforce-samesite-strict-based-on-top-frame-unique-redirects-to-database.html [ Skip ]
    732732
     733# The CNAME and cookie transform SPIs are only available in macOS Big Sur + iOS 14 and above.
     734http/tests/resourceLoadStatistics/cname-cloaking-top-cname-sub-1p-cname.html [ Skip ]
     735http/tests/resourceLoadStatistics/cname-cloaking-top-cname-sub-3p-cname.html [ Skip ]
     736http/tests/resourceLoadStatistics/cname-cloaking-top-cname-sub-matching-cname.html [ Skip ]
     737http/tests/resourceLoadStatistics/cname-cloaking-top-cname-sub-no-cname.html [ Skip ]
     738http/tests/resourceLoadStatistics/cname-cloaking-top-no-cname-sub-1p-cname.html [ Skip ]
     739http/tests/resourceLoadStatistics/cname-cloaking-top-no-cname-sub-3p-cname.html [ Skip ]
     740http/tests/resourceLoadStatistics/cname-cloaking-top-no-cname-sub-no-cname.html [ Skip ]
     741
    733742http/tests/websocket/connection-refusal-in-frame-resource-load-statistics.html [ Pass ]
    734743# These are only supported behind a compile time flag in macOS High Sierra + iOS 11, and above.
  • trunk/Source/WTF/ChangeLog

    r265383 r265389  
     12020-08-07  John Wilander  <wilander@apple.com>
     2
     3        Experimental: Cap the expiry of persistent cookies set in 3rd-party CNAME cloaked HTTP responses
     4        https://bugs.webkit.org/show_bug.cgi?id=215201
     5        <rdar://problem/57454633>
     6
     7        Reviewed by Brent Fulgham. Also reviewed and commented on by Chris Dumez, Jiten Mehta, Sam Weinig, and Alex Christensen.
     8
     9        This change defines HAVE_CFNETWORK_CNAME_AND_COOKIE_TRANSFORM_SPI.
     10
     11        * wtf/PlatformHave.h:
     12
    1132020-08-07  Saam Barati  <sbarati@apple.com>
    214
  • trunk/Source/WTF/wtf/PlatformHave.h

    r265315 r265389  
    708708#define HAVE_NSTABLEVIEWSTYLE 1
    709709#endif
     710
     711#if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 110000) \
     712    || ((PLATFORM(IOS) || PLATFORM(MACCATALYST)) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 140000) \
     713    || (PLATFORM(WATCHOS) && __WATCH_OS_VERSION_MIN_REQUIRED >= 70000) \
     714    || (PLATFORM(APPLETV) && __TV_OS_VERSION_MIN_REQUIRED >= 140000)
     715#define HAVE_CFNETWORK_CNAME_AND_COOKIE_TRANSFORM_SPI 1
     716#endif
  • trunk/Source/WebCore/ChangeLog

    r265388 r265389  
     12020-08-07  John Wilander  <wilander@apple.com>
     2
     3        Experimental: Cap the expiry of persistent cookies set in 3rd-party CNAME cloaked HTTP responses
     4        https://bugs.webkit.org/show_bug.cgi?id=215201
     5        <rdar://problem/57454633>
     6
     7        Reviewed by Brent Fulgham. Also reviewed and commented on by Chris Dumez, Jiten Mehta, Sam Weinig, and Alex Christensen.
     8
     9        Tests: http/tests/resourceLoadStatistics/cname-cloaking-top-cname-sub-1p-cname.html
     10               http/tests/resourceLoadStatistics/cname-cloaking-top-cname-sub-3p-cname.html
     11               http/tests/resourceLoadStatistics/cname-cloaking-top-cname-sub-matching-cname.html
     12               http/tests/resourceLoadStatistics/cname-cloaking-top-cname-sub-no-cname.html
     13               http/tests/resourceLoadStatistics/cname-cloaking-top-no-cname-sub-1p-cname.html
     14               http/tests/resourceLoadStatistics/cname-cloaking-top-no-cname-sub-3p-cname.html
     15               http/tests/resourceLoadStatistics/cname-cloaking-top-no-cname-sub-no-cname.html
     16
     17        * page/Settings.yaml:
     18            Added the off-by-default flag isCNAMECloakingMitigationEnabled.
     19        * platform/network/NetworkStorageSession.cpp:
     20        (WebCore::NetworkStorageSession::resourceLoadStatisticsEnabled const):
     21            New getter for the ITP setting.
     22        * platform/network/NetworkStorageSession.h:
     23        * platform/network/cocoa/NetworkStorageSessionCocoa.mm:
     24        (WebCore::NetworkStorageSession::capExpiryOfPersistentCookie):
     25            Broke this function out so that it can be reused.
     26        (WebCore::parseDOMCookie):
     27            Here's from where the function above was broken out.
     28            The existing functionality has a test case.
     29
    1302020-08-07  Chris Dumez  <cdumez@apple.com>
    231
  • trunk/Source/WebCore/PAL/ChangeLog

    r265315 r265389  
     12020-08-07  John Wilander  <wilander@apple.com>
     2
     3        Experimental: Cap the expiry of persistent cookies set in 3rd-party CNAME cloaked HTTP responses
     4        https://bugs.webkit.org/show_bug.cgi?id=215201
     5        <rdar://problem/57454633>
     6
     7        Reviewed by Brent Fulgham. Also reviewed and commented on by Chris Dumez, Jiten Mehta, Sam Weinig, and Alex Christensen.
     8
     9        * pal/spi/cf/CFNetworkSPI.h:
     10            This change declares two new properties on NSURLSessionTask:
     11            - _cookieTransformCallback
     12            - _resolvedCNAMEChain
     13
    1142020-08-05  Tim Horton  <timothy_horton@apple.com>
    215
  • trunk/Source/WebCore/PAL/pal/spi/cf/CFNetworkSPI.h

    r264943 r265389  
    296296    NSHTTPCookieAcceptPolicyExclusivelyFromMainDocumentDomain = 3,
    297297};
     298
     299#if HAVE(CFNETWORK_CNAME_AND_COOKIE_TRANSFORM_SPI)
     300@interface NSURLSessionTask ()
     301@property (nonatomic, copy, nullable) NSArray<NSHTTPCookie*>* (^_cookieTransformCallback)(NSArray<NSHTTPCookie*>* cookies);
     302@property (nonatomic, readonly, nullable) NSArray<NSString*>* _resolvedCNAMEChain;
     303@end
     304#endif
    298305
    299306#endif // defined(__OBJC__)
  • trunk/Source/WebCore/page/Settings.yaml

    r263977 r265389  
    929929  initial: false
    930930
     931isCNAMECloakingMitigationEnabled:
     932  initial: false
     933
    931934isLoggedInAPIEnabled:
    932935  initial: false
  • trunk/Source/WebCore/platform/network/NetworkStorageSession.cpp

    r263964 r265389  
    7373    m_isResourceLoadStatisticsEnabled = enabled;
    7474}
     75
     76bool NetworkStorageSession::resourceLoadStatisticsEnabled() const
     77{
     78    return m_isResourceLoadStatisticsEnabled;
     79}
    7580#endif
    7681
  • trunk/Source/WebCore/platform/network/NetworkStorageSession.h

    r264811 r265389  
    8686enum class ThirdPartyCookieBlockingMode : uint8_t { All, AllExceptBetweenAppBoundDomains, AllOnSitesWithoutUserInteraction, OnlyAccordingToPerDomainPolicy };
    8787enum class SameSiteStrictEnforcementEnabled : bool { Yes, No };
     88enum class CNAMECloakingMitigationEnabled : bool { Yes, No };
    8889enum class FirstPartyWebsiteDataRemovalMode : uint8_t { AllButCookies, None, AllButCookiesLiveOnTestingTimeout, AllButCookiesReproTestingTimeout };
    8990enum class ShouldAskITP : bool { No, Yes };
     
    185186#if ENABLE(RESOURCE_LOAD_STATISTICS)
    186187    WEBCORE_EXPORT void setResourceLoadStatisticsEnabled(bool);
     188    WEBCORE_EXPORT bool resourceLoadStatisticsEnabled() const;
    187189    WEBCORE_EXPORT bool shouldBlockCookies(const ResourceRequest&, Optional<FrameIdentifier>, Optional<PageIdentifier>, ShouldRelaxThirdPartyCookieBlocking) const;
    188190    WEBCORE_EXPORT bool shouldBlockCookies(const URL& firstPartyForCookies, const URL& resource, Optional<FrameIdentifier>, Optional<PageIdentifier>, ShouldRelaxThirdPartyCookieBlocking) const;
     
    190192    WEBCORE_EXPORT bool shouldBlockThirdPartyCookiesButKeepFirstPartyCookiesFor(const RegistrableDomain&) const;
    191193    WEBCORE_EXPORT void setAllCookiesToSameSiteStrict(const RegistrableDomain&, CompletionHandler<void()>&&);
     194#if PLATFORM(COCOA)
     195    WEBCORE_EXPORT static NSHTTPCookie *capExpiryOfPersistentCookie(NSHTTPCookie *, Seconds cap);
     196#endif
    192197    WEBCORE_EXPORT bool hasHadUserInteractionAsFirstParty(const RegistrableDomain&) const;
    193198    WEBCORE_EXPORT void setPrevalentDomainsToBlockAndDeleteCookiesFor(const Vector<RegistrableDomain>&);
  • trunk/Source/WebCore/platform/network/cocoa/NetworkStorageSessionCocoa.mm

    r264943 r265389  
    309309}
    310310
     311NSHTTPCookie *NetworkStorageSession::capExpiryOfPersistentCookie(NSHTTPCookie *cookie, Seconds cap)
     312{
     313    if ([cookie isSessionOnly])
     314        return cookie;
     315
     316    if (!cookie.expiresDate || cookie.expiresDate.timeIntervalSinceNow > cap.seconds()) {
     317        auto properties = adoptNS([[cookie properties] mutableCopy]);
     318        auto date = adoptNS([[NSDate alloc] initWithTimeIntervalSinceNow:cap.seconds()]);
     319        [properties setObject:date.get() forKey:NSHTTPCookieExpires];
     320        cookie = [NSHTTPCookie cookieWithProperties:properties.get()];
     321    }
     322    return cookie;
     323}
     324
    311325NSArray *NetworkStorageSession::cookiesForURL(const URL& firstParty, const SameSiteInfo& sameSiteInfo, const URL& url, Optional<FrameIdentifier> frameID, Optional<PageIdentifier> pageID, ShouldAskITP shouldAskITP, ShouldRelaxThirdPartyCookieBlocking shouldRelaxThirdPartyCookieBlocking) const
    312326{
     
    418432        return nil;
    419433
    420     // Cap lifetime of persistent, client-side cookies to a week.
    421     if (cappedLifetime && ![cookie isSessionOnly]) {
    422         if (!cookie.expiresDate || cookie.expiresDate.timeIntervalSinceNow > cappedLifetime->seconds()) {
    423             auto properties = adoptNS([[cookie properties] mutableCopy]);
    424             auto dateInAWeek = adoptNS([[NSDate alloc] initWithTimeIntervalSinceNow:cappedLifetime->seconds()]);
    425             [properties setObject:dateInAWeek.get() forKey:NSHTTPCookieExpires];
    426             return [NSHTTPCookie cookieWithProperties:properties.get()];
    427         }
    428     }
     434    // Cap lifetime of persistent, client-side cookies.
     435    if (cappedLifetime)
     436        return NetworkStorageSession::capExpiryOfPersistentCookie(cookie, *cappedLifetime);
    429437
    430438    return cookie;
  • trunk/Source/WebKit/ChangeLog

    r265376 r265389  
     12020-08-07  John Wilander  <wilander@apple.com>
     2
     3        Experimental: Cap the expiry of persistent cookies set in 3rd-party CNAME cloaked HTTP responses
     4        https://bugs.webkit.org/show_bug.cgi?id=215201
     5        <rdar://problem/57454633>
     6
     7        Reviewed by Brent Fulgham. Also reviewed and commented on by Chris Dumez, Jiten Mehta, Sam Weinig, and Alex Christensen.
     8
     9        This experimental feature is off by default.
     10
     11        CNAME cloaking means a host resolves to a a different domain, potentially a
     12        third-party domain, as part of DNS resolution.
     13
     14        This patch makes WebKit::NetworkDataTaskCocoa capture any CNAME cloaking for
     15        the first party host and stores it in a table in the WebKit::NetworkSession.
     16        It then checks first party subresource loads to see if they resolve to a
     17        different domain and if so, compare that domain to both the first party
     18        domain and its CNAME cloaking domain, if there is one. If there's a
     19        mismatch, it's deemed a case of third-party CNAME cloaking and any cookies
     20        set in the response of the cloaked subresource load will have their expiry
     21        capped to 7 days.
     22
     23        The cases for capping expiry look like this (and are backed by test cases):
     24
     25        First-party host  | First-party subdomain      | Capped expiry
     26        ------------------|----------------------------|--------------
     27        No CNAME cloaking | No CNAME cloaking          | No
     28        No CNAME cloaking | First-party CNAME cloaking | No
     29        No CNAME cloaking | Third-party CNAME cloaking | Yes
     30        CNAME cloaking    | No CNAME cloaking          | No
     31        CNAME cloaking    | Matching CNAME cloaking    | No
     32        CNAME cloaking    | First-party CNAME cloaking | No
     33        CNAME cloaking    | Third-party CNAME cloaking | Yes
     34
     35        This patch makes use of two new CFNetwork SPIs on NSURLSessionTask:
     36        - _cookieTransformCallback
     37        - _resolvedCNAMEChain
     38
     39        * NetworkProcess/NetworkProcess.cpp:
     40        (WebKit::NetworkProcess::resetParametersToDefaultValues):
     41            This reset now covers the new CNAME cloaking member variables.
     42        (WebKit::NetworkProcess::setIsRunningResourceLoadStatisticsTest):
     43            This function now also enables the CNAME cloaking code.
     44        (WebKit::NetworkProcess::setFirstPartyHostCNAMEDomainForTesting):
     45        (WebKit::NetworkProcess::setThirdPartyCNAMEDomainForTesting):
     46        * NetworkProcess/NetworkProcess.h:
     47        * NetworkProcess/NetworkProcess.messages.in:
     48            New IPC to forward test configuration.
     49        * NetworkProcess/NetworkSession.cpp:
     50        (WebKit::NetworkSession::NetworkSession):
     51            Now picks up the flag for this feature.
     52        (WebKit::NetworkSession::setFirstPartyHostCNAMEDomain):
     53            This is called from NetworkDataTaskCocoa::updateFirstPartyInfoForTaskAndSession()
     54            when there is CNAME cloaking for the first party host. This is done to make it
     55            possible to not cap the expiry of cookies if subsequent subresource loads have
     56            CNAME cloaking that matches the first-party host's CNAME cloaking. This happens
     57            when whole websites are hosted on edge networks.
     58            This function is also used by the test infrastructure to mock the DNS resolution
     59            for a first-party host.
     60        (WebKit::NetworkSession::firstPartyHostCNAMEDomain):
     61            This returns any captured CNAME cloaking for a host, if there is one.
     62        (WebKit::NetworkSession::resetCNAMEDomainData):
     63        * NetworkProcess/NetworkSession.h:
     64        (WebKit::NetworkSession::setCNAMECloakingMitigationEnabled):
     65        (WebKit::NetworkSession::cnameCloakingMitigationEnabled const):
     66        (WebKit::NetworkSession::setThirdPartyCNAMEDomainForTesting):
     67            This test functions allows us to mock the DNS resolution for a subresource.
     68        (WebKit::NetworkSession::thirdPartyCNAMEDomainForTesting const):
     69        * NetworkProcess/cocoa/NetworkDataTaskCocoa.h:
     70        * NetworkProcess/cocoa/NetworkDataTaskCocoa.mm:
     71        (WebKit::hasCNAMEAndCookieTransformSPI):
     72        (WebKit::lastCNAMEDomain):
     73        (WebKit::NetworkDataTaskCocoa::updateFirstPartyInfoForSession):
     74            This is called by NetworkDataTaskCocoa::didReceiveResponse() to capture any
     75            CNAME cloaking for the first-party host.
     76        (WebKit::NetworkDataTaskCocoa::applyCookiePolicyForThirdPartyCNAMECloaking):
     77            This is called in the NetworkDataTaskCocoa constructor and in
     78            NetworkDataTaskCocoa::willPerformHTTPRedirection() and sets the new
     79            _cookieTransformCallback SPI property on the task which will check the
     80            response for any third-party CNAME cloaking and cap the expiry of incoming
     81            cookies accordingly.
     82        (WebKit::NetworkDataTaskCocoa::NetworkDataTaskCocoa):
     83            This now calls
     84            NetworkDataTaskCocoa::applyCookiePolicyForThirdPartyCNAMECloaking().
     85        (WebKit::NetworkDataTaskCocoa::didReceiveResponse):
     86            This now calls
     87            NetworkDataTaskCocoa::updateFirstPartyInfoForTaskAndSession().
     88        (WebKit::NetworkDataTaskCocoa::willPerformHTTPRedirection):
     89            This now calls
     90            NetworkDataTaskCocoa::applyCookiePolicyForThirdPartyCNAMECloaking().
     91        * Shared/ResourceLoadStatisticsParameters.h:
     92            Now holds a WebCore::CNAMECloakingMitigationEnabled flag.
     93        (WebKit::ResourceLoadStatisticsParameters::encode const):
     94        (WebKit::ResourceLoadStatisticsParameters::decode):
     95        * Shared/WebPreferences.yaml:
     96        * UIProcess/API/C/WKWebsiteDataStoreRef.cpp:
     97        (WKWebsiteDataStoreSetResourceLoadStatisticsFirstPartyHostCNAMEDomainForTesting):
     98            Used to mock CNAME resolution data.
     99        (WKWebsiteDataStoreSetResourceLoadStatisticsThirdPartyCNAMEDomainForTesting):
     100            Used to mock CNAME resolution data.
     101        * UIProcess/API/C/WKWebsiteDataStoreRef.h:
     102        * UIProcess/Network/NetworkProcessProxy.cpp:
     103        (WebKit::NetworkProcessProxy::setFirstPartyHostCNAMEDomainForTesting):
     104        (WebKit::NetworkProcessProxy::setThirdPartyCNAMEDomainForTesting):
     105        * UIProcess/Network/NetworkProcessProxy.h:
     106        * UIProcess/WebProcessPool.cpp:
     107        (WebKit::WebProcessPool::ensureNetworkProcess):
     108            Now handles the WebCore::CNAMECloakingMitigationEnabled flag.
     109        * UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm:
     110        (WebKit::WebsiteDataStore::platformSetNetworkParameters):
     111            Now handles the WebCore::CNAMECloakingMitigationEnabled flag.
     112        * UIProcess/WebsiteData/WebsiteDataStore.cpp:
     113        (WebKit::WebsiteDataStore::setResourceLoadStatisticsFirstPartyHostCNAMEDomainForTesting):
     114        (WebKit::WebsiteDataStore::setResourceLoadStatisticsThirdPartyCNAMEDomainForTesting):
     115        (WebKit::WebsiteDataStore::parameters):
     116        * UIProcess/WebsiteData/WebsiteDataStore.h:
     117
    11182020-08-07  Wenson Hsieh  <wenson_hsieh@apple.com>
    2119
  • trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp

    r265149 r265389  
    815815{
    816816    if (auto* networkSession = this->networkSession(sessionID)) {
     817        networkSession->resetCNAMEDomainData();
     818        networkSession->setCNAMECloakingMitigationEnabled(WebCore::CNAMECloakingMitigationEnabled::No);
    817819        if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
    818820            resourceLoadStatistics->resetParametersToDefaultValues(WTFMove(completionHandler));
     
    867869{
    868870    if (auto* networkSession = this->networkSession(sessionID)) {
     871        networkSession->setCNAMECloakingMitigationEnabled(WebCore::CNAMECloakingMitigationEnabled::Yes);
    869872        if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
    870873            resourceLoadStatistics->setIsRunningTest(value, WTFMove(completionHandler));
     
    13791382        completionHandler();
    13801383    }
     1384}
     1385
     1386void NetworkProcess::setFirstPartyHostCNAMEDomainForTesting(PAL::SessionID sessionID, String&& firstPartyHost, WebCore::RegistrableDomain&& cnameDomain, CompletionHandler<void()>&& completionHandler)
     1387{
     1388    if (auto* networkSession = this->networkSession(sessionID))
     1389        networkSession->setFirstPartyHostCNAMEDomain(WTFMove(firstPartyHost), WTFMove(cnameDomain));
     1390    completionHandler();
     1391}
     1392
     1393void NetworkProcess::setThirdPartyCNAMEDomainForTesting(PAL::SessionID sessionID, WebCore::RegistrableDomain&& domain, CompletionHandler<void()>&& completionHandler)
     1394{
     1395    if (auto* networkSession = this->networkSession(sessionID))
     1396        networkSession->setThirdPartyCNAMEDomainForTesting(WTFMove(domain));
     1397    completionHandler();
    13811398}
    13821399#endif // ENABLE(RESOURCE_LOAD_STATISTICS)
  • trunk/Source/WebKit/NetworkProcess/NetworkProcess.h

    r264664 r265389  
    274274    void setFirstPartyWebsiteDataRemovalModeForTesting(PAL::SessionID, WebCore::FirstPartyWebsiteDataRemovalMode, CompletionHandler<void()>&&);
    275275    void setToSameSiteStrictCookiesForTesting(PAL::SessionID, const WebCore::RegistrableDomain&, CompletionHandler<void()>&&);
     276    void setFirstPartyHostCNAMEDomainForTesting(PAL::SessionID, String&& firstPartyHost, WebCore::RegistrableDomain&& cnameDomain, CompletionHandler<void()>&&);
     277    void setThirdPartyCNAMEDomainForTesting(PAL::SessionID, WebCore::RegistrableDomain&&, CompletionHandler<void()>&&);
    276278#endif
    277279
  • trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in

    r264356 r265389  
    149149    SetFirstPartyWebsiteDataRemovalModeForTesting(PAL::SessionID sessionID, enum:uint8_t WebCore::FirstPartyWebsiteDataRemovalMode mode) -> () Async
    150150    SetToSameSiteStrictCookiesForTesting(PAL::SessionID sessionID, WebCore::RegistrableDomain domain) -> () Async
     151    SetFirstPartyHostCNAMEDomainForTesting(PAL::SessionID sessionID, String firstPartyHost, WebCore::RegistrableDomain cnameDomain) -> () Async
     152    SetThirdPartyCNAMEDomainForTesting(PAL::SessionID sessionID, WebCore::RegistrableDomain domain) -> () Async
    151153#endif
    152154
  • trunk/Source/WebKit/NetworkProcess/NetworkSession.cpp

    r263298 r265389  
    9191    , m_firstPartyWebsiteDataRemovalMode(parameters.resourceLoadStatisticsParameters.firstPartyWebsiteDataRemovalMode)
    9292    , m_standaloneApplicationDomain(parameters.resourceLoadStatisticsParameters.standaloneApplicationDomain)
     93    , m_cnameCloakingMitigationEnabled(parameters.resourceLoadStatisticsParameters.cnameCloakingMitigationEnabled)
    9394#endif
    9495    , m_adClickAttribution(makeUniqueRef<AdClickAttributionManager>(networkProcess, parameters.sessionID))
     
    281282        m_resourceLoadStatistics->setSameSiteStrictEnforcementEnabled(enabled);
    282283}
     284
     285void NetworkSession::setFirstPartyHostCNAMEDomain(String&& firstPartyHost, WebCore::RegistrableDomain&& cnameDomain)
     286{
     287#if HAVE(CFNETWORK_CNAME_AND_COOKIE_TRANSFORM_SPI)
     288    if (!cnameCloakingMitigationEnabled())
     289        return;
     290
     291    ASSERT(!firstPartyHost.isEmpty() && !cnameDomain.isEmpty() && firstPartyHost != cnameDomain.string());
     292    if (firstPartyHost.isEmpty() || cnameDomain.isEmpty() || firstPartyHost == cnameDomain.string())
     293        return;
     294    m_firstPartyHostCNAMEDomains.add(WTFMove(firstPartyHost), WTFMove(cnameDomain));
     295#else
     296    UNUSED_PARAM(firstPartyHost);
     297    UNUSED_PARAM(cnameDomain);
     298#endif
     299}
     300
     301Optional<WebCore::RegistrableDomain> NetworkSession::firstPartyHostCNAMEDomain(const String& firstPartyHost)
     302{
     303#if HAVE(CFNETWORK_CNAME_AND_COOKIE_TRANSFORM_SPI)
     304    if (!cnameCloakingMitigationEnabled())
     305        return WTF::nullopt;
     306
     307    auto iterator = m_firstPartyHostCNAMEDomains.find(firstPartyHost);
     308    if (iterator == m_firstPartyHostCNAMEDomains.end())
     309        return WTF::nullopt;
     310    return iterator->value;
     311#else
     312    UNUSED_PARAM(firstPartyHost);
     313    return WTF::nullopt;
     314#endif
     315}
     316
     317void NetworkSession::resetCNAMEDomainData()
     318{
     319    m_firstPartyHostCNAMEDomains.clear();
     320    m_thirdPartyCNAMEDomainForTesting = WTF::nullopt;
     321}
    283322#endif // ENABLE(RESOURCE_LOAD_STATISTICS)
    284323
  • trunk/Source/WebKit/NetworkProcess/NetworkSession.h

    r263298 r265389  
    106106    void setThirdPartyCookieBlockingMode(WebCore::ThirdPartyCookieBlockingMode);
    107107    void setShouldEnbleSameSiteStrictEnforcement(WebCore::SameSiteStrictEnforcementEnabled);
     108    void setCNAMECloakingMitigationEnabled(WebCore::CNAMECloakingMitigationEnabled value) { m_cnameCloakingMitigationEnabled = value; }
     109    bool cnameCloakingMitigationEnabled() const { return m_cnameCloakingMitigationEnabled == WebCore::CNAMECloakingMitigationEnabled::Yes; }
     110    void setFirstPartyHostCNAMEDomain(String&& firstPartyHost, WebCore::RegistrableDomain&& cnameDomain);
     111    Optional<WebCore::RegistrableDomain> firstPartyHostCNAMEDomain(const String& firstPartyHost);
     112    void setThirdPartyCNAMEDomainForTesting(WebCore::RegistrableDomain&& domain) { m_thirdPartyCNAMEDomainForTesting = WTFMove(domain); };
     113    Optional<WebCore::RegistrableDomain> thirdPartyCNAMEDomainForTesting() const { return m_thirdPartyCNAMEDomainForTesting; }
     114    void resetCNAMEDomainData();
    108115    void destroyResourceLoadStatistics(CompletionHandler<void()>&&);
    109116    void flushAndDestroyPersistentStore(CompletionHandler<void()>&&);
     
    167174    WebCore::FirstPartyWebsiteDataRemovalMode m_firstPartyWebsiteDataRemovalMode { WebCore::FirstPartyWebsiteDataRemovalMode::AllButCookies };
    168175    WebCore::RegistrableDomain m_standaloneApplicationDomain;
     176    WebCore::CNAMECloakingMitigationEnabled m_cnameCloakingMitigationEnabled { WebCore::CNAMECloakingMitigationEnabled::No };
     177    HashMap<String, WebCore::RegistrableDomain> m_firstPartyHostCNAMEDomains;
     178    Optional<WebCore::RegistrableDomain> m_thirdPartyCNAMEDomainForTesting;
    169179#endif
    170180    bool m_isStaleWhileRevalidateEnabled { false };
  • trunk/Source/WebKit/NetworkProcess/cocoa/NetworkDataTaskCocoa.h

    r264021 r265389  
    3434OBJC_CLASS NSHTTPCookieStorage;
    3535OBJC_CLASS NSURLSessionDataTask;
     36
     37namespace WebCore {
     38class RegistrableDomain;
     39}
    3640
    3741namespace WebKit {
     
    8892#if ENABLE(RESOURCE_LOAD_STATISTICS)
    8993    static NSHTTPCookieStorage *statelessCookieStorage();
     94#if HAVE(CFNETWORK_CNAME_AND_COOKIE_TRANSFORM_SPI)
     95    void updateFirstPartyInfoForSession(const URL&);
     96    void applyCookiePolicyForThirdPartyCNAMECloaking(const WebCore::ResourceRequest&);
     97#endif
    9098    void blockCookies();
    9199    void unblockCookies();
     
    103111#if ENABLE(RESOURCE_LOAD_STATISTICS)
    104112    bool m_hasBeenSetToUseStatelessCookieStorage { false };
     113#if HAVE(CFNETWORK_CNAME_AND_COOKIE_TRANSFORM_SPI)
     114    Seconds m_ageCapForCNAMECloakedCookies { 24_h * 7 };
     115#endif
    105116#endif
    106117
  • trunk/Source/WebKit/NetworkProcess/cocoa/NetworkDataTaskCocoa.mm

    r264021 r265389  
    3939#import <WebCore/NetworkStorageSession.h>
    4040#import <WebCore/NotImplemented.h>
     41#import <WebCore/RegistrableDomain.h>
    4142#import <WebCore/ResourceRequest.h>
    4243#import <pal/spi/cf/CFNetworkSPI.h>
     
    129130    return statelessCookieStorage.get().get();
    130131}
     132
     133#if HAVE(CFNETWORK_CNAME_AND_COOKIE_TRANSFORM_SPI)
     134// FIXME: Remove these selector checks when macOS Big Sur has shipped.
     135// https://bugs.webkit.org/show_bug.cgi?id=215280
     136static bool hasCNAMEAndCookieTransformSPI(NSURLSessionDataTask* task)
     137{
     138    return [task respondsToSelector:@selector(_cookieTransformCallback)]
     139        && [task respondsToSelector:@selector(_resolvedCNAMEChain)];
     140}
     141
     142static WebCore::RegistrableDomain lastCNAMEDomain(NSArray<NSString *> *cnames)
     143{
     144    if (auto* lastResolvedCNAMEInChain = [cnames lastObject]) {
     145        auto cname = String(lastResolvedCNAMEInChain);
     146        if (cname.endsWith('.'))
     147            cname.remove(cname.length() - 1);
     148        return WebCore::RegistrableDomain::uncheckedCreateFromHost(cname);
     149    }
     150
     151    return { };
     152}
     153
     154void NetworkDataTaskCocoa::updateFirstPartyInfoForSession(const URL& requestURL)
     155{
     156    if (!hasCNAMEAndCookieTransformSPI(m_task.get()) || !networkSession() || !networkSession()->networkStorageSession() || !networkSession()->networkStorageSession()->resourceLoadStatisticsEnabled() || !networkSession()->cnameCloakingMitigationEnabled() || requestURL.host().isEmpty())
     157        return;
     158
     159    auto cnameDomain = lastCNAMEDomain([m_task _resolvedCNAMEChain]);
     160    if (!cnameDomain.isEmpty())
     161        networkSession()->setFirstPartyHostCNAMEDomain(requestURL.host().toString(), WTFMove(cnameDomain));
     162}
     163
     164void NetworkDataTaskCocoa::applyCookiePolicyForThirdPartyCNAMECloaking(const WebCore::ResourceRequest& request)
     165{
     166    if (!hasCNAMEAndCookieTransformSPI(m_task.get()) || isTopLevelNavigation() || !networkSession() || !networkSession()->networkStorageSession() || !networkSession()->networkStorageSession()->resourceLoadStatisticsEnabled() || !networkSession()->cnameCloakingMitigationEnabled())
     167        return;
     168
     169    if (isThirdPartyRequest(request)) {
     170        m_task.get()._cookieTransformCallback = nil;
     171        return;
     172    }
     173
     174    // Cap expiry of incoming cookies in response if it is a same-site
     175    // subresource but it resolves to a different CNAME than the top
     176    // site request, a.k.a. third-party CNAME cloaking.
     177    auto firstPartyURL = request.firstPartyForCookies();
     178    auto firstPartyHostCNAME = networkSession()->firstPartyHostCNAMEDomain(firstPartyURL.host().toString());
     179
     180    m_task.get()._cookieTransformCallback = makeBlockPtr([requestURL = crossThreadCopy(request.url()), firstPartyURL = crossThreadCopy(firstPartyURL), firstPartyHostCNAME = crossThreadCopy(firstPartyHostCNAME), thirdPartyCNAMEDomainForTesting = crossThreadCopy(networkSession()->thirdPartyCNAMEDomainForTesting()), ageCapForCNAMECloakedCookies = crossThreadCopy(m_ageCapForCNAMECloakedCookies), task = m_task] (NSArray<NSHTTPCookie*> *cookiesSetInResponse) -> NSArray<NSHTTPCookie*> * {
     181        if (![cookiesSetInResponse count])
     182            return cookiesSetInResponse;
     183
     184        auto cnameDomain = lastCNAMEDomain([task _resolvedCNAMEChain]);
     185        if (cnameDomain.isEmpty()) {
     186            if (!thirdPartyCNAMEDomainForTesting)
     187                return cookiesSetInResponse;
     188            cnameDomain = *thirdPartyCNAMEDomainForTesting;
     189        }
     190
     191        // CNAME cloaking is a first-party sub resource that resolves
     192        // through a CNAME that differs from the first-party domain and
     193        // also differs from the top frame host's CNAME, if one exists.
     194        if (!cnameDomain.matches(firstPartyURL) && (!firstPartyHostCNAME || cnameDomain != *firstPartyHostCNAME)) {
     195
     196            NSUInteger count = [cookiesSetInResponse count];
     197            // Don't use RetainPtr here. This array has to be retained and
     198            // auto released to not be released before returned to the code
     199            // executing the block.
     200            auto* cappedCookies = [NSMutableArray arrayWithCapacity:count];
     201            for (NSUInteger i = 0; i < count; ++i) {
     202                NSHTTPCookie *cookie = (NSHTTPCookie *)[cookiesSetInResponse objectAtIndex:i];
     203                cookie = WebCore::NetworkStorageSession::capExpiryOfPersistentCookie(cookie, ageCapForCNAMECloakedCookies);
     204                [cappedCookies addObject:cookie];
     205            }
     206            return cappedCookies;
     207        }
     208
     209        return cookiesSetInResponse;
     210    }).get();
     211}
     212#endif
    131213
    132214void NetworkDataTaskCocoa::blockCookies()
     
    264346
    265347#if ENABLE(RESOURCE_LOAD_STATISTICS)
     348#if HAVE(CFNETWORK_CNAME_AND_COOKIE_TRANSFORM_SPI)
     349    applyCookiePolicyForThirdPartyCNAMECloaking(request);
     350#endif
    266351    if (shouldBlockCookies) {
    267352#if !RELEASE_LOG_DISABLED
     
    346431{
    347432    WTFEmitSignpost(m_task.get(), "DataTask", "received response headers");
     433#if HAVE(CFNETWORK_CNAME_AND_COOKIE_TRANSFORM_SPI)
     434    if (isTopLevelNavigation())
     435        updateFirstPartyInfoForSession(response.url());
     436#endif
    348437    NetworkDataTask::didReceiveResponse(WTFMove(response), negotiatedLegacyTLS, WTFMove(completionHandler));
    349438}
     
    400489
    401490#if ENABLE(RESOURCE_LOAD_STATISTICS)
     491#if HAVE(CFNETWORK_CNAME_AND_COOKIE_TRANSFORM_SPI)
     492    applyCookiePolicyForThirdPartyCNAMECloaking(request);
     493#endif
    402494    if (!m_hasBeenSetToUseStatelessCookieStorage) {
    403495        if (m_storedCredentialsPolicy == WebCore::StoredCredentialsPolicy::EphemeralStateless
  • trunk/Source/WebKit/Shared/ResourceLoadStatisticsParameters.h

    r261242 r265389  
    4646    WebCore::ThirdPartyCookieBlockingMode thirdPartyCookieBlockingMode { WebCore::ThirdPartyCookieBlockingMode::All };
    4747    WebCore::SameSiteStrictEnforcementEnabled sameSiteStrictEnforcementEnabled { WebCore::SameSiteStrictEnforcementEnabled::No };
     48    WebCore::CNAMECloakingMitigationEnabled cnameCloakingMitigationEnabled { WebCore::CNAMECloakingMitigationEnabled::No };
    4849#endif
    4950    WebCore::FirstPartyWebsiteDataRemovalMode firstPartyWebsiteDataRemovalMode { WebCore::FirstPartyWebsiteDataRemovalMode::AllButCookies };
     
    6465        encoder << thirdPartyCookieBlockingMode;
    6566        encoder << sameSiteStrictEnforcementEnabled;
     67        encoder << cnameCloakingMitigationEnabled;
    6668#endif
    6769        encoder << firstPartyWebsiteDataRemovalMode;
     
    118120        if (!sameSiteStrictEnforcementEnabled)
    119121            return WTF::nullopt;
     122
     123        Optional<WebCore::CNAMECloakingMitigationEnabled> cnameCloakingMitigationEnabled;
     124        decoder >> cnameCloakingMitigationEnabled;
     125        if (!cnameCloakingMitigationEnabled)
     126            return WTF::nullopt;
    120127#endif
    121128
     
    151158            WTFMove(*thirdPartyCookieBlockingMode),
    152159            WTFMove(*sameSiteStrictEnforcementEnabled),
     160            WTFMove(*cnameCloakingMitigationEnabled),
    153161#endif
    154162            WTFMove(*firstPartyWebsiteDataRemovalMode),
  • trunk/Source/WebKit/Shared/WebPreferences.yaml

    r265235 r265389  
    20572057  category: experimental
    20582058
     2059IsCNAMECloakingMitigationEnabled:
     2060  type: bool
     2061  defaultValue: false
     2062  humanReadableName: "Enable CNAME cloaking mitigation"
     2063  humanReadableDescription: "Enable third-party CNAME cloaking mitigation"
     2064  category: experimental
     2065
    20592066IsLoggedInAPIEnabled:
    20602067    type: bool
  • trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.cpp

    r264356 r265389  
    629629}
    630630
     631void WKWebsiteDataStoreSetResourceLoadStatisticsFirstPartyHostCNAMEDomainForTesting(WKWebsiteDataStoreRef dataStoreRef, WKStringRef firstPartyURLString, WKStringRef cnameURLString, void* context, WKWebsiteDataStoreSetResourceLoadStatisticsFirstPartyHostCNAMEDomainForTestingFunction completionHandler)
     632{
     633#if ENABLE(RESOURCE_LOAD_STATISTICS)
     634    WebKit::toImpl(dataStoreRef)->setResourceLoadStatisticsFirstPartyHostCNAMEDomainForTesting(URL(URL(), WebKit::toImpl(firstPartyURLString)->string()), URL(URL(), WebKit::toImpl(cnameURLString)->string()), [context, completionHandler] {
     635        completionHandler(context);
     636    });
     637#else
     638    completionHandler(context);
     639#endif
     640}
     641
     642void WKWebsiteDataStoreSetResourceLoadStatisticsThirdPartyCNAMEDomainForTesting(WKWebsiteDataStoreRef dataStoreRef, WKStringRef cnameURLString, void* context, WKWebsiteDataStoreSetResourceLoadStatisticsThirdPartyCNAMEDomainForTestingFunction completionHandler)
     643{
     644#if ENABLE(RESOURCE_LOAD_STATISTICS)
     645    WebKit::toImpl(dataStoreRef)->setResourceLoadStatisticsThirdPartyCNAMEDomainForTesting(URL(URL(), WebKit::toImpl(cnameURLString)->string()), [context, completionHandler] {
     646        completionHandler(context);
     647    });
     648#else
     649    completionHandler(context);
     650#endif
     651}
     652
    631653void WKWebsiteDataStoreSetAppBoundDomainsForTesting(WKArrayRef originURLsRef, void* context, WKWebsiteDataStoreSetAppBoundDomainsForTestingFunction completionHandler)
    632654{
  • trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.h

    r264356 r265389  
    131131typedef void (*WKWebsiteDataStoreSetResourceLoadStatisticsToSameSiteStrictCookiesForTestingFunction)(void* functionContext);
    132132WK_EXPORT void WKWebsiteDataStoreSetResourceLoadStatisticsToSameSiteStrictCookiesForTesting(WKWebsiteDataStoreRef dataStoreRef, WKStringRef hostName, void* context, WKWebsiteDataStoreSetResourceLoadStatisticsToSameSiteStrictCookiesForTestingFunction completionHandler);
     133typedef void (*WKWebsiteDataStoreSetResourceLoadStatisticsFirstPartyHostCNAMEDomainForTestingFunction)(void* functionContext);
     134WK_EXPORT void WKWebsiteDataStoreSetResourceLoadStatisticsFirstPartyHostCNAMEDomainForTesting(WKWebsiteDataStoreRef dataStoreRef, WKStringRef firstPartyURLString, WKStringRef cnameURLString, void* context, WKWebsiteDataStoreSetResourceLoadStatisticsFirstPartyHostCNAMEDomainForTestingFunction completionHandler);
     135typedef void (*WKWebsiteDataStoreSetResourceLoadStatisticsThirdPartyCNAMEDomainForTestingFunction)(void* functionContext);
     136WK_EXPORT void WKWebsiteDataStoreSetResourceLoadStatisticsThirdPartyCNAMEDomainForTesting(WKWebsiteDataStoreRef dataStoreRef, WKStringRef cnameURLString, void* context, WKWebsiteDataStoreSetResourceLoadStatisticsThirdPartyCNAMEDomainForTestingFunction completionHandler);
    133137typedef void (*WKWebsiteDataStoreSetAppBoundDomainsForTestingFunction)(void* functionContext);
    134138WK_EXPORT void WKWebsiteDataStoreSetAppBoundDomainsForTesting(WKArrayRef originURLsRef, void* context, WKWebsiteDataStoreSetAppBoundDomainsForTestingFunction completionHandler);
  • trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp

    r265035 r265389  
    11961196}
    11971197
     1198void NetworkProcessProxy::setFirstPartyHostCNAMEDomainForTesting(PAL::SessionID sessionID, const String& firstPartyHost, const RegistrableDomain& cnameDomain, CompletionHandler<void()>&& completionHandler)
     1199{
     1200    sendWithAsyncReply(Messages::NetworkProcess::SetFirstPartyHostCNAMEDomainForTesting(sessionID, firstPartyHost, cnameDomain), WTFMove(completionHandler));
     1201}
     1202
     1203void NetworkProcessProxy::setThirdPartyCNAMEDomainForTesting(PAL::SessionID sessionID, const WebCore::RegistrableDomain& domain, CompletionHandler<void()>&& completionHandler)
     1204{
     1205    sendWithAsyncReply(Messages::NetworkProcess::SetThirdPartyCNAMEDomainForTesting(sessionID, domain), WTFMove(completionHandler));
     1206}
    11981207void NetworkProcessProxy::setDomainsWithUserInteraction(HashSet<WebCore::RegistrableDomain>&& domains)
    11991208{
  • trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h

    r264356 r265389  
    186186    void setFirstPartyWebsiteDataRemovalModeForTesting(PAL::SessionID, WebCore::FirstPartyWebsiteDataRemovalMode, CompletionHandler<void()>&&);
    187187    void setToSameSiteStrictCookiesForTesting(PAL::SessionID, const RegistrableDomain&, CompletionHandler<void()>&&);
     188    void setFirstPartyHostCNAMEDomainForTesting(PAL::SessionID, const String& firstPartyHost, const RegistrableDomain& cnameDomain, CompletionHandler<void()>&&);
     189    void setThirdPartyCNAMEDomainForTesting(PAL::SessionID, const WebCore::RegistrableDomain&, CompletionHandler<void()>&&);
    188190    void setDomainsWithUserInteraction(HashSet<WebCore::RegistrableDomain>&&);
    189191#endif
  • trunk/Source/WebKit/UIProcess/WebProcessPool.cpp

    r265081 r265389  
    602602    WebCore::ThirdPartyCookieBlockingMode thirdPartyCookieBlockingMode = WebCore::ThirdPartyCookieBlockingMode::All;
    603603    WebCore::SameSiteStrictEnforcementEnabled sameSiteStrictEnforcementEnabled = WebCore::SameSiteStrictEnforcementEnabled::No;
     604    WebCore::CNAMECloakingMitigationEnabled cnameCloakingMitigationEnabled = WebCore::CNAMECloakingMitigationEnabled::No;
    604605#endif
    605606    WebCore::FirstPartyWebsiteDataRemovalMode firstPartyWebsiteDataRemovalMode = WebCore::FirstPartyWebsiteDataRemovalMode::AllButCookies;
     
    635636            thirdPartyCookieBlockingMode = networkSessionParameters.resourceLoadStatisticsParameters.thirdPartyCookieBlockingMode;
    636637            sameSiteStrictEnforcementEnabled = networkSessionParameters.resourceLoadStatisticsParameters.sameSiteStrictEnforcementEnabled;
     638            cnameCloakingMitigationEnabled = networkSessionParameters.resourceLoadStatisticsParameters.cnameCloakingMitigationEnabled;
    637639#endif
    638640            firstPartyWebsiteDataRemovalMode = networkSessionParameters.resourceLoadStatisticsParameters.firstPartyWebsiteDataRemovalMode;
     
    662664            thirdPartyCookieBlockingMode = networkSessionParameters.resourceLoadStatisticsParameters.thirdPartyCookieBlockingMode;
    663665            sameSiteStrictEnforcementEnabled = networkSessionParameters.resourceLoadStatisticsParameters.sameSiteStrictEnforcementEnabled;
     666            cnameCloakingMitigationEnabled = networkSessionParameters.resourceLoadStatisticsParameters.cnameCloakingMitigationEnabled;
    664667#endif
    665668            firstPartyWebsiteDataRemovalMode = networkSessionParameters.resourceLoadStatisticsParameters.firstPartyWebsiteDataRemovalMode;
     
    705708        thirdPartyCookieBlockingMode,
    706709        sameSiteStrictEnforcementEnabled,
     710        cnameCloakingMitigationEnabled,
    707711#endif
    708712        firstPartyWebsiteDataRemovalMode,
  • trunk/Source/WebKit/UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm

    r265063 r265389  
    9595    bool enableResourceLoadStatisticsDebugMode = false;
    9696    auto sameSiteStrictEnforcementEnabled = WebCore::SameSiteStrictEnforcementEnabled::No;
     97    auto cnameCloakingMitigationEnabled = WebCore::CNAMECloakingMitigationEnabled::No;
    9798    auto firstPartyWebsiteDataRemovalMode = WebCore::FirstPartyWebsiteDataRemovalMode::AllButCookies;
    9899    WebCore::RegistrableDomain resourceLoadStatisticsManualPrevalentResource { };
     
    102103    if ([defaults boolForKey:[NSString stringWithFormat:@"Experimental%@", WebPreferencesKey::isSameSiteStrictEnforcementEnabledKey().createCFString().get()]])
    103104        sameSiteStrictEnforcementEnabled = WebCore::SameSiteStrictEnforcementEnabled::Yes;
     105
     106    if ([defaults boolForKey:[NSString stringWithFormat:@"Experimental%@", WebPreferencesKey::isCNAMECloakingMitigationEnabledKey().createCFString().get()]])
     107        cnameCloakingMitigationEnabled = WebCore::CNAMECloakingMitigationEnabled::Yes;
    104108
    105109    if ([defaults boolForKey:[NSString stringWithFormat:@"Experimental%@", WebPreferencesKey::isFirstPartyWebsiteDataRemovalDisabledKey().createCFString().get()]])
     
    179183    parameters.networkSessionParameters.resourceLoadStatisticsParameters.enableDebugMode = enableResourceLoadStatisticsDebugMode;
    180184    parameters.networkSessionParameters.resourceLoadStatisticsParameters.sameSiteStrictEnforcementEnabled = sameSiteStrictEnforcementEnabled;
     185    parameters.networkSessionParameters.resourceLoadStatisticsParameters.cnameCloakingMitigationEnabled = cnameCloakingMitigationEnabled;
    181186    parameters.networkSessionParameters.resourceLoadStatisticsParameters.firstPartyWebsiteDataRemovalMode = firstPartyWebsiteDataRemovalMode;
    182187    parameters.networkSessionParameters.resourceLoadStatisticsParameters.standaloneApplicationDomain = WebCore::RegistrableDomain { m_configuration->standaloneApplicationURL() };
  • trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp

    r264790 r265389  
    19371937    }
    19381938}
     1939
     1940void WebsiteDataStore::setResourceLoadStatisticsFirstPartyHostCNAMEDomainForTesting(const URL& firstPartyURL, const URL& cnameURL, CompletionHandler<void()>&& completionHandler)
     1941{
     1942    if (cnameURL.host() != "testwebkit.org" && cnameURL.host() != "3rdpartytestwebkit.org") {
     1943        completionHandler();
     1944        return;
     1945    }
     1946
     1947    auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
     1948
     1949    for (auto& processPool : processPools())
     1950        processPool->ensureNetworkProcess().setFirstPartyHostCNAMEDomainForTesting(m_sessionID, firstPartyURL.host().toString(), WebCore::RegistrableDomain { cnameURL }, [callbackAggregator] { });
     1951}
     1952
     1953void WebsiteDataStore::setResourceLoadStatisticsThirdPartyCNAMEDomainForTesting(const URL& cnameURL, CompletionHandler<void()>&& completionHandler)
     1954{
     1955    if (cnameURL.host() != "testwebkit.org" && cnameURL.host() != "3rdpartytestwebkit.org") {
     1956        completionHandler();
     1957        return;
     1958    }
     1959
     1960    auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
     1961
     1962    for (auto& processPool : processPools())
     1963        processPool->ensureNetworkProcess().setThirdPartyCNAMEDomainForTesting(m_sessionID, WebCore::RegistrableDomain { cnameURL }, [callbackAggregator] { });
     1964}
    19391965#endif // ENABLE(RESOURCE_LOAD_STATISTICS)
    19401966
     
    22842310        thirdPartyCookieBlockingMode(),
    22852311        WebCore::SameSiteStrictEnforcementEnabled::No,
     2312        WebCore::CNAMECloakingMitigationEnabled::No,
    22862313#endif
    22872314        firstPartyWebsiteDataRemovalMode,
  • trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h

    r265063 r265389  
    204204    void setResourceLoadStatisticsFirstPartyWebsiteDataRemovalModeForTesting(bool enabled, CompletionHandler<void()>&&);
    205205    void setResourceLoadStatisticsToSameSiteStrictCookiesForTesting(const URL&, CompletionHandler<void()>&&);
     206    void setResourceLoadStatisticsFirstPartyHostCNAMEDomainForTesting(const URL& firstPartyURL, const URL& cnameURL, CompletionHandler<void()>&&);
     207    void setResourceLoadStatisticsThirdPartyCNAMEDomainForTesting(const URL&, CompletionHandler<void()>&&);
    206208    WebCore::ThirdPartyCookieBlockingMode thirdPartyCookieBlockingMode() const;
    207209    bool isItpStateExplicitlySet() const { return m_isItpStateExplicitlySet; }
  • trunk/Tools/ChangeLog

    r265386 r265389  
     12020-08-07  John Wilander  <wilander@apple.com>
     2
     3        Experimental: Cap the expiry of persistent cookies set in 3rd-party CNAME cloaked HTTP responses
     4        https://bugs.webkit.org/show_bug.cgi?id=215201
     5        <rdar://problem/57454633>
     6
     7        Reviewed by Brent Fulgham. Also reviewed and commented on by Chris Dumez, Jiten Mehta, Sam Weinig, and Alex Christensen.
     8
     9        This patch adds two TestRunner functions which allows for testing
     10        with data that would otherwise come from DNS resolution:
     11        - statisticsSetFirstPartyHostCNAMEDomain()
     12        - statisticsSetThirdPartyCNAMEDomain()
     13
     14        * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
     15        * WebKitTestRunner/InjectedBundle/InjectedBundle.cpp:
     16        (WTR::InjectedBundle::didReceiveMessageToPage):
     17        * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
     18        (WTR::TestRunner::statisticsSetFirstPartyHostCNAMEDomain):
     19        (WTR::TestRunner::statisticsCallDidSetFirstPartyHostCNAMEDomainCallback):
     20        (WTR::TestRunner::statisticsSetThirdPartyCNAMEDomain):
     21        (WTR::TestRunner::statisticsCallDidSetThirdPartyCNAMEDomainCallback):
     22        * WebKitTestRunner/InjectedBundle/TestRunner.h:
     23        * WebKitTestRunner/TestController.cpp:
     24        (WTR::TestController::setStatisticsFirstPartyHostCNAMEDomain):
     25        (WTR::TestController::setStatisticsThirdPartyCNAMEDomain):
     26        * WebKitTestRunner/TestController.h:
     27        * WebKitTestRunner/TestInvocation.cpp:
     28        (WTR::TestInvocation::didReceiveMessageFromInjectedBundle):
     29        (WTR::TestInvocation::didSetFirstPartyHostCNAMEDomain):
     30        (WTR::TestInvocation::didSetThirdPartyCNAMEDomain):
     31        * WebKitTestRunner/TestInvocation.h:
     32
    1332020-08-07  Jonathan Bedard  <jbedard@apple.com>
    234
  • trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl

    r265169 r265389  
    348348    void setStatisticsFirstPartyWebsiteDataRemovalMode(boolean value, object callback);
    349349    void statisticsSetToSameSiteStrictCookies(DOMString hostName, object callback);
     350    void statisticsSetFirstPartyHostCNAMEDomain(DOMString firstPartyURLString, DOMString cnameURLString, object callback);
     351    void statisticsSetThirdPartyCNAMEDomain(DOMString cnameURLString, object callback);
    350352    void loadedThirdPartyDomains(object callback);
    351353
  • trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp

    r265248 r265389  
    360360    }
    361361
     362    if (WKStringIsEqualToUTF8CString(messageName, "CallDidSetFirstPartyHostCNAMEDomain")) {
     363        m_testRunner->statisticsCallDidSetFirstPartyHostCNAMEDomainCallback();
     364        return;
     365    }
     366
     367    if (WKStringIsEqualToUTF8CString(messageName, "CallDidSetThirdPartyCNAMEDomain")) {
     368        m_testRunner->statisticsCallDidSetThirdPartyCNAMEDomainCallback();
     369        return;
     370    }
     371
    362372    if (WKStringIsEqualToUTF8CString(messageName, "CallDidResetStatisticsToConsistentState")) {
    363373        m_testRunner->statisticsCallDidResetToConsistentStateCallback();
  • trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp

    r265169 r265389  
    759759    StatisticsDidSetFirstPartyWebsiteDataRemovalModeCallbackID,
    760760    StatisticsDidSetToSameSiteStrictCookiesCallbackID,
     761    StatisticsDidSetFirstPartyHostCNAMEDomainCallbackID,
     762    StatisticsDidSetThirdPartyCNAMEDomainCallbackID,
    761763    AllStorageAccessEntriesCallbackID,
    762764    LoadedThirdPartyDomainsCallbackID,
     
    23652367}
    23662368
     2369
     2370void TestRunner::statisticsSetFirstPartyHostCNAMEDomain(JSStringRef firstPartyURLString, JSStringRef cnameURLString, JSValueRef completionHandler)
     2371{
     2372    cacheTestRunnerCallback(StatisticsDidSetFirstPartyHostCNAMEDomainCallbackID, completionHandler);
     2373
     2374    Vector<WKRetainPtr<WKStringRef>> keys;
     2375    Vector<WKRetainPtr<WKTypeRef>> values;
     2376   
     2377    keys.append(adoptWK(WKStringCreateWithUTF8CString("FirstPartyURL")));
     2378    values.append(adoptWK(WKStringCreateWithJSString(firstPartyURLString)));
     2379   
     2380    keys.append(adoptWK(WKStringCreateWithUTF8CString("CNAME")));
     2381    values.append(adoptWK(WKStringCreateWithJSString(cnameURLString)));
     2382   
     2383    Vector<WKStringRef> rawKeys(keys.size());
     2384    Vector<WKTypeRef> rawValues(values.size());
     2385   
     2386    for (size_t i = 0; i < keys.size(); ++i) {
     2387        rawKeys[i] = keys[i].get();
     2388        rawValues[i] = values[i].get();
     2389    }
     2390
     2391    auto messageName = adoptWK(WKStringCreateWithUTF8CString("StatisticsSetFirstPartyHostCNAMEDomain"));
     2392    auto messageBody = adoptWK(WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size()));
     2393    WKBundlePostMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get());
     2394}
     2395
     2396void TestRunner::statisticsCallDidSetFirstPartyHostCNAMEDomainCallback()
     2397{
     2398    callTestRunnerCallback(StatisticsDidSetFirstPartyHostCNAMEDomainCallbackID);
     2399}
     2400
     2401void TestRunner::statisticsSetThirdPartyCNAMEDomain(JSStringRef cnameURLString, JSValueRef completionHandler)
     2402{
     2403    cacheTestRunnerCallback(StatisticsDidSetThirdPartyCNAMEDomainCallbackID, completionHandler);
     2404
     2405    auto messageName = adoptWK(WKStringCreateWithUTF8CString("StatisticsSetThirdPartyCNAMEDomain"));
     2406    auto messageBody = adoptWK(WKStringCreateWithJSString(cnameURLString));
     2407    WKBundlePostMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get());
     2408}
     2409
     2410void TestRunner::statisticsCallDidSetThirdPartyCNAMEDomainCallback()
     2411{
     2412    callTestRunnerCallback(StatisticsDidSetThirdPartyCNAMEDomainCallbackID);
     2413}
     2414
    23672415void TestRunner::statisticsResetToConsistentState(JSValueRef completionHandler)
    23682416{
  • trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h

    r265169 r265389  
    454454    void statisticsSetToSameSiteStrictCookies(JSStringRef hostName, JSValueRef callback);
    455455    void statisticsCallDidSetToSameSiteStrictCookiesCallback();
     456    void statisticsSetFirstPartyHostCNAMEDomain(JSStringRef firstPartyURLString, JSStringRef cnameURLString, JSValueRef completionHandler);
     457    void statisticsCallDidSetFirstPartyHostCNAMEDomainCallback();
     458    void statisticsSetThirdPartyCNAMEDomain(JSStringRef cnameURLString, JSValueRef completionHandler);
     459    void statisticsCallDidSetThirdPartyCNAMEDomainCallback();
    456460    void statisticsResetToConsistentState(JSValueRef completionHandler);
    457461    void statisticsCallDidResetToConsistentStateCallback();
  • trunk/Tools/WebKitTestRunner/TestController.cpp

    r265258 r265389  
    38633863}
    38643864
     3865void TestController::setStatisticsFirstPartyHostCNAMEDomain(WKStringRef firstPartyURLString, WKStringRef cnameURLString)
     3866{
     3867    ResourceStatisticsCallbackContext context(*this);
     3868    WKWebsiteDataStoreSetResourceLoadStatisticsFirstPartyHostCNAMEDomainForTesting(websiteDataStore(), firstPartyURLString, cnameURLString, &context, resourceStatisticsVoidResultCallback);
     3869    runUntil(context.done, noTimeout);
     3870    m_currentInvocation->didSetFirstPartyHostCNAMEDomain();
     3871}
     3872
     3873void TestController::setStatisticsThirdPartyCNAMEDomain(WKStringRef cnameURLString)
     3874{
     3875    ResourceStatisticsCallbackContext context(*this);
     3876    WKWebsiteDataStoreSetResourceLoadStatisticsThirdPartyCNAMEDomainForTesting(websiteDataStore(), cnameURLString, &context, resourceStatisticsVoidResultCallback);
     3877    runUntil(context.done, noTimeout);
     3878    m_currentInvocation->didSetThirdPartyCNAMEDomain();
     3879}
     3880
    38653881struct AppBoundDomainsCallbackContext {
    38663882    explicit AppBoundDomainsCallbackContext(TestController& controller)
  • trunk/Tools/WebKitTestRunner/TestController.h

    r264356 r265389  
    267267    void setStatisticsFirstPartyWebsiteDataRemovalMode(bool value);
    268268    void setStatisticsToSameSiteStrictCookies(WKStringRef hostName);
     269    void setStatisticsFirstPartyHostCNAMEDomain(WKStringRef firstPartyURLString, WKStringRef cnameURLString);
     270    void setStatisticsThirdPartyCNAMEDomain(WKStringRef cnameURLString);
    269271    void setAppBoundDomains(WKArrayRef originURLs);
    270272    void statisticsResetToConsistentState();
  • trunk/Tools/WebKitTestRunner/TestInvocation.cpp

    r264609 r265389  
    958958    }
    959959
     960    if (WKStringIsEqualToUTF8CString(messageName, "StatisticsSetFirstPartyHostCNAMEDomain")) {
     961        ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
     962       
     963        WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
     964        WKRetainPtr<WKStringRef> firstPartyURLStringKey = adoptWK(WKStringCreateWithUTF8CString("FirstPartyURL"));
     965        WKRetainPtr<WKStringRef> cnameURLStringKey = adoptWK(WKStringCreateWithUTF8CString("CNAME"));
     966       
     967        WKStringRef firstPartyURLString = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, firstPartyURLStringKey.get()));
     968        WKStringRef cnameURLString = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, cnameURLStringKey.get()));
     969       
     970        TestController::singleton().setStatisticsFirstPartyHostCNAMEDomain(firstPartyURLString, cnameURLString);
     971        return;
     972    }
     973
     974    if (WKStringIsEqualToUTF8CString(messageName, "StatisticsSetThirdPartyCNAMEDomain")) {
     975        ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
     976        WKStringRef cnameURLString = static_cast<WKStringRef>(messageBody);
     977        TestController::singleton().setStatisticsThirdPartyCNAMEDomain(cnameURLString);
     978        return;
     979    }
     980
    960981    if (WKStringIsEqualToUTF8CString(messageName, "StatisticsResetToConsistentState")) {
    961982        if (m_shouldDumpResourceLoadStatistics)
     
    19471968}
    19481969
     1970void TestInvocation::didSetFirstPartyHostCNAMEDomain()
     1971{
     1972    WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidSetFirstPartyHostCNAMEDomain"));
     1973    WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), nullptr);
     1974}
     1975
     1976void TestInvocation::didSetThirdPartyCNAMEDomain()
     1977{
     1978    WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidSetThirdPartyCNAMEDomain"));
     1979    WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), nullptr);
     1980}
     1981
    19491982void TestInvocation::didResetStatisticsToConsistentState()
    19501983{
  • trunk/Tools/WebKitTestRunner/TestInvocation.h

    r261963 r265389  
    7878    void didSetFirstPartyWebsiteDataRemovalMode();
    7979    void didSetToSameSiteStrictCookies();
     80    void didSetFirstPartyHostCNAMEDomain();
     81    void didSetThirdPartyCNAMEDomain();
    8082    void didResetStatisticsToConsistentState();
    8183    void didSetBlockCookiesForHost();
Note: See TracChangeset for help on using the changeset viewer.