0

I am working on a google chrome extension that takes-over control of Chrome's cookie management, and instead, my extension should manage the cookies.

What I did is the following:

  1. at extension startup (after browser has started) it downloads from a cloud service cookies already stored for some URLs.
  2. chrome.webNavigation.onCreatedNavigationTarget - here i establish (for given URL) if my extension will manage the cookies or not. If yes, I mark some internal variables to establish something like an "internal session". If I already have cloud-cookies for this URL, then I set them in the session variable, to be later used. If not, the session variable is simply initialized with blank data.
  3. in chrome.webRequest.onBeforeRequest i do some checks if i have a session internally for given URL but nothing special here.
  4. in chrome.webRequest.onBeforeSendHeaders - here is where i set the cookie header with what exists internally in the session variable (which is either something restored from cloud or the cookies received via set-cookie from the website)
  5. in chrome.webRequest.onHeadersReceived i overwrite any already existing internal cookies (if any) with whatever new data was received from the website (via the set-cookie headers), so all future requests are updated
  6. either when browser is idle or when the user closes the tab, cookies get uploaded to cloud-service, so later they can be restored.

Besides the above simplistic description that I mentioned, there's also a content script that runs from the extension's codespace, which injects and executes a javascript on the URL in order to override document.cookie setter and getter, in order to pass the cookies managed from background script to content area and viceversa (there's some communication between the 2 "channels", cookies get updated back and forth)

Things apparently work. I navigate to a URL, login with some credentials, cookies are handled/passed etc. I then close the tab, verify the cookies where sent to cloud-service, then restore the tab (via reopen previously closed tab) and test if navigation is still possible - and it is and is still managed by the background script, etc. Also verified by debugg inspector (navigated to application - storage - cookies) confirmed there are no cookies at all inside the browser. Even executing document.cookie from console, shows that there are some cookies being used, etc.

However, the last testing scenario, where i close the browser, reopen it... so it fetches the cookies again from the cloud service. At the point when I navigate again to URL-1, i see from my internal logging that:

  • the session has been created at step 2
  • at step 4 (onBeforeSendHeaders) cookies get added to request-headers like i expected, i then confirm this in Navigation-inspector by inspecting various requests to see if the cookies have been sent or not, etc.
  • But at the first onHeadersReceived i see that the cookies "have not been accepted" and they already been overwritten, like they never existed before... (obviously, I'm being asked again to login/etc) - totally not what I expected. It behaves like the request contained no cookies at all initially. (if then i login again... all navigation works great... all until i reopen the browser again).

What would you guys believe that could be the cause for this behavior? I'm not an expert on how cookies get stored/passed/etc :(

Sebi O.
  • 23
  • 6
  • 1
    Extension's background script is delayed at browser startup so it can't intercept those first requests made in the opening tabs, especially the active tab. The only solution is to use chrome.declarativeNetRequest's updateDynamicRules to either add the rules for cookies or just block everything by default and then unblock using updateSessionRules when the extension finally starts. – wOxxOm Feb 14 '23 at 10:32
  • In chrome.webNavigation.onCreatedNavigationTarget i actually first load a static HTML page, start a method to prepare the session and then with a timeout i update the tab's url to user's final destination URL. Shouldn't this approach overcome the delay you're talking about? Literally what I do is: 1. chrome.tabs.update(tabId, staticURL); then prepare the session and last chrome.tabs.update(tabId, originalDestinationURL) – Sebi O. Feb 14 '23 at 13:45
  • 1
    Your extension is not running at the early stages of browser startup, i.e. the background script is not running yet, the JS listeners aren't running yet. When the background script starts it will never see those early events like they never happened. – wOxxOm Feb 14 '23 at 14:17
  • The extension actually runs in a fork of Chrome that I built myself. In NewTabPage of chrome i display a list of URLs that the end-user will open, URLs that are later handled by this extension (for cookies management). So basically... i am sure (i guess) that everything was loaded already at browser startup, all should be ok, no? – Sebi O. Feb 14 '23 at 15:30
  • I just inspected a bit SessionBox extension. In their manifest file, there is nothing related to declarative_net_request and yet, they have a feature called "sharing session" which allows one user to share a website's session with some other user. As I've tested their extension for a bit, they also show a temporary page before actually loading the destination-website, etc... how comes that it works for them? There must be something that I'm missing, right before my eyes... – Sebi O. Feb 15 '23 at 04:02
  • 1
    They have `"permissions": ["background"]` which keeps the extension running when the browser window is closed. It's fragile though because the user can close the Chrome process in the shell tray. – wOxxOm Feb 15 '23 at 04:55
  • @wOxxOm - maybe you can take a quick look at [link](http://camerolla.com/session-helper.png) and let me know what you think? – Sebi O. Feb 15 '23 at 20:00
  • 1
    A site's service worker may return a cached response for the page, which won't be reported to webRequest or declarativeNetRequest because this request doesn't reach the network layer. There's no good solution. The only workaround is to unregister the site's service worker and clear its cache using chrome.browsingData API ([example for MV3](https://stackoverflow.com/a/74823389), just remove await in MV2). – wOxxOm Feb 15 '23 at 20:47
  • I believe I've discovered my issue, remains to test this... it seems that some sites invalidate cookies based on things saved in LocalStorage... so I'd have to sync also the local storage data of websites (if possible) and not only the cookies/etc. Remains to test if I can do this and how :) many thanks! – Sebi O. Feb 16 '23 at 08:38
  • I confirm this was the issue. Now I also store storage data to the cloud-service and restore it back when needed, all works ok as far as I tested. Many thanks @wOxxOm for all your input, was eyes opening! I owe you at least a coffee but till this will be possible, wish you all the best! – Sebi O. Feb 16 '23 at 15:25

0 Answers0