Bug 237350 - Web App Added to Home Screen Cookies Deleted After 7 Days
Summary: Web App Added to Home Screen Cookies Deleted After 7 Days
Status: NEW
Alias: None
Product: WebKit
Classification: Unclassified
Component: Website Storage (show other bugs)
Version: Safari 15
Hardware: iPhone / iPad iOS 15
: P2 Major
Assignee: Nobody
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2022-03-01 17:48 PST by ben
Modified: 2022-03-08 19:29 PST (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description ben 2022-03-01 17:48:49 PST
We have a PWA using a Service Worker, Application Cache and IndexedDB to provide offline functionality to our users. Our users are from a medium-size enterprise and they all have the app installed to Home. We have set the authentication cookie to expire after 28 days. It is set as Secure and Same-site: Strict. Our app display mode in the manifest is set to 'standalone'. This is an internal specialist app so some users may not have cause to access it regularly hence the longer expiry.

We deployed this app only a few months ago but we've recently had reports that the users are being asked to login again after only 7 days. We were able to confirm this on our iPhone 7 with iOS 15.3.

We're aware of the restrictions of 7 days on script writable storage for a web site opened in Safari but our users install the app to the Home screen. In our testing we opened our app 4 days out of 7 to check whether or not our user was still logged in and yet it still logged us out after only 7 days. The only thing we perhaps didn't do was tap around in the app when we opened it to check the login status. The app users would normally be completing activities in the app that would cause them to tap buttons etc. However we would expect that opening the app would mean that the counter should be reset to 0. Or is it that the user must actually interact with the app by tapping a button or completing an input field to count as a interaction?

Could you please also clarify for us, if the user doesn't use the installed app at all, i.e. they don't open it at all, for a period of 7 days will their app storage (IndexedDb, cookies etc.) be automatically deleted? Or should the data be safe based on this line "We do not expect the first-party in such a web application to have its website data deleted." from https://webkit.org/blog/10218/full-third-party-cookie-blocking-and-more/  ?
Comment 1 John Wilander 2022-03-02 10:21:23 PST
Hi! Thanks for filing. The only things that should be capped to 7 days for the main domain of Home Screen web apps are:
- Cookies created in JavaScript.
- Cookies created in 3rd-party CNAME-cloaked HTTP responses.

Non CNAME-cloaked server-set cookies and HTML storage should not be deleted for the main domain of Home Screen web apps.

Could you clarify exactly what is being deleted and if cookies, how they were created?
Comment 2 John Wilander 2022-03-02 10:23:03 PST
The blog post you're referring to is old. 

See "Home Screen Web Application Domain Exempt From ITP" in this more recent blog post which also explains 3rd-party CNAME cloaking: https://webkit.org/blog/11338/cname-cloaking-and-bounce-tracking-defense/

… or see our evergreen documentation here: https://webkit.org/tracking-prevention/#intelligent-tracking-prevention-itp
Comment 3 ben 2022-03-02 14:06:47 PST
Thanks for replying and supplying the updated blog posts. 

This now makes a bit more sense as the app is made with React and so we created the cookie on the client-side with Javascript and it is the cookie with the authorisation code that was deleted. 

However, the cookie domain is for the first-party domain of the app, i.e. the app is on app.mydomain.com and the cookie domain is set to mydomain.com, does that not mean that it should be exempt or does the fact that it was created with Javascript override this? 

Also, since the app was opened several times during the 7 day period, in my direct testing, shouldn't this have resulted in the cookie not being deleted? Or does there have to be an interaction to reset the ITP counter?
Comment 4 John Wilander 2022-03-02 14:46:39 PST
(In reply to ben from comment #3)
> Thanks for replying and supplying the updated blog posts. 
> 
> This now makes a bit more sense as the app is made with React and so we
> created the cookie on the client-side with Javascript and it is the cookie
> with the authorisation code that was deleted. 
> 
> However, the cookie domain is for the first-party domain of the app, i.e.
> the app is on app.mydomain.com and the cookie domain is set to mydomain.com,
> does that not mean that it should be exempt or does the fact that it was
> created with Javascript override this?

It doesn't since it's not ITP actively deleting the cookie but rather a policy that all script-written cookies are capped to a max 7-day expiry. It's the expiry mechanism of cookies.

> Also, since the app was opened several times during the 7 day period, in my
> direct testing, shouldn't this have resulted in the cookie not being
> deleted? Or does there have to be an interaction to reset the ITP counter?

Nope. Again, it's the expiry mechanism of the cookie. It works just like if you set the expiry to be 7 days. No other storage mechanism has an expiry which is why those are on a "7 days of browser use without user interaction" timer.

We are aware of the request to make script-written cookies use the "7 days of browser use without user interaction" timer too. Doing that requires extra infrastructure support since after a cookie has been created, there is nothing to distinguish a cookie created in JavaScript and one created by a server (except that only servers can create HttpOnly cookies which is in part why we always advice developers to set any sensitive cookies as HttpOnly).

Login cookies should always be HttpOnly, i.e. not be created or accessible by JavaScript. Script-accessible login cookies are a security anti-pattern since 1) they can be stolen through XSS, and 2) they cannot be kept outside the web content process where Spectre security attacks can happen.
Comment 5 ben 2022-03-02 15:14:52 PST
Ok, just confirming my understanding, the WebKit policy overrides/caps the expiry setting on all JS script-written cookies, no matter the domain or installed status of the app, to 7 days. So, if I create the auth token cookie from the server-side as HttpOnly and set expiry to say 28 days then this will be honoured? 

Then any other client-side cookies I have I should write this data into my IndexedDB database or localstorage to preserve them as these storage types have no explicit expiry date other than the 7 day non-interaction policy. Is this right? Or will they be preserved beyond 7 days as long as the app is installed to the Home screen?
Comment 6 Radar WebKit Bug Importer 2022-03-08 17:49:19 PST
<rdar://problem/90001326>
Comment 7 John Wilander 2022-03-08 19:29:50 PST
(In reply to ben from comment #5)
> Ok, just confirming my understanding, the WebKit policy overrides/caps the
> expiry setting on all JS script-written cookies, no matter the domain or
> installed status of the app, to 7 days. So, if I create the auth token
> cookie from the server-side as HttpOnly and set expiry to say 28 days then
> this will be honoured?

Yes.

> Then any other client-side cookies I have I should write this data into my
> IndexedDB database or localstorage to preserve them as these storage types
> have no explicit expiry date other than the 7 day non-interaction policy. Is
> this right? Or will they be preserved beyond 7 days as long as the app is
> installed to the Home screen?

You don’t have to but you can. In shipping software, there’s no cap on the expiry of server-set first-party cookies.

However, browsers have reached consensus on a ~400-day expiry cap on all cookies. I can only assume that the ~400-cap will in some form apply to HTML storage too. None of those caps are shipping though.