Title: [284819] trunk
Revision
284819
Author
katherine_che...@apple.com
Date
2021-10-25 13:24:45 -0700 (Mon, 25 Oct 2021)

Log Message

[App Privacy Report] CORS preflight requests attributed incorrectly
https://bugs.webkit.org/show_bug.cgi?id=232221
<rdar://problem/84116159>

Reviewed by Brent Fulgham.

Source/WebKit:

HTTP redirects should already be marked as app-initiated or not based
on the NSURLRequest that initiated the redirect, either because the
same NSURLRequest is used or because it is set in the completion
handler of the networkDataTask->willPerformHTTPRedirection call in
NetworkSessionCocoa.

However, checking the request before calling the completion handler
can initiate CORS preflight checks that create loads that are incorrectly
marked for App Privacy Report. This patch sets the app initiated value
in the ResourceRequest object before the new NetworkDataTask is created to fix this.

* NetworkProcess/cocoa/NetworkDataTaskCocoa.mm:
(WebKit::NetworkDataTaskCocoa::willPerformHTTPRedirection):

LayoutTests:

Layout test coverage.

* http/tests/app-privacy-report/app-attribution-cors-preflight-redirect-expected.txt: Added.
* http/tests/app-privacy-report/app-attribution-cors-preflight-redirect.html: Added.
* http/tests/app-privacy-report/resources/cors-preflight.py: Added.
* http/tests/app-privacy-report/resources/redirect-with-cors-preflight-check.py: Added.
* http/tests/app-privacy-report/user-attribution-cors-preflight-redirect-expected.txt: Added.
* http/tests/app-privacy-report/user-attribution-cors-preflight-redirect.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (284818 => 284819)


--- trunk/LayoutTests/ChangeLog	2021-10-25 20:15:02 UTC (rev 284818)
+++ trunk/LayoutTests/ChangeLog	2021-10-25 20:24:45 UTC (rev 284819)
@@ -1,3 +1,20 @@
+2021-10-25  Kate Cheney  <katherine_che...@apple.com>
+
+        [App Privacy Report] CORS preflight requests attributed incorrectly
+        https://bugs.webkit.org/show_bug.cgi?id=232221
+        <rdar://problem/84116159>
+
+        Reviewed by Brent Fulgham.
+
+        Layout test coverage.
+
+        * http/tests/app-privacy-report/app-attribution-cors-preflight-redirect-expected.txt: Added.
+        * http/tests/app-privacy-report/app-attribution-cors-preflight-redirect.html: Added.
+        * http/tests/app-privacy-report/resources/cors-preflight.py: Added.
+        * http/tests/app-privacy-report/resources/redirect-with-cors-preflight-check.py: Added.
+        * http/tests/app-privacy-report/user-attribution-cors-preflight-redirect-expected.txt: Added.
+        * http/tests/app-privacy-report/user-attribution-cors-preflight-redirect.html: Added.
+
 2021-10-25  Chris Dumez  <cdu...@apple.com>
 
         imported/w3c/web-platform-tests/html/semantics/forms/form-submission-0/form-submission-algorithm.html is timing out

Added: trunk/LayoutTests/http/tests/app-privacy-report/app-attribution-cors-preflight-redirect-expected.txt (0 => 284819)


--- trunk/LayoutTests/http/tests/app-privacy-report/app-attribution-cors-preflight-redirect-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/app-privacy-report/app-attribution-cors-preflight-redirect-expected.txt	2021-10-25 20:24:45 UTC (rev 284819)
@@ -0,0 +1,11 @@
+Tests that CORS preflight checks for HTTP redirects are marked app initiated.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS loadedUrl is "http://localhost:8000/app-privacy-report/resources/cors-preflight.py?value=1234"
+PASS successfully loaded only app initiated requests
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/http/tests/app-privacy-report/app-attribution-cors-preflight-redirect.html (0 => 284819)


--- trunk/LayoutTests/http/tests/app-privacy-report/app-attribution-cors-preflight-redirect.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/app-privacy-report/app-attribution-cors-preflight-redirect.html	2021-10-25 20:24:45 UTC (rev 284819)
@@ -0,0 +1,56 @@
+<!DOCTYPE html><!-- webkit-test-runner [ isAppInitiated=true ] -->
+<html>
+<head>
+    <script src=""
+</head>
+<body _onload_="fetchAndRedirectWithCORSPreflightCheck()">
+<script>
+    description("Tests that CORS preflight checks for HTTP redirects are marked app initiated.");
+    jsTestIsAsync = true;
+
+    function log(message)
+    {
+        document.getElementById('console').appendChild(document.createTextNode(message + '\n'));
+    }
+    
+    function askForAttribution() {
+        var didLoadAppBoundRequest = testRunner.didLoadAppInitiatedRequest();
+        var didLoadNonAppBoundRequest = testRunner.didLoadNonAppInitiatedRequest();
+
+        if (didLoadNonAppBoundRequest) {
+            log("FAIL did load non app initiated request");
+            finishJSTest();
+            return;
+        }
+
+        if (!didLoadAppBoundRequest) {
+            log("FAIL did not load app initiated request");
+            finishJSTest();
+            return;
+        }
+
+        log("PASS successfully loaded only app initiated requests");
+
+        finishJSTest();
+    }
+    
+    var loadedUrl;
+    function fetchAndRedirectWithCORSPreflightCheck() {
+        fetch("http://localhost:8000/app-privacy-report/resources/redirect-with-cors-preflight-check.py",
+            {
+                headers: {
+                    "X-WebKit": "1234",
+                }
+            }
+        ).then(function(response) {
+            loadedUrl = response.url;
+            shouldBeEqualToString("loadedUrl", "http://localhost:8000/app-privacy-report/resources/cors-preflight.py?value=1234");
+            askForAttribution();
+        }).catch(function(error) {
+            testFailed(error.message);
+            finishJSTest();
+        });
+    }
+</script>
+</body>
+</html>

Added: trunk/LayoutTests/http/tests/app-privacy-report/resources/cors-preflight.py (0 => 284819)


--- trunk/LayoutTests/http/tests/app-privacy-report/resources/cors-preflight.py	                        (rev 0)
+++ trunk/LayoutTests/http/tests/app-privacy-report/resources/cors-preflight.py	2021-10-25 20:24:45 UTC (rev 284819)
@@ -0,0 +1,11 @@
+#!/usr/bin/env python3
+
+import os
+import sys
+from urllib.parse import parse_qs
+
+sys.stdout.write(
+    'Access-Control-Allow-Origin: http://127.0.0.1:8000\r\n'
+    'Access-Control-Allow-Headers: X-WebKit\r\n'
+    'Content-Type: text/html\r\n\r\n'
+)
Property changes on: trunk/LayoutTests/http/tests/app-privacy-report/resources/cors-preflight.py
___________________________________________________________________

Added: svn:executable

+* \ No newline at end of property

Added: trunk/LayoutTests/http/tests/app-privacy-report/resources/redirect-with-cors-preflight-check.py (0 => 284819)


--- trunk/LayoutTests/http/tests/app-privacy-report/resources/redirect-with-cors-preflight-check.py	                        (rev 0)
+++ trunk/LayoutTests/http/tests/app-privacy-report/resources/redirect-with-cors-preflight-check.py	2021-10-25 20:24:45 UTC (rev 284819)
@@ -0,0 +1,33 @@
+#!/usr/bin/env python3
+
+import os
+import sys
+
+if_none_match = os.environ.get('HTTP_IF_NONE_MATCH', None)
+if_modified_since = os.environ.get('HTTP_IF_MODIFIED_SINCE', None)
+
+sys.stdout.write('Content-Type: text/html\r\n')
+
+if if_none_match is not None or if_modified_since is not None:
+    sys.stdout.write('status: 500\r\n\r\n')
+    sys.exit(0)
+
+request_method = os.environ.get('REQUEST_METHOD', '')
+ac_request_method = os.environ.get('HTTP_ACCESS_CONTROL_REQUEST_METHOD', '')
+
+
+sys.stdout.write(
+    'Access-Control-Allow-Origin: http://127.0.0.1:8000\r\n'
+    'Access-Control-Allow-Headers: X-WebKit\r\n'
+)
+
+if request_method == 'OPTIONS' and ac_request_method == 'GET':
+    sys.stdout.write('\r\n')
+    sys.exit(0)
+
+header_string_value = os.environ.get('HTTP_X_WEBKIT', '')
+sys.stdout.write(
+    'status: 301\r\n'
+    'ETag: "WebKitTest"\r\n'
+    'Location: http://localhost:8000/app-privacy-report/resources/cors-preflight.py?value={}\r\n\r\n'.format(header_string_value)
+)
Property changes on: trunk/LayoutTests/http/tests/app-privacy-report/resources/redirect-with-cors-preflight-check.py
___________________________________________________________________

Added: svn:executable

+* \ No newline at end of property

Added: trunk/LayoutTests/http/tests/app-privacy-report/user-attribution-cors-preflight-redirect-expected.txt (0 => 284819)


--- trunk/LayoutTests/http/tests/app-privacy-report/user-attribution-cors-preflight-redirect-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/app-privacy-report/user-attribution-cors-preflight-redirect-expected.txt	2021-10-25 20:24:45 UTC (rev 284819)
@@ -0,0 +1,11 @@
+Tests that CORS preflight checks for HTTP redirects are marked non app initiated.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS loadedUrl is "http://localhost:8000/app-privacy-report/resources/cors-preflight.py?value=1234"
+PASS successfully loaded only non app initiated requests
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/http/tests/app-privacy-report/user-attribution-cors-preflight-redirect.html (0 => 284819)


--- trunk/LayoutTests/http/tests/app-privacy-report/user-attribution-cors-preflight-redirect.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/app-privacy-report/user-attribution-cors-preflight-redirect.html	2021-10-25 20:24:45 UTC (rev 284819)
@@ -0,0 +1,56 @@
+<!DOCTYPE html><!-- webkit-test-runner [ isAppInitiated=false ] -->
+<html>
+<head>
+    <script src=""
+</head>
+<body _onload_="fetchAndRedirectWithCORSPreflightCheck()">
+<script>
+    description("Tests that CORS preflight checks for HTTP redirects are marked non app initiated.");
+    jsTestIsAsync = true;
+
+    function log(message)
+    {
+        document.getElementById('console').appendChild(document.createTextNode(message + '\n'));
+    }
+    
+    function askForAttribution() {
+        var didLoadAppBoundRequest = testRunner.didLoadAppInitiatedRequest();
+        var didLoadNonAppBoundRequest = testRunner.didLoadNonAppInitiatedRequest();
+
+        if (didLoadAppBoundRequest) {
+            log("FAIL did load app initiated request");
+            finishJSTest();
+            return;
+        }
+
+        if (!didLoadNonAppBoundRequest) {
+            log("FAIL did not load non app initiated request");
+            finishJSTest();
+            return;
+        }
+
+        log("PASS successfully loaded only non app initiated requests");
+
+        finishJSTest();
+    }
+    
+    var loadedUrl;
+    function fetchAndRedirectWithCORSPreflightCheck() {
+        fetch("http://localhost:8000/app-privacy-report/resources/redirect-with-cors-preflight-check.py",
+            {
+                headers: {
+                    "X-WebKit": "1234",
+                }
+            }
+        ).then(function(response) {
+            loadedUrl = response.url;
+            shouldBeEqualToString("loadedUrl", "http://localhost:8000/app-privacy-report/resources/cors-preflight.py?value=1234");
+            askForAttribution();
+        }).catch(function(error) {
+            testFailed(error.message);
+            finishJSTest();
+        });
+    }
+</script>
+</body>
+</html>

Modified: trunk/Source/WebKit/ChangeLog (284818 => 284819)


--- trunk/Source/WebKit/ChangeLog	2021-10-25 20:15:02 UTC (rev 284818)
+++ trunk/Source/WebKit/ChangeLog	2021-10-25 20:24:45 UTC (rev 284819)
@@ -1,3 +1,25 @@
+2021-10-25  Kate Cheney  <katherine_che...@apple.com>
+
+        [App Privacy Report] CORS preflight requests attributed incorrectly
+        https://bugs.webkit.org/show_bug.cgi?id=232221
+        <rdar://problem/84116159>
+
+        Reviewed by Brent Fulgham.
+
+        HTTP redirects should already be marked as app-initiated or not based
+        on the NSURLRequest that initiated the redirect, either because the
+        same NSURLRequest is used or because it is set in the completion
+        handler of the networkDataTask->willPerformHTTPRedirection call in
+        NetworkSessionCocoa.
+
+        However, checking the request before calling the completion handler
+        can initiate CORS preflight checks that create loads that are incorrectly
+        marked for App Privacy Report. This patch sets the app initiated value
+        in the ResourceRequest object before the new NetworkDataTask is created to fix this.
+
+        * NetworkProcess/cocoa/NetworkDataTaskCocoa.mm:
+        (WebKit::NetworkDataTaskCocoa::willPerformHTTPRedirection):
+
 2021-10-25  Wenson Hsieh  <wenson_hs...@apple.com>
 
         REGRESSION (r284079): Audio continues playing on hulu.com in private browsing mode after closing the tab

Modified: trunk/Source/WebKit/NetworkProcess/cocoa/NetworkDataTaskCocoa.mm (284818 => 284819)


--- trunk/Source/WebKit/NetworkProcess/cocoa/NetworkDataTaskCocoa.mm	2021-10-25 20:15:02 UTC (rev 284818)
+++ trunk/Source/WebKit/NetworkProcess/cocoa/NetworkDataTaskCocoa.mm	2021-10-25 20:24:45 UTC (rev 284819)
@@ -519,6 +519,10 @@
     if (isTopLevelNavigation())
         request.setFirstPartyForCookies(request.url());
 
+#if ENABLE(APP_PRIVACY_REPORT)
+    request.setIsAppInitiated(request.nsURLRequest(WebCore::HTTPBodyUpdatePolicy::DoNotUpdateHTTPBody).attribution == NSURLRequestAttributionDeveloper);
+#endif
+
 #if ENABLE(INTELLIGENT_TRACKING_PREVENTION)
 #if HAVE(CFNETWORK_CNAME_AND_COOKIE_TRANSFORM_SPI)
     applyCookiePolicyForThirdPartyCNAMECloaking(request);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to