Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Cordova App with IFrames Chrome 63 No Request Headers Cookies

Since the release of Chrome 63 on Android, on the 6th December 2017, I have encountered a problem with my companies Cordova based Android app. This app includes IFrames that allow users to navigate parts of my companies eCommerce website from within the app.

The navigation between pages loaded in the IFrames no longer send any cookie information in the Request Headers.

Information such as Session Ids that are stored in a cookie are not passed across to the next page, which in turn causes the next page to start a whole new user session!

What is strange however is that any AJAX calls preformed within a page on the IFrames (e.g. To retrieve the number of items in the basket) and asset requests (css js, image files etc) do send cookie information in the request headers fine. The session id in these headers are identical between pages, indicating session persistence.

Cookies are being created ok and I can see them when using the Chrome developer tools within the Application panel under the companies domain. They just aren't being passed to the next page.

I experienced this issue on an Android 7.1.1 device. When I disable the Chrome app on this device the cookie request headers in the IFrames in the app begin to work fine again, presumably the Cordova Webview is no longer using Chrome when it is disabled?

Does anyone know what may be causing this issue? Could it be anything related to SameSite cookies or Strict site isolation changes or other security related changes in Chrome 63?

The issue appears similar to this Chromium bug that was fixed October 2016: https://bugs.chromium.org/p/chromium/issues/detail?id=634311

The Webview does however have ThirdParty cookies enabled in the SystemCookieManager class of the Cordova library (Cordova Android 6.4.0):

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    cookieManager.setAcceptThirdPartyCookies(webView, true);            
}

Apologies if I haven't specified anything clearly enough. I'm happy to provide additional information if anyone can help with this issue.

like image 279
user1491571 Avatar asked Dec 09 '17 18:12

user1491571


2 Answers

This bug was filed and addressed in the Chromium Bug tracker. According to the Chromium devs, there's nothing we can do from the App side of things.

like image 98
Gregor Schmidt Avatar answered Nov 11 '22 20:11

Gregor Schmidt


Here is a way to reproduce the issue without Cordova. It uses http://httpbin.org/cookies/set?k2=v2&k1=v1 to test cookies. With Android System WebView v. 63 the cookies are not sent. With previous versions they are sent. I hope it can help to find the answer to the question. Here is a link to the full Android project: https://www.dropbox.com/s/s53wfy71uou11rh/test-webview.zip?dl=0

MainActivity.java

package com.example.mihai.twv;

import android.os.Build;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.webkit.CookieManager;
import android.webkit.WebView;

import java.io.InputStream;

public class MainActivity extends AppCompatActivity {

    WebView mWebView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initWebView();
        loadWebView();
    }

    private void initWebView() {
        mWebView = (WebView) findViewById(R.id.webView);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            WebView.setWebContentsDebuggingEnabled(true);
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            CookieManager.getInstance().setAcceptThirdPartyCookies(mWebView, true);
        }
    }

    private void loadWebView() {
        String url = "http://httpbin.org";
        String html = getLocalFileContents("html/main.html");
        mWebView.loadDataWithBaseURL(url, html, "text/html", "UTF-8", null);
    }

    private String getLocalFileContents(String filepath) {
        String response = "";

        try {
            InputStream is = getAssets().open(filepath);
            int size = is.available();

            StringBuilder builder = new StringBuilder();

            byte[] buffer = new byte[size];
            while (is.read(buffer) != -1) {
                builder.append(new String(buffer, "UTF-8"));
            }
            is.close();
            response = builder.toString();
        } catch (Exception e) {
        }
        return response;
    }
}

html/main.html (in assets folder)

<html>
<head>
    <base href="file:///android_asset/html/">
    <link type="text/css" rel="stylesheet" href="../css/main.css" />
</head>
<body>
    <iframe src="http://httpbin.org/cookies/set?k1=v1&k2=v2" frameborder="0"></iframe>
</body>

css/main.css (in assets folder)

html,
body,
iframe {
  width: 100%;
  height: 100%;
}
like image 2
mihai1990 Avatar answered Nov 11 '22 22:11

mihai1990