apache / cordova-android

Apache Cordova Android
https://cordova.apache.org/
Apache License 2.0
3.59k stars 1.52k forks source link

Ready for Chrome 80's [Cookies default to SameSite=Lax] ? #850

Closed meishier closed 1 year ago

meishier commented 4 years ago

I noticed warnings in my chrome debug console,

A cookie associated with a cross-site resource at http://xxx.xxx.xxx.xxx/ was set 
without the SameSite attribute. A future release of Chrome will only deliver cookies
 with cross-site requests if they are set with SameSite=None and Secure. You can review 
cookies in developer tools under Application>Storage>Cookies and see more details at 
https://www.chromestatus.com/feature/5088147346030592 and 
https://www.chromestatus.com/feature/5633521622188032.

After some digging by google, I tested

  1. add cookie header [SameSite=Lax] on server
  2. run my cordova android application.
  3. my application does not work for authenticated user, because cookie JSessionId is not sent to server any more. (we send cookie to server from local html file's webview by ajax or xhr)

Actually chrome tell us we should set SameSite=None+Secure for cookie in Chrome 80, and that's a solution precisely. But for some reason, we can not do that. According to Apple's WkWebview Bug 198181 - Cookies with SameSite=None or SameSite=invalid treated as Strict , the fix is only for 10.15 and iOS 13 and later ver, and that means, If we set SameSite=None+Secure on server, our iOS application will not work also for iOS 12 and before ver.

Is there any other simple solution to deal with our situation? any suggestions will be greatly appreciated.

ref: https://textslashplain.com/2019/09/30/same-site-cookies-by-default

breautek commented 4 years ago

This sounds like a difficult problem because afaik you can't disable the policy on the android webview.

I'm not sure if the current cordova webview uses the CookieManager class, or if it already does this or not, but maybe using setAcceptThirdPartyCookies will disable the same cookie site policy without having to specify SameSite=None?

meishier commented 4 years ago

@breautek thanks. From the source SystemCookieManager, CookieManager is still in use, setAcceptThirdPartyCookies is called already.

you're right, seems it's not possible to modify webview's flags either.

breautek commented 4 years ago

I'll add the help wanted tag to this issue. Someone will need to investigate potential solutions. The browsers have been implementing a lot of security features that makes it hard for web apps to run off of the filesystem.

But I'm not entirely confident this is something that can be solved at the client side level. Something like this might require a backend hack to make it send the appropriate header if the request is from chrome only.

meishier commented 4 years ago

I found a way to get through.

get cookie by native http request, and set the cookie(SameSite modified) back to webview.

I did simply tested, using cordova-plugin-advanced-http and cordova-cookie-master, and it does work on android/iOS both with specifying SameSite=Lax.

If there is a way to solve the problem by cordova-android package(such as set config(inject cookie or something else) in config.xml), and that will really be a graceful solution.

I'm not sure cordova-cookie-master will still work or not on chome 80, so I'll test it again after chrome 79 beta's release on googleplay store.

MBoberski commented 4 years ago

I found a way to get through.

get cookie by native http request, and set the cookie(SameSite modified) back to webview.

I did simply tested, using cordova-plugin-advanced-http and cordova-cookie-master, and it does work on android/iOS both with specifying SameSite=Lax.

If there is a way to solve the problem by cordova-android package(such as set config(inject cookie or something else) in config.xml), and that will really be a graceful solution.

I'm not sure cordova-cookie-master will still work or not on chome 80, so I'll test it again after chrome 79 beta's release on googleplay store.

Can you give exacly code for this fix?

MBoberski commented 4 years ago

@meishier

Steenkuyl commented 4 years ago

Yes I am curious as well. Why do you need both the plug-ins?

meishier commented 4 years ago

@MBoberski I'm afraid to say I can not do that because of company's network security restrictions.

@Steenkuyl cordova-plugin-advanced-http is for reading cookie from native-http at login page, cordova-cookie-master is for setting back cookie to webview. And after that, any page can use cookie freely regardless of what SameSite is.

meishier commented 4 years ago

@breautek

good news for cordova android app(webview). The new SameSite behavior will not be enforced on Android Webview until later.

https://www.chromium.org/updates/same-site

Last updated Dec 16, 2019. The new SameSite behavior will not be enforced on Android Webview until later, though app developers are advised to declare the appropriate SameSite cookie settings for Android WebViews based on versions of Chrome that are compatible with the None value, both for cookies accessed via HTTP(S) headers and via Android WebView's CookieManager API. This does not apply to Chrome browser on Android, which will begin to enforce the new SameSite rules at the same time as the desktop versions of Chrome. The new SameSite behavior will not affect Chrome on iOS.

breautek commented 1 year ago

SameSite will now be enforced on API 31 devices.

Starting in API 31 on Android 12 devices, Google has started enforcing SameSite policies for WebView cookies.

Cordova cannot override this policy.

Personally I don't use cookies so I'm not totally familiar with the SameSite policies but they have a guide that should be able to help. It may involve making changes to your server.

https://github.com/apache/cordova-android/issues/1417#issuecomment-1129514787

However, Cordova cannot override this policy. May require server changes to satisfy SameSite rules, or you may have to stop using cookies for Cordova-based apps.

For this reason, I'm closing this issue as won't fix.

customautosys commented 1 year ago

SameSite will now be enforced on API 31 devices.

Starting in API 31 on Android 12 devices, Google has started enforcing SameSite policies for WebView cookies. Cordova cannot override this policy. Personally I don't use cookies so I'm not totally familiar with the SameSite policies but they have a guide that should be able to help. It may involve making changes to your server.

#1417 (comment)

However, Cordova cannot override this policy. May require server changes to satisfy SameSite rules, or you may have to stop using cookies for Cordova-based apps.

For this reason, I'm closing this issue as won't fix.

Hi I believe the situation is now more severe with API 31. I've just tried it and my app which works on API 30 cannot work on API 31 at all due to this issue. I can't modify the server which I'm accessing through CORS as I don't have access to that server. On Electron I am able to access the response to forcibly add SameSite=None; Secure to every single cookie but for Cordova there doesn't seem to be a way to do this. I'm wondering if there's a way to override shouldInterceptRequest for the Cordova webView for people who need this fix. However, it seems that shouldInterceptRequest doesn't work for AJAX requests but only page loads?

stjfk commented 1 year ago

I found a way to get through.

get cookie by native http request, and set the cookie(SameSite modified) back to webview.

I did simply tested, using cordova-plugin-advanced-http and cordova-cookie-master, and it does work on android/iOS both with specifying SameSite=Lax.

If there is a way to solve the problem by cordova-android package(such as set config(inject cookie or something else) in config.xml), and that will really be a graceful solution.

I'm not sure cordova-cookie-master will still work or not on chome 80, so I'll test it again after chrome 79 beta's release on googleplay store.

were you able to provide a solution for this issue? any example code?

breautek commented 1 year ago

A better solution than proposed here is probably to use SameSite=None; Secure when setting your cookies. This would be a server side change.

If you aren't already using the schemes stuff on Android, you must also use the https:// scheme for the "secure" context. This is the cordova android default since cordova-android 10, unless you have AndroidInsecureFileModeEnabled preference enabled.

A cordova environment is always considered cross origin and chromes default switched away from None to Lax. Which is the cause of the issue.

customautosys commented 1 year ago

A better solution than proposed here is probably to use SameSite=None; Secure when setting your cookies. This would be a server side change.

If you aren't already using the schemes stuff on Android, you must also use the https:// scheme for the "secure" context. This is the cordova android default since cordova-android 10, unless you have AndroidInsecureFileModeEnabled preference enabled.

A cordova environment is always considered cross origin and chromes default switched away from None to Lax. Which is the cause of the issue.

The problem is that we cannot always do a server side change. Some of us do not own the server we are targeting via CORS (e.g. scraping from another site).

Is there a way to route the AJAX requests through cordova-plugin-advanced-http and cordova-cookie-master? The problem I'm facing is that I have a lot of cross platform code (e.g. on electron and chrome extension) that relies on axios and I don't want to rewrite everything to use cordova-plugin-advanced-http separately for cordova. If there could be a drop in replacement that would be great.

breautek commented 1 year ago

Is there a way to route the AJAX requests through cordova-plugin-advanced-http and cordova-cookie-master?

I'm not familiar with how these plugins work but you'll likely have to build your own abstraction. You might be able to overwrite the underlying XMLHttpRequest object on the browser to provide a different implementation that communicates with those plugins instead, but I'm not sure if that will work. Sometime native browser features aren't overwritable. It's possible you'd also have to overwrite the native fetch api as well, depending on what axios actually uses.

The problem is that we cannot always do a server side change. Some of us do not own the server we are targeting via CORS (e.g. scraping from another site).

This can usually be worked around by having your own endpoint that you can control that proxies to the endpoint you want to target. CORS and cookies is a browser concept, so it only applies when using the browser's http features. So you'll need to configure your server accordingly for your clients, but the request from your own server to the target endpoint will not be restricted by CORS or Cookies SameSite policies. However, if the server you do not control have restrictive policies, it could be that they don't want you from hitting their endpoint(s) in the first place.

customautosys commented 1 year ago

Is there a way to route the AJAX requests through cordova-plugin-advanced-http and cordova-cookie-master?

I'm not familiar with how these plugins work but you'll likely have to build your own abstraction. You might be able to overwrite the underlying XMLHttpRequest object on the browser to provide a different implementation that communicates with those plugins instead, but I'm not sure if that will work. Sometime native browser features aren't overwritable. It's possible you'd also have to overwrite the native fetch api as well, depending on what axios actually uses.

The problem is that we cannot always do a server side change. Some of us do not own the server we are targeting via CORS (e.g. scraping from another site).

This can usually be worked around by having your own endpoint that you can control that proxies to the endpoint you want to target. CORS and cookies is a browser concept, so it only applies when using the browser's http features. So you'll need to configure your server accordingly for your clients, but the request from your own server to the target endpoint will not be restricted by CORS or Cookies SameSite policies. However, if the server you do not control have restrictive policies, it could be that they don't want you from hitting their endpoint(s) in the first place.

Not asking for any change to be made to Cordova as I know it has to use the upstream webview from Android, but does anyone know of any alternative webview we can use to overcome the SameSite problem? I tried a number of Crosswalk and X5 WebView plugins, but they all did not work.

customautosys commented 1 year ago

Is there a way to route the AJAX requests through cordova-plugin-advanced-http and cordova-cookie-master?

I'm not familiar with how these plugins work but you'll likely have to build your own abstraction. You might be able to overwrite the underlying XMLHttpRequest object on the browser to provide a different implementation that communicates with those plugins instead, but I'm not sure if that will work. Sometime native browser features aren't overwritable. It's possible you'd also have to overwrite the native fetch api as well, depending on what axios actually uses.

The problem is that we cannot always do a server side change. Some of us do not own the server we are targeting via CORS (e.g. scraping from another site).

This can usually be worked around by having your own endpoint that you can control that proxies to the endpoint you want to target. CORS and cookies is a browser concept, so it only applies when using the browser's http features. So you'll need to configure your server accordingly for your clients, but the request from your own server to the target endpoint will not be restricted by CORS or Cookies SameSite policies. However, if the server you do not control have restrictive policies, it could be that they don't want you from hitting their endpoint(s) in the first place.

I have solved my problem!

https://github.com/customautosys/axios-cordova-adapter

Also did a small bug fix to cordova-plugin-advanced-http: https://github.com/customautosys/cordova-plugin-advanced-http-redirect-fix https://github.com/silkimen/cordova-plugin-advanced-http/pull/501