I'm currently working on a web application which sits inside an iframe for security purposes (protecting user data) and is hosted on other websites. To keep session state for insecure data, we write some data to local storage for user functionality i.e., remembering the user's background colour we save "backgroundColour" as "red".
However I have run into the following two issues on iOS Safari which currently work on MacOS Safari and Chrome and internet Explorer 11.
Issue 1: local storage is not retained when I force quit iOS
The user navigates to the host website, www.host.com, which loads my iframe content from a different domain, www.example.com
The user then interacts with the iframe and saves their background colour preferences which I save to local storage.
The user then force quits Safari or navigates away and then force quits Safari.
Navigate back to the host website
Expected behaviour: The localStorage contains the backgroundColour property
Actual behaviour: The local storage is empty
Issue 2: using the iframe content on different sites doesn't utilise local storage
The user navigates to the host website, www.host.com, which loads my iframe content from a different domain, www.example.com
The user then interacts with the iframe and saves their background colour preferences which I save to local storage.
The user navigates to www.awesomesite.com which also has my iframe content from the domain in step 1, www.example.com
Expected behaviour: The local storage is retained between the different sites because the storage is against DNS of the iframe
Actual behaviour: The local storage is empty
Has anyone experienced this before? Are there any workarounds that people have found? Is this a bug in iOS Safari? Have I done something wrong?
Cheers
Issue 1 is Safari behavior and cannot be changed externally with code. Please open a feature request or bug report with Apple:
https://www.apple.com/feedback/safari.html
Issue 2: Unfortunately, the technique you are using "3rd party local storage" is a technique employed by tracking technologies. The recent privacy push has led all browsers to make more strict rules for 3rd party cookies, and other local storage. You will find that privacy settings will make your user experience inconsistent. You cannot expect your local storage to be reliable when you are a 3rd party.
SEE:
Is there any workaround to set third party cookie in Iframe for safari?
AND
https://medium.com/#bluepnume/safaris-new-tracking-rules-and-enabling-cross-domain-data-storage-85241eea7483
AND
https://groups.google.com/forum/#!topic/mozilla.dev.platform/vm81cSx4teo
Related
Short:
I need help in SSO in Safari, I'm using iFrame and postMessage logic which is working fine in Chrome and Firefox (PC, Mac, Android and iOS) but the catch is in Safari. I tried Storage Access APIs and placed those in iFrame's onLoading event to check access. But the localStorage which I was used to store JWT is not persistent in the iFrame. I'm using Angular 11.
Scenario:
I'm developing few applications which uses same auth site for sso, which was working as expected as I said in short description. But when it comes to Intelligent Tracking Prevention enabled browsers as of now Safari, It blocks the iFrame by considering it as 3rd Party Trackers which is very insane since the iFrame's origin (Domain) is same with Sub-domain used in service sites.
I tried to check the access by using storage access API i.e hasStorageAccess() in window onLoad method in the iFrame's script. If has no access, I called requestStorageAccess(). I'm here not using user gesture and using button click from service site because I'm using angular for frontend framework but in order to request using button in iFrame.(Since, The policy specifies to get access works only after user interaction which is another headache for devs)
I need help to overcome this issue and fix the SSO with ITP. Any guidance is useful and I'll keep updated.
Google is working fine with their sso and services such as YouTube and Mail doesn't need login on every visit. Any idea on how they achieved.
The reason could be that Safari has the option "Prevent cross-site tracking" enabled by default and that can interfere with the SSO login and display of an embedded iframe (because it blocks some cookies).
Solution
Disable (uncheck) the option for "Prevent cross-site tracking" in the Safari configuration menu.
Tip: To achieve a better user experience, using Javascript you can detect when a user is using Safari and show him an HTML message explaining that he needs to disable that option in order to continue or use another browser like Chrome or Firefox.
I have a web app that uses a cookie as an access token (to let users stay logged in after refreshing/closing the site/app). It works perfectly on desktop but when I try to use it on my Android phone (installing it via Chrome), for some reason it says that I'm not logged in which means it wasn't able to load the access token.
Why is this happening? Is there a difference between how cookies are handled in the browser and when starting a PWA as a standalone?
Also two little side questions, 1, is there a way to debug a PWA that's added to the homescreen (using some sort of remote debugger) and 2, would it be a security risk to use localStorage for storing the access token instead of a cookie? I realize neither is particularly safe but I read that cookies are slightly better for this sort of thing. localStorage works just fine when starting as a standalone
After accessing a webpage with dynamic content, I use the "work offline" functionality of my web browser, and then I play around a bit with the page.
Later on, I turn back to mode "online" in my browser so that my changes can be appropriately stored in the corresponding server.
What can I do to "save" the information related to the webpage when working offline (so that I can close my browser or reboot my PC) and reopen it later (before turning back to "online" again?
Some extra information:
The page in question is a page provided by a remote Kallithea server.
For example, a similar context can be accessed via this link:
https://kallithea-scm.org/repos/kallithea/changeset/9e750b37b391af137aee703532082059ae6a3e25
Currently using Mozilla, but responses for any browser are welcome
You can save your data to the local storage using javascript.
You can also look into service workers if you have to intercept browser request (but they are not available in all browsers). Google also has a project called "Progressive Web Apps" to deliver offline functionality and faster load time: link.
The issue:
I have used github project of Ofir Dagan: Storing cross domain local storage.
It implements html5 local storage:
https://github.com/ofirdagan/cross-domain-local-storage
The problem:
Safari doesn't allow third party cookies by default (other browsers allow it).
Safari privacy preferences are:
The default is: "Allow from websites I visit".
I read about these settings:
Always Block - Block all first-party cookies and block all third-party cookies.
Allow from Current Website Only - Allow all first-party cookies and block all third-party cookies.
Allow from Websites I Visit - Allow all first-party cookies and block all third-party cookies unless that third party was a first party at one time (based on current cookies and browsing history).
Always Allow - Allow all first-party cookies and allow all third-party cookies.
Solution I have tried:
Local Storage with an iframe (pixel) - I think it's no longer works on Safari - Is there any workaround to set third party cookie in Iframe for safari?
I think that there is a way to share local storage between first party and third party sites on Safari. (Facebook.com and Booking.com share data between different domains).
I succeeded to achieve it by removing the API and writing it by myself, But I don't want to remove the API and implement it by myself (hope that there is a small fix in order to support Safari):
Iframe.html:
window.addEventListener('cors_event', function(event) {
if(event.event_id === 'my_cors_message'){
if (event.data.options.funcName == "SetItem") {
localStorage.setItem(event.data.options.key, event.data.options.value);
}
else if (event.data.options.funcName == "GetItem") {
return localStorage.getItem(event.data.options.key);
}
}
});
MainPage:
<iframe id="target" src="iframe.html" frameborder="1"></iframe>
<script>
var target = document .getElementById('target');
target.onload = function(){
target.contentWindow.postMessage('set', '*')
}
</script>
So does someone know how can I achieve it by changing some API logic to support Safari?
Any help appreciated!
As noted by the Cross-Storage library documentation:
Notes on Safari 7+ (OSX, iOS)
All cross-domain local storage access is disabled by default with Safari 7+. This is a result of the "Block cookies and other website data" privacy setting being set to "From third parties and advertisers". Any cross-storage client code will not crash, however, it will only have access to a sandboxed, isolated local storage instance. As such, none of the data previously set by other origins will be accessible. If an option, one could fall back to using root cookies for those user agents, or requesting the data from a server-side store.
It seems that the recent updates to the Safari browser (Prevent cross-site tracking) blocks any cookies from being generated when the Matomo domain doesn't match the website it's being loaded from.
This breaks the use of iFrames for Matomo that require cookies to be set (For example the logme feature)
There doesn't seem to be any way to fix this with headers (Eg using CSP or CORS configurations).
current workarounds exist that I've found:
Disable the "Prevent cross-site tracking" setting in the Privacy settings
Redirect the visitor to the page outside of an iFrame to set the cookie - after this the iFrame can load as long as the CORS configuration is correct and the browser isn't completely blocking the iFrame from loading.
I'm not sure how many users are using iFrames that would require cookies to be set, but they would be impacted if any of their users use Safari.
You may try Store.JS. As per the docs:
store.js exposes a simple API for cross browser local storage
I'm running into a major issue with Safari compatibility for my website. It's not an error per say, but apparently Safari classifies my website as 'third party'.
This means, that for me to set cookies (which is 100% necessary for my web app to run), the user needs to open up Safari preferences, click to 'Privacy' and opt-out of Safari's default setting. They need to set Safari's cookie policy from 'Block cookies from third parties' to 'Never block cookies'.
This is a terrible experience and means that probably most users who use Safari on my site will just navigate away because it's not working. I could pop up an info graphic to walk the user through the process, but come on... Most every other major browser (chrome, firefox, etc) takes an opposite stance and default to accepting all cookies.
Is there some application process to Apple that will get my website classified as 'first party'? Does it have something to do with SSL? Is it a CORS issue?
How do I get classified as a 'first party' website?
I think there is a conceptual misunderstanding here. A web site isn't first-party or third-party by itself, and there isn't some kind of list of these maintained by Apple. It is the third party in a specific context. When Safari blocks third-party cookies, what that means is that website www.aaa.com (the site the user is visiting) can't set (or retrieve) a cookie for www.bbb.com (a third party to the transaction between the user and www.aaa.com). I suspect you are doing something involving an iframe or otherwise including elements from one domain in a web page on another domain, and that is the source of the problem.