Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Intelligent Tracking Prevention #7

Open
twosatnams opened this issue Sep 26, 2017 · 6 comments
Open

Intelligent Tracking Prevention #7

twosatnams opened this issue Sep 26, 2017 · 6 comments

Comments

@twosatnams
Copy link

As you might be aware that Apple recently published a change to Safari that would affect this library. See this official Apple announcement for more details

I say it'd affect this library because you set a third-party cookie and then read from this cookie using an iframe to keep this id unique and consistent. Safari would make this cookie unavailable after 24 hours of setting it. So any user who visits the page using Safari with a gap of more than 24 hours would give us a different ID.

How do you plan to address it?

@lzhuor
Copy link

lzhuor commented Oct 9, 2017

Hi Satnam14, thank you for raising this question.

I have been using this library in production for about 2 months. Based on my observation and understanding of the source code, my website always reads third-party-cookie with this library and then convert it to a first-party-cookie in the callback to avoid your concern. I don't think webkit recognizes this approach as read/write of third-party-cookie as of today ( :

To be more specific:

  1. Let's assume we have site-marketing.com, site-app.com, site-cookie.com. site-marketing.com will check the existence of tracking.id cookie from site-cookie.com and set one if it doesn't exist. You would like to know if a user has visited site-marketing.com in the past 30 days when arriving site-app.com.
  2. When site-cookie.com receives the message of setting tracking.id cookie, you can let site-cookie.com convert tracking.id to a "first-party-cookie" using a callback. It can avoid tracking.id being considered as third-party-cookie by webkit. When site-app.com reads tracking.id from site-cookie.com, tracking.id is already a "first-party-cookie". Example code on site-cookie.com:
var isHttps = window.location.protocol==='https:';
var env = '<%= config.env %>';
var isDebug = env === 'development';
var iframeUrl = '<%= config.thirdPartyCookieDomain %>'
try {
  var xd_cookie = xDomainCookie( iframeUrl, 'site', true, 1000, isHttps, isDebug );
  xd_cookie.get('tracking.id', function(cookieVal) {
    // Write cookieVal as 1st party cookie
    document.cookie = 'tracking.id=' + cookieVal;
  }, 30, false );
} catch (err) {
  console.debug('xDomainCookie failed to set.');
}

@adrcal
Copy link

adrcal commented Mar 27, 2018

@Satnam14 We neither did not manage to get this library working for Safari. Our setup is as follows:

D1.com loads an iframe from I.com on which we set the cookie to allow us to go to D2.com that similarly loads an iframe from I.com and read data from the cookies set on I.com. This works on all browsers except on Safari with Intelligent Tracking Prevention turned on.

@lzhuor Does it still work for you ? If not, did you manage to implement a workaround?

Thanks!

@lzhuor
Copy link

lzhuor commented Apr 12, 2018

Hi @adrcal, sorry for the delay. I was busy having my wedding over last week.

Yes, it still works for us in the latest Safari/Chrome/Edge/Firefox. You can quickly testify it by:

Step 1: Go to https://www.stashaway.sg/referrals/zhuoranle629. Check your cookies, you should have a stashaway.voucher under domain www.stashaway.sg

Step 2: Then navigate to https://app.stashaway.com, you should find stashaway.voucher has been copied under domain app.stashaway.com

You can view the source code of app.stashaway.com (index: line 67 - 118) to debug our logic in the browser:

<script type="text/javascript">
    // loading function which ensures callback is invoked only after script (from url) is loaded
    function loadScript( url, callback ) {
        var script = document.createElement( "script" )
        script.type = "text/javascript";
        if(script.readyState) {  //IE
            script.onreadystatechange = function() {
                if ( script.readyState === "loaded" || script.readyState === "complete" ) {
                    script.onreadystatechange = null;
                    callback();
                }
            };
        } else {  //Others
            script.onload = function() {
                callback();
            };
        }

        script.src = url;
        document.getElementsByTagName( "head" )[0].appendChild( script );
    }

    // Load xDomainCookie and invoke setter callback for current domain
    loadScript("//www.stashaway.sg/xdomain_cookie.js", function() {
        var isHttps = window.location.protocol==='https:';
        var env = 'production';
        var isDebug = env === 'development';
        var iframeUrl = '//www.stashaway.sg'
        try {
            var xd_cookie = xDomainCookie( iframeUrl, 'stashaway', true, 1000, isHttps, isDebug );
            var d = new Date();
            d.setTime(d.getTime() + (30 * 1000 * 60 * 60 * 24));
            
            xd_cookie.get('stashaway.tid', function(cookieVal) {
                // Overwrite 1st party cookie from 3rd party cookie
                if (cookieVal !== null) {
                    document.cookie = 'stashaway.tid=' + cookieVal + '; expires=' + d.toUTCString();
                }
            }, 30, false );
            
            xd_cookie.get('stashaway.voucher', function(cookieVal) {
                // Overwrite 1st party cookie from 3rd party cookie
                if (cookieVal !== null) {
                    document.cookie = 'stashaway.voucher=' + cookieVal + '; expires=' + d.toUTCString();
                }
            }, 30, false );
            
        } catch (err) {
            isDebug && console.log('xDomainCookie failed to set.', err);
        }
        isDebug && console.log('xDomainCookies script is loaded and executed.');
    });
</script>

@adrcal
Copy link

adrcal commented Apr 12, 2018

Hi @lzhuor, I have to admit that's a really good reason for the delay in response :) Congrats!

Secondly, thank you for the code snippet, but the thing is that your described case is not in danger of Safari's ITP. Because the third party cookie that you are setting in the iframe is set on stashaway.sg which you actually visit.

In my specific case, the user does not visit I.com in the last 24 hours, so the library cannot read anymore the cookies set on I.com after that time period.

The only workaround we have at this moment is a quick redirect with js from D1.com to I.com and back from I.com to D1.com if the third party cookies are blocked. And this is not quite elegant.

It seems that Webkit's proposal is introducing a Storage Access API which probably would solve this issue More details on https://webkit.org/blog/8124/introducing-storage-access-api/

@lzhuor
Copy link

lzhuor commented Apr 12, 2018

Thank you!

I see the difference now. Will read and learn the webkit's proposal. Have fun!

@bvlgn
Copy link

bvlgn commented Jun 7, 2018

https://webkit.org/blog/8311/intelligent-tracking-prevention-2-0/
The 24 Hour Cookie Access Window will be removed in 2.0
And de redirect you suggested will be identified by ITP 2.0 as tracker behaviour.

Further more, they are proposing to other browser makers to add this as a standard:
whatwg/html#3338
I suggested a possible solution at that thread, but maybe there are betters solutions that would allow legitimate first party (cross site) while preventing undesired third party abuse? If you have any solutions in mind please suggest them at that thread: whatwg/html#3338

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants