Chrome extension for restoring cookies - javascript

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:
at extension startup (after browser has started) it downloads from a cloud service cookies already stored for some URLs.
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.
in chrome.webRequest.onBeforeRequest i do some checks if i have a session internally for given URL but nothing special here.
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)
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
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 :(

Related

On iOS, is there a way to detect a web page runs in the embedded browser and open the "real" one?

My web site uses magic links for login, however, I have a problem on mobile (not sure about Android - haven't tried yet, but the problem exists at least on iOS): when a user receives the email say in the GMail app, the link opens in the embedded browser, meaning that cookies will not be passed to the "real" browser.
Is there a way to ensure the link in the email opens in the real system browser and therefore cookies are stored permanently?
(Essentially browser session isolation on iOS breaks a lot of things on the Internet, so surely there is a workaround?)
After some research: no, it is not possible to detect you are in an embedded browser, neither is it possible to enforce opening a link in the system one. Makes sense from security point of view.
However, I was asking the wrong question. The problem of a magic link login is solved differently: when starting a login process you can set a session cookie and create an associated DB record for it, marking it as blocked, i.e. not logged in.
At next step, when the magic link is opened in whatever browser you unblock the session in the DB. At this stage you can replace the login cookie with a real one, e.g. JWT, or continue using it as your main auth token.
If the user then returns to the real browser, you check the login cookie and act accordingly, keeping in mind that it may not be the browser where they validated the magic link. At this stage you can, again, replace the login cookie with your real auth cookie knowing that the session has been validated already.
I'm not entirely sure this is 100% safe, need to think about it more but at first glance it does look safe and seems to be pretty much the only way of handling magic links on mobile.

Store sensitive information on the client side (Web)

I develop a website and I need to store a private key on the client side.
How to securely store this variable on the client side?
Can I use sessionStorage?
(I would like this (variable) information to be accessible only to the current user. As soon as he closes his browser, the data will have to be deleted.)
Thank you.
At a top level, yes, sessionStorage will do what you need. To quote MDN’s page on sessionStorage:
A page session lasts as long as the browser is open, and survives over page reloads and restores.
Opening a page in a new tab or window creates a new session with the value of the top-level browsing context, which differs from how session cookies work.
Opening multiple tabs/windows with the same URL creates sessionStorage for each tab/window.
Closing a tab/window ends the session and clears objects in sessionStorage.
There are several things to be careful of though. Firstly, any connection to the server would need to be done securely. This necessitates an HTTPS connection, probably with TLS 1.2 or 1.3 at this point.
Secondly, you’ll need to make sure that the page environment is clean. This means that you can’t load 3rd party JavaScript that could exfiltrate the private key. At an absolute minimum, any third party JS you load will need to be audited first and then have an integrity attribute added to make sure it doesn’t change.
Finally, you probably would want to add something to destroy the key after the user has finished using the page. This could be warning them to close the page after they’ve finished using the system, or something more automatic like retiring the key after x minutes and getting the system to negotiate a new one in time. Obviously there’s a balance here between security and usability, but the best systems can do this in a user-transparent way.

MSAL.js How to access SID received in other tab?

I'm trying to implement MSAL in a client side library, which works pretty well so far.
Now for my next steps I'm trying to add SSO by following the documentation at https://learn.microsoft.com/en-us/azure/active-directory/develop/msal-js-sso#automatically-select-account-on-azure-ad
In this documentation it is pointed out that I can add the sid claim to the auth requests, and reuse that sid in my second tab when logging in.
Now my main question is: what is the process to access the sid retrieved in tab A, and then re-use it in tab B?
I'll summarize for anyone else that is running into this sort of situation. The traditional way to store login tokens is in a cookie. This works fine for most scenarios- if the user tries to login to a different site on the same domain, the cookie is picked up. If they are signing in to a different domain, they will still need to visit the login page, but instead of entering their credentials they will simply be issued a new cookie for the new domain.
The question posed is for a special case when attempting to obtain a cookie on one tab, then using it on another tab without refreshing the page in the second tab. In this case, the token must be stored in local storage in order to be accessible to the code in the second tab immediately.

Office JS ui.displayDialogAsync loses session cookies when closed

I'm trying to build a Word add-on using the Office JS API that talks to an external web service (under my control).
I'm opening a dialog with ui.displayDialogAsync, which immediately redirects to the external server's login page (the redirect is to get around the same domain limitation).
When the user enters their login details correctly the server sends a session cookie back.
Unfortunately, in older versions of Word 2016, when the dialog is closed in Word, all session cookies are forgotten and any further requests sent to the web service from the add-on are rejected as no cookie is sent.
The problem exhibits itself in Volume licensed versions of Word 2016, but not in Office 365 versions of Word 2016, which seem to have a higher version / build number.
If I use Fiddler to view the requests / responses, I can see that the requests made from inside the dialog come from a different process ID to those made after the dialog closes.
I can't use persistent cookies for a combination of security reasons (once user closes the browser, the session needs to be terminated) and also persistent cookies seem to be shared with IE and we need to have independent sessions in IE and Word at the same time (some important state is stored in the cookie).
Has anyone else encountered this / know how to get around it.
The dialogs run in separate processes thats correct.
See for info: https://learn.microsoft.com/en-us/office/dev/add-ins/develop/dialog-api-in-office-add-ins
Note that:
"Store the information somewhere that is accessible to both the host window and dialog box. The two windows do not share a common session storage, but if they have the same domain (including port number, if any), they share a common local storage."
So option one: is to use local storage if you meet the requirements.
Option two: you could use a function called Office.context.ui.messageParent() to message your host (TaskPane) with a sessionId it needs to store and store it from the TaskPane
I see that starting with version 2107 build 14228.20250, dialogs opened from the Word desktop started sharing cookies with the sidebar automatically. I also checked it with Fiddler, now Word uses the same OS process to open a new dialog.

jQuery fallback when localStorage/sessionStorage is disabled

I have a REST based service architecture. One service is used to login users. A successful login request results in a auth_token sent back to the web client.
I would like to store the token in localStorage which is working fine in most situations. However it is possible that the user disables localStorage or the browser is in private mode (as far as I know only an issue on Safari).
My question is: Is there any concept I can use as a fallback when localStorage is not available?
Is storing the token in the window variable an option?
Any ideas are appreciated.
Checkout this link to find whether you have local storage enabled or not.
https://mathiasbynens.be/notes/localstorage-pattern
Also, for the fallback you can use cookies always. Or even if the cookies is not enabled, the only way to support is by URL param. Usually, in these cases people will show a warning message staing their Localstorage/Cookie should be enabled in order to work with their site. Hope it helps .
Alternatively, you can store in window.name which will be carried over on one browser tab; if you open the same page on anther tab it wont be available.

Categories