Sharing localstorage between iframe and website being shown in iframe - javascript

I have a website example.com. example.com is embeded in an iframe on example2.com. I fill in some data in the iframe, this data is saved in localstorage on example.com.
Now if i navigate to examle.com, this data persists. Meaning it is sharing localstorage with the iframe, which makes sense because it is the same website, however, this only works in chrome, in firefox and safari, the data does not persist.
So to be clear, i dont want to share data between example.com and example2.com i just want the localstorage to persist on example.com regardless of it being in an iframe or being accessed directly.
Thanks

LocalStorage is intended to store data on client's browser and, because of this, stored data are equated to third-party cookies when saved by resources coming from external domains.
Currently (Jan 2022) browsers are dropping support (in terms of both availabilty and durability) of third-party cookies and you probably should expect Chrome will behave in the same way in the near future (see here).

Related

Cross domain local storage using iframes - "Block third-party cookies"

There are already a few questions related to using the local storage with iframes to be able to share data across different domains. However, none of them addresses the issue when the "Block third-party cookies" is enabled.
Currently, by default now Chrome uses the option "Block third-party cookies in Incognito" which breaks the localStorage use within iframes whenever you use the incognito mode.
Is there any workaround for this problem? We're using post message to send the data for the iframe.
The behavior you are describing sounds exactly like the pattern of behavior the Third-Party Cookie Block is intended to prevent.
There have been numerous changes in Chrome (and other browsers) regarding cookies and iframe.
The basics of what is changing is there is now a 'SameSite' cookie policy, where Only cookies set as SameSite=None; Secure will be available in third-party contexts, provided they are being accessed from secure connections.
Also in safari, the third-party frame will have to request access to the storage API before the cookie will be accessible.
Firefox is using a partitioned approach to the storage, and so the frame will behave as normal unless you then open your application as a new window then the cookie store may or may not follow depending on how the new window was created.
Cookie Status is an excellent resource to track how third party cookies work in the different browsers and what you should change to make it work.
I want to add my two cents here because all replies to this question completely miss the point of what's being asked. Take what I have here with a grain of salt, it's based on the most recent versions of Chromium and my personal experience, but maybe it can help someone understand the mess Chromimium has made.
Obscure Chromium Setting
First and foremost the setting within Chromium applications does not explicitly state that local storage or anything regarding "data" will be impacted by "blocking third-party cookies".
Ironically this setting used to actually explain that third-party cookies and data would be blocked, but in recent versions no longer mention data anymore, just cookies.
Is local storage a Cookie?
No. Local storage has nothing to do with cookies, and therefore the option for "blocking third-party cookies" is disingenuous because it lacks describing that local storage will also be blocked.
Local Storage data is stored by the browser for a particular domain. This data is not shared or exposed in any way.
So does local storage have "third-party data"?
No, there is also nothing "third-party" about local storage.
In context of cookies, a "third-party cookie" is a cookie for a domain that was created by a different domain, hence being "third-party". This allows domains to inject data into cookies that get sent to a different domain, which could be useful if you want to let that other domain know something, though this could also become nefarious. This essentially was a way of two domains to have a communication channel based on the user's session, but it becomes a privacy concern because it enables these domains to communicate in context of the user.
What does "third-party" mean for local storage? Nothing. Local storage is bound to the domain that's accessing the storage object - there is no "third-party" mechanism when setting or retrieving data from local storage since it is always in context of the window frame where the code is executing.
This further exasperates the problem: Why does "blocking third-party cookies" prevent local storage which is neither "third-party" nor a "cookie"?
So what does this setting do to local storage?
The "block third-party cookies" setting will block, as the name suggests, third-party cookies, but will also block local storage within an embedded iframe document. The embedded page will not be able to access the local storage property and will throw "Access denied" exceptions when the web page attempts to do so.
Blocking third-party cookies will have no impact to websites since it's used as a mechanism to share information with no returned output and no dependency of success. If your app uses local storage, it will likely break without it.
What's the security concern?
Doesn't that make sense that an embedded page can't access the local storage?
As other comments have incorrectly stated is that accessing the local storage within an embedded iframe would essentially enable cross-domain data access.
This is incorrect. The localStorage property is unique to the window variable of the frame, it is not unique to the parent domain. In other words, if you have an embedded iframe it will have a separate local storage than the parent window. This is because local storage is unique to the domain for which the code is executing in, and therefore there is no "cross-domain" access happening as part of it.
There must be other ways this is a security concern
As other comments have mentioned, the ultimate concern is leaking data across domains. So how can this happen?
It is technically possible to access the local storage property bi-laterally - child iframes can access their parent's window property and vice-versa, parent frames can access embedded iframe window objects, however Chromium blocks this by default. I tried turning off all security settings within Chromium and could not directly access the localStorage property in a parent/child or child/parent direction.
In the context of Chromium I have no reason to believe that local storage can be accessed across domains in any way unless it's explicitly instructed by the frame source page using a special header.
So why does Chromium block local storage in iframes?
Perhaps it made sense at a time before local storage became what it is today, or before accessing iframe window properties from relative frames was prevented.
Ultimately if Chromium implements local storage properly, there should be no possibility of cross-domain access without the hosting website being explicitly configured to allow such behavior. See FireFox for an example of this done properly.
What should Chromium do?
Separate out blocking local storage into it's own setting, and it should be disabled by default because there is very little reason to outright disable the entire feature that breaks a website.

Cross Origin Iframes Parititioning IndexedDB

I have a cross origin iframe that's using indexeddb for local storage. What I want is to have my indexeddb to have the origin set to be origin of the iframe. When I visit the iframe's domain, I want to be able to access the data stored in the indexeddb for that domain.
This works fine in Chrome, however in both Firefox and Safari, I've found a problem. The iframe code is getting two different indexeddbs based on whether it's loaded in an iframe or not. I figured out what Firefox is doing, and I suspect Safari is doing something similar. Firefox is actually partitioning the indexeddb based on the union of the iframe's domain and the embedding parent's domain. (i.e. Firefox is not segmenting by the iframe's origin, but rather a combination of iframe's and the parent's origins.)
I've been poking around with various sandbox parameters on the iframe, but I haven't figured out a way around this, and there's not a lot of information about this. Is there anyway to force Firefox and Safari to just use the iframe's origin here?
This is due to state partitioning.
You can request unpartitioned state access by using the Document.requestStorageAccess() api

sessionStorage in iframe

I'm going to have several iframes on my page and I'm going to quite intensively use sessionStorage inside them. What I'm curious about is if I will have separate storages or one shared for all iframes? How do the size limits apply?
If sessionStorage is shared depends on the iframe's page and it's origin, which is the domain part of the URL. If you have a webpage at http://myserver/test.html and it is including http://thatserver/some.html via an iframe, the iframe's page has the domain thatserver. Thus the origin differs and the sessionStorage won't be shared. But if the iframe's page is http://myserver/some.html it has the same origin and therefore will share the same session storage.
Now there is an additional trick: The sandbox attribute for the iframe. If you write <iframe sandbox> without the value allow-same-origin the content of the iframe gets a unique origin. That means it would get a different sessionStorage regardless of the real origin that page has. You can write <iframe sandbox="allow-same-origin"> to sandbox the content AND let the content of the iframe to have the same origin (but only if if does have the real same origin).
Now special notes: sandboxed iframes won't support localStorage per spec. And in webkit-browsers and mozilla firefox an exception will be thrown if the sandboxed iframe content will try to access sessionStorage.
OK, I've made a test myself. At least in Chrome (44) and Firefox (40) the sessionStorage is shared among page and the iframes included if they are of the same domain and do not if they are of different domains.

Does chrome extension has it's own document.cookie?

I'm writing a chrome extension. I want to store some data in the browser cookie so that I can use it later. Cookie is a perfect way to do that. Does chrome extension have it's own document cookie for this like all the websites?
I got this result when I did some research https://developer.chrome.com/extensions/cookies
But it mostly talks about cookie API and getting cookies of other websites hence the question. Also does chrome storage have any advantages over using a cookie? I just need to store 2/3 key value pairs. https://developer.chrome.com/apps/storage
I will say Just one line and you will understand it.
Cookies are always related to a website/domain.
It does not make sense to ask if Chrome extension has a cookie. You can have a cookie for every domain.
Some more information to help you solve your problem. If you see chrome extension model, you can see there are
Background Scripts
Content Scripts
Popup Page/Scripts
If you want to store cookie in a background script/ popup script, then you can definitely do it. But that cookie will be saved for the domain of your background script which is essentially your chrome extension id.
If you store cookie in a content script, then you are storing information in cookie which belongs to the domain on which your content script is injected.
One one hand, yes, cookies are available in Chrome extensions. But this is a very unorthodox method of storing data in extensions.
As you correctly pointed out, chrome.cookies API is for manipulating other pages' cookies. The common way of working with cookies in JS is document.cookie.
What are the common ways to store persistent data?
Two classic ways are localStorage and chrome.storage.
I've answered about them before; see this answer for comparison between them, and this answer for a usage example.
To decide what you need, the most important question is: do you need to access data from a content script?
If no, using localStorage may be simpler.
If yes, you will need to use either chrome.storage, or message passing.

window.localStorage vs chrome.storage.local

I'm developing a Chrome extension and I need to store some data and then get it in some point. I did investigation on available storages and came across to the following ones: window.localStorage and chrome.storage.local.
So my question is, which one is the right choice to use in Chrome extensions:
window.localStorage or chrome.storage.local?
P.S. I'm using browser action to load a local HTML in IFRAME. So I'm not using popup.js.
localStorage
Pros:
Synchronous, and thus easier to work with: var value = localStorage[key]
Has support in Dev Tools: Resources > Local Storage to view and modify.
Cons:
Only stores strings, therefore you need to serialize data yourself, i.e. with JSON.stringify
Is not accessible from content scripts (or rather, context scripts share it with the page and not the extension), so you need to rely on Messaging to pass values to them.
Synchronous AND shared between concurrently-executing extension pages, leading to possible synchronization issues.
chrome.storage.local
Pros:
Automagically serializes JSON-compatible data, can store non-strings with no additional boilerplate.
Fully available within Content Scripts.
Supports events that notify about changes: chrome.storage.onChanged
With "unlimitedStorage" permission, can hold arbitrarily large amounts of data.
Has a nice built-in mechanism for default values:
chrome.storage.local.get({key: defaultValue}, function(value){/*...*/});
Fully supported in Firefox WebExtensions and Edge Extensions.
Cons:
Asynchronous, therefore a bit harder to work with:
chrome.storage.local.get("key", function(value){/* Continue here */});
Not visualized in Dev Tools; one needs to call chrome.storage.local.get(null) to get all values or use something like Storage Area Explorer.
chrome.storage.sync
Same as above, but:
Pros:
Automatically synced between signed-in Chrome instances, if extensions sync is enabled.
Cons:
Inflexible quotas on data size and update frequency.
As of 2016-11-06, not yet supported in either Firefox WebExtensions or Edge Extensions, so non-portable.
Note: storage.sync is now FF WebExtension compatible, though there is no way to make Chrome and FF natively sync between each other.
It depends entirely on what your Chrome Extension will be doing. window.localStorage is HTML5 storage. Unless you're running it in the background page, it can only allow you to get and set data into storage for a specific domain. This is also true for code injected into the DOM, since it would use the localStorage on the web page.
In other words, you won't be able to share data across different web pages unless you use localStorage in the background page, which operates independently of web pages, since it has a chrome:// URI as its domain.
chrome.storage.local, on the other hand, is designed for Chrome Extensions and Chrome Apps to store data in a more central location. Since this isn't accessible to normal web pages, each Extension gets its own storage. One possibility is for your background page to handle dealing with the setting and getting of the data, while your content scripts deal with modifying and interacting with the web page.
However, these API's work in content scripts as well, and both of the extensions I've written use chrome.storage.local called from the content scripts.
As an example, I built a Stack App that preserves inbox items in Stack Exchange until you've actually read them, called StackInbox. Since Stack Exchange sites span across hundreds of domains, I chose chrome.storage.local because I could save the user's accountId and reuse it across all the sites, ensuring that the inbox data is synchronized, while also using this directly in the content script.
As a simple test, put some data in localStorage on one domain, in a content script, and try to pull it from another, and you'll see that the data won't be there. With chrome.storage.local, this isn't a problem.
Lastly, Chrome Extensions and Chrome Apps are whitelisted, since the user chose to install it, so they typically can do more things than a normal website. For instance, by specifying the "unlimitedStorage" permission in your manifest, you can store data well beyond the 5MB limit placed upon HTML5 localStorage.
For more information, see Google's documentation on Chrome Storage.

Categories

Resources