Bug 200857 - REGRESSION (iOS 13): WKWebView does not include cookies/credentials in cross-origin-requests
Summary: REGRESSION (iOS 13): WKWebView does not include cookies/credentials in cross-...
Status: NEW
Alias: None
Product: WebKit
Classification: Unclassified
Component: New Bugs (show other bugs)
Version: Safari Technology Preview
Hardware: iPhone / iPad Other
: P2 Major
Assignee: Nobody
URL:
Keywords: InRadar, Regression, WebExposed
Depends on:
Blocks:
 
Reported: 2019-08-17 02:09 PDT by Niklas Merz
Modified: 2019-09-11 03:28 PDT (History)
16 users (show)

See Also:


Attachments
Test app to reproduce issue (41.29 KB, application/zip)
2019-08-19 06:12 PDT, Niklas Merz
no flags Details
Updated demo app (43.38 KB, application/zip)
2019-08-21 06:19 PDT, Niklas Merz
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Niklas Merz 2019-08-17 02:09:51 PDT
Like discussed here: https://bugs.webkit.org/show_bug.cgi?id=140205 iOS 13 seems to have changed its cookie handling (/blocking).

HTTP requests to other origin done with JavaScript fetch and the option "credentials: 'include'" should send cookies like they did in iOS 12.

Some steps to reproduce:

1. Create an app which loads a webpage in WKWebView (I can add a sample later)
2. Open the console of the device running the app via Safari on Mac
3. Do a CORS-request with fetch: fetch("https://cors-test.appspot.com/test" {credentials: "include"})
4. Inspect the networks tab in developer tools
5. This request will work and contain a cookie (on cookies tab) with the "Set-Cookie test=test" HTTP header
6. Do the request again
7. The network request for the second request will not send the cookie

I could reproduce this with random pages opened in WKWebView and Safari on iOS 13. If you use Cordova your app will run on "ionic://localhost" and all HTTP requests to server will fail which means the app cannot login anywhere with cookies. If I call my test server the authentication fails and I can see in the network traffic with Wireshark that no cookie header is sent.

Disabling Cross-Site-Tracking in the Safari settings does not have an effect on iOS 13 for Safari or WKWebView. I think it did on iOS 12 for Safari in this case. Like https://bugs.webkit.org/show_bug.cgi?id=140205 said there is no API to set cookie policies on WKWebView.

Apps depending on session authentication with cookies need a fix or workaround for this to work on iOS 13. Especially Cordova Apps are in big trouble since the cannot communicate with any server at all.

Details will follow. Contact me for any questions.
Comment 1 John Wilander 2019-08-17 05:38:30 PDT
Cc’ing Youenn since this seems to be specific to Fetch.
Comment 2 Niklas Merz 2019-08-17 05:46:06 PDT
I should test XMLHttpRequest, too. I will report back!
Comment 3 Radar WebKit Bug Importer 2019-08-18 11:14:44 PDT
<rdar://problem/54445945>
Comment 4 Niklas Merz 2019-08-19 06:10:32 PDT
(In reply to Niklas Merz from comment #2)
> I should test XMLHttpRequest, too. I will report back!

fetch and XMLHttpRequest have this problem on iOS 13 beta.

> Details will follow. Contact me for any questions.

I created a small app which loads my testpage on Github (https://niklas.merz.dev/corstest) in WKWebView. The test app is attached to this bug report.

This page works with cookies in Safari and WKWebView on iOS 12. On iOS 13 beta in Safari and WKWebView the cookie is not sent after recieving it for the first time.

Steps to test:

Safari:
1. Open https://niklas.merz.dev/corstest in Safari on iOS/iPadOS 13
2. Open the console of this device via Mac Safari
3. Switch to the network tab
4. Click one of the buttons
5. Inspect the request -> No cookie should be sent, one cookie should be recieved, visibile on the cookies tab and the Set-Cookie header
6. Click the button again
7. On iOS 12 the cookie will be sent (Cookie header), on iOS 13 NOT!

NativeWebView - Testapp from attachments
1. Launche the app via Xcode on iOs 13 device
2. Inspect the webpage via Mac Safari
3. Just like iOS Safari the cookie will not be sent on iOS 13
Comment 5 Niklas Merz 2019-08-19 06:12:57 PDT
Created attachment 376682 [details]
Test app to reproduce issue

I can reproduce this issue in WKWebView with this minimal test app. The test page on https://niklas.merz.dev/corstest is also included.

This page does a cross origin request to https://cors-test.appspot.com/test which returns a cookie called test. This API echos the origin so this is a valid cors request.
Comment 6 Niklas Merz 2019-08-19 07:05:19 PDT
Another finding from testing this on Safari for Mac and the Safari cross-site-tracking

I used the testpage in Safari 12.1.2 and Safari 13 (Technology Preview). Both browser version don't send the cookie if the preference cross-site-tracking is enabled.

If cross site tracking is disabled the cookie works in Safari 12 and 13 on macOS.

In iOS 12 Safari the cross-site-tracking also blocks the cookie on the test page if enabled. I think this is ok and expected behavior. The cookie works if it is disabled.

Disabling cross-site-tracking on iOS 13 does not work. Cookies are blocked in Safari anyways.
Comment 7 youenn fablet 2019-08-19 12:07:09 PDT
> Disabling cross-site-tracking on iOS 13 does not work. Cookies are blocked
> in Safari anyways.

AIUI, the bug seems to be that cross-site tracking stays enabled even though it was disabled from Safari preferences.
Is that right? Is there anything specific related to WKWebView?
Comment 8 John Wilander 2019-08-19 12:18:23 PDT
(In reply to youenn fablet from comment #7)
> > Disabling cross-site-tracking on iOS 13 does not work. Cookies are blocked
> > in Safari anyways.
> 
> AIUI, the bug seems to be that cross-site tracking stays enabled even though
> it was disabled from Safari preferences.
> Is that right? Is there anything specific related to WKWebView?

I believe, ITP is a red herring here, Youenn. It has never been on outside Safari as far as I know. My hunch is that something in the rules around Fetch credentials has changed for the protocol or host they’re using, i.e. non-http(s) scheme and/or a host without TLD such as localhost.
Comment 9 Niklas Merz 2019-08-19 12:20:13 PDT
(In reply to youenn fablet from comment #7)
> > Disabling cross-site-tracking on iOS 13 does not work. Cookies are blocked
> > in Safari anyways.
> 
> AIUI, the bug seems to be that cross-site tracking stays enabled even though
> it was disabled from Safari preferences.

I was comparing WKWebView to Safari and iOS 12 to iOS 13. Safari seems to have the same bug as WKWebView that now cookies are always ignored.

> Is that right? Is there anything specific related to WKWebView?

The bug is about WKWebview dropping cookies from request on iOS 13 with no option to enable it. 

I am in trouble because our whole app runs in WKWebView and relies on cookies for authentication. WKWebView now does not handle cookies correctly, on contrast to iOS 12 where it did.
Comment 10 Niklas Merz 2019-08-19 12:57:23 PDT
(In reply to John Wilander from comment #8)
> (In reply to youenn fablet from comment #7)
> I believe, ITP is a red herring here, Youenn. It has never been on outside
> Safari as far as I know. 

You are probably right. Since iOS 13 Safari is not working as expected regardless of the ITP setting.

> My hunch is that something in the rules around
> Fetch credentials has changed for the protocol or host they’re using, i.e.
> non-http(s) scheme and/or a host without TLD such as localhost.

I can add that XMLHttpRequest is doing the same. I tested it on various origins like custom protocol localhost, IP and normal subdomains with HTTPS. As far as I know it happens regardless of the origin.

Did anyone try me test, yet? Would be good to know its not my fault and somebody else has the same issue.
Comment 11 Niklas Merz 2019-08-19 13:41:51 PDT
(In reply to Niklas Merz from comment #10)
To many typos here. Sorry for that. Let's try again:

> Did anyone try me test, yet? Would be good to know its not my fault and
> somebody else has the same issue.

Did anyone try my test page and project, yet? Would be good to know if it's not my fault and somebody else has the same issue.


(In reply to  youenn fablet from comment #7)
> AIUI, the bug seems to be that cross-site tracking stays enabled even though it was disabled from Safari preferences.
>Is that right? Is there anything specific related to WKWebView?

My comparison with Safari may let to confusion. Safari on iOS 13 is another topic. 
This report is only about the issue that cookies are not handled in WKWebView on iOS 13 beta. This looks like a regression.


(In reply to  John Wilander from comment #8)
>My hunch is that something in the rules around Fetch credentials has changed

This sounds very likely. I will start looking at the Webkit sources for changes, but navigating the codebase is hard from the outside.
Comment 12 Niklas Merz 2019-08-21 06:19:44 PDT
Created attachment 376870 [details]
Updated demo app

I've got new information from futher testing with my example. Please consider this while reproducing and fixing this bug.

The "cookies are not handled on first launch" bug still exists. This means you have to put the app in background and open it again before testing this after installing it via Xcode to get cookies working on iOS 12. This is a known bug on the Cordova community (https://github.com/imransilvake/Cordova-Plugin-Sync-Cookies https://github.com/Telerik-Verified-Plugins/WKWebView/issues/247 etc.), but I cannot find a Webkit bug. Is this worth a new one?

While testing a new device, I found that you have to set the cookie accept policy on the shared HTTPCookieStorage to make cookies work on iOS 12 aswell.
According to the docs this should be default: https://developer.apple.com/documentation/foundation/httpcookie/acceptpolicy/always . Is this a new bug?

I updated the project in the attachment accordingly. I need to set it once like this to get cookies working on iOS 12: 

```
let cookieStorage = HTTPCookieStorage.shared
cookieStorage.cookieAcceptPolicy = HTTPCookie.AcceptPolicy.always
```

iOS 13 is unaffected from these "workarounds" and does not send cookies at all. Is there another cookie setting that could have changed the default?
Comment 13 Benjamin Tietze 2019-08-21 23:53:57 PDT
Could the problem already be reproduced and will it be fixed in version 13?
If not, our customers can not update to version 13, as our software would no longer be able to run.
Comment 14 dima 2019-08-22 07:59:57 PDT
iOS 13 beta 7 breaks our application because cookies are not being returned to the server. We rely on cookies for session management. Hopefully it doesn't get released in current form because it will create massive issues for us.
Comment 15 youenn fablet 2019-08-23 03:58:12 PDT
I can repro the issue. This indeed seems like a regression.

One workaround is to load the request that triggers setting cookies as a main document.
Taking Niklas example:
1. load https://cors-test.appspot.com/test as main document. Cookies will be set.
2. load https://niklas.merz.dev/corstest
3. Do a cross-origin XHR/fetch, cookies should be included in the requests but response cookies will be discarded.

Not sure how practical this workaround is though.
Comment 16 Niklas Merz 2019-08-23 06:31:15 PDT
(In reply to youenn fablet from comment #15)
> I can repro the issue. This indeed seems like a regression.

Thank you very much for testing this. I'm really glad that this issue is confirmed.
 
> One workaround is to load the request that triggers setting cookies as a
> main document.
> Taking Niklas example:
> 1. load https://cors-test.appspot.com/test as main document. Cookies will be
> set.
> 2. load https://niklas.merz.dev/corstest
> 3. Do a cross-origin XHR/fetch, cookies should be included in the requests
> but response cookies will be discarded.
> 
> Not sure how practical this workaround is though.

This works indeed in the test app. For our app this is not practical. We trying  a couple of workarounds but a timely fix for this bug would be ideal.
Comment 17 Stephane 2019-09-06 02:50:42 PDT
I had the same problem with my ionic 3 app and ios 13.
I found workarounds using :

https://github.com/sneas/ionic-native-http-connection-backend

https://ionicframework.com/docs/native/http/#installation

By replacing the API calls from rxjs with the native objective C http call, the cookie persist well from the http response of the backend.
Comment 18 Niklas Merz 2019-09-06 03:04:14 PDT
(In reply to lordsteph84 from comment #17)
> I had the same problem with my ionic 3 app and ios 13.
> I found workarounds using :
> 
> https://github.com/sneas/ionic-native-http-connection-backend
> 
> https://ionicframework.com/docs/native/http/#installation
> 
> By replacing the API calls from rxjs with the native objective C http call,
> the cookie persist well from the http response of the backend.

Thank you for pointing that out for Cordova/Ionic developers.

Regardless this is still a workaround and doing HTTP in the browser should work as expected. I would be happy to remove any workarounds, when this issues gets fixed.
Comment 19 Alexey Proskuryakov 2019-09-09 15:57:23 PDT
Could you please elaborate on end user impact of this problem? What are the popular apps that have important functionality broken because of this regression?

Please feel free to e-mail me directly if you would prefer not to mention those publicly.
Comment 20 dima 2019-09-10 00:08:51 PDT
(In reply to Alexey Proskuryakov from comment #19)
> Could you please elaborate on end user impact of this problem? What are the
> popular apps that have important functionality broken because of this
> regression?

Whatsapp, Twitter, FaceBook, Goldman Sacks App..?

What difference doesn't it make the popularity or importance of the app?
It breaks our mobile app because we rely on session cookies. It will break any other app which does the same. If server complies with request and provides all necessary headers according to the spec the client must fulfill it's part. Or reject the response and raise the error.

The impact of not doing this is that the developer will have to replace the entire mechanism of session management on the server side or fork and fix this bug themselves.
Comment 21 Alexey Proskuryakov 2019-09-10 09:29:32 PDT
> Whatsapp, Twitter, FaceBook, Goldman Sacks App..?

Please provide steps to reproduce with these apps, or any shipping apps at all. Please be very precise, as I haven't seen related reports of broken functionality in these particular apps.

> What difference doesn't it make the popularity or importance of the app?

User impact is one of the most important factors for prioritization. The question is not whether this issue needs to be investigated and fixed, but whether users are so severely impacted that this issue needs to be prioritized. Typically, broken functionality in popular apps is the easiest way to demonstrate the impact. Breaking  many non-top apps is also not OK, but please realize that we know of exactly zero specific impacted apps at the moment.

It is doubly important to clearly state the user impact because even after a bug like this is fixed, all companies that use WebKit will need to decide whether to expedite shipping the fix to customers as part of their products.
Comment 22 Yordan Bonev 2019-09-11 03:28:57 PDT
We have exactly same issue with our app and cookie authentication. Not working only on iOS 13