Open Bug 1412844 Opened 7 years ago Updated 1 year ago

Add ability for WebExtensions to access websites' localStorage.

Categories

(WebExtensions :: Storage, enhancement, P5)

enhancement

Tracking

(firefox57 wontfix)

UNCONFIRMED
Tracking Status
firefox57 --- wontfix

People

(Reporter: snprintfv, Unassigned)

Details

(Whiteboard: [design-decision-needed])

User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:57.0) Gecko/20100101 Firefox/57.0 Build ID: 20171026211016 Steps to reproduce: Currently, the only way for WebExtensions to interact with Web Storage is by injecting a content script into a currently active webpage. This method makes it impossible both to access the Web Storage of not-currently-displayed sites as well as to override the standard API and use most of WebExtension functionality from the overridden functions. (Because Web Storage is a sync API). For example, in my use case (A rewrite/clone of "Self-Destructing Cookies" add-on), i want to clear the localStorage after all the tabs of a certain domain closes. The current API does not allow to do that without using a very hacky approach. Actual results: Such API does not exist yet. Expected results: I would like to propose the following API: The API lives in "browser.webStorage", requires a "webStorage" permission as well a host permission for the website, whose localStorage the extension wants to access. Types: webStorage.Storage: A representation of localStorage store for a specific website Methods: Storage.keys(): Returns a Promise that will be fulfilled with an array of all keys stored in localStorage Storage.get(keys: Array<string>): Returns a Promise that is fulfilled with an object like: ForEach key in keys: {key: value}, where value is the value stored for key. If a key passed in the keys does not have a value, it value is assumed to be "undefined". If keys is undefined, all keys in localStorage are returned. Storage.remove(keys: Array<string>): Returns a promise, that is fulfilled with "undefined" when all the keys passed in the array are removed from localStorage. Storage.set(obj: Object<string, string>): Returns a promise, that is fulfilled with "undefined" when all the keys passed in the object are set to the new values. Events: Storage.onChanged.[addListener()/removeListener()/hasListener()]: fired, when a localStorage is chaned for a website. The callback is passed a domStorage.ChangeInfo object. domStorage.ChangeInfo: A representation of a change to localStorage. Properties: ChangeInfo.key: the affected key ChangeInfo.oldValue: the old value of the affected key. Does not exist if the event is a creation of a new value. ChangeInfo.newValue: the new value of the affected key. Does not exist if the event is a removal of a value. Methods: webStorage.getStores(domains: Array<URL>): Returns a promise, that is fulfilled with "domStorage.Storage" objects for domains that are both passed in in "domains" parameter and the extension has a host permission to. webStorage.removeStores(domains: Array<URL>): Returns a promise, that is fulfilled with "undefined" when the localStorages for all the domains passed in the array are cleared.
Severity: normal → enhancement
Priority: -- → P5
Whiteboard: [design-decision-needed]
The only concrete application given for this API is to remove data from local storage, which can already be done via the browsingData API: https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/browsingData The request to read and write individual records will almost certainly be denied without specific use cases.
(In reply to Andrew Swan [:aswan] from comment #1) > The only concrete application given for this API is to remove data from > local storage, which can already be done via the browsingData API: > https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/browsingData > > The request to read and write individual records will almost certainly be > denied without specific use cases. Correct, localStorage storage can be removed via the browsing data api. However this approach is too imprecise as it completely removes all of the data for all websites. In my particular use case, i remove localStorage only for websites that are not whitelisted by the user and also after all of the tabs of a website was closed. Also my use case provides a "Resurrect Cookies" functionality that allows to restore the deleted cookies and localStorage for a specific website at the request of the user.
(In reply to snprintfv from comment #2) > Correct, localStorage storage can be removed via the browsing data api. > However this approach is too imprecise as it completely removes all of the > data for all websites. No, the options passed to remove() and removeLocalStorage() can include a hostnames property: https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/browsingData/RemovalOptions
(In reply to Andrew Swan [:aswan] from comment #3) > (In reply to snprintfv from comment #2) > > Correct, localStorage storage can be removed via the browsing data api. > > However this approach is too imprecise as it completely removes all of the > > data for all websites. > > No, the options passed to remove() and removeLocalStorage() can include a > hostnames property: > https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/browsingData/ > RemovalOptions Still no way to resurrect or edit the localStorage.
(In reply to snprintfv from comment #4) > Still no way to resurrect or edit the localStorage. As I said in comment 1, evaluating whether to add the ability to edit localStorage would be easier with some concrete use cases.
Component: WebExtensions: Untriaged → WebExtensions: Storage
Gonna add myself to userlist for this bug since: https://addons.mozilla.org/en-GB/firefox/addon/self-destructing-cookies-webex/ Is pretty useless in this era of super cookies without ability to clear local storage on tab close.
Product: Toolkit → WebExtensions
Severity: normal → S3

Actually, now as Add-ons can finally be developed for Android, I decided to have a go to get my preferred "Cookie behavior", I used on Desktop for decades, to Android: I want all tracking relevant data (Cookies and local storage) to go if I close or restart the browser with exception of a very small hand selected whitelist of just a handful websites I don't want to be logged out. This is possible on Desktop but not on Android where I have to clear all browsing data and then have to re-login everywhere.

It is very possible to create something like this for cookies only. The cookies API gives great control over everything stored by websites. Fine granular filtering is possible and whatever I selected based on filtering can be deleted easily. But just clearing cookies does not stop tracking anymore, now as other techniques are possible. An API like this is missing for "local storage". IMHO it could be pretty similar to the "cookies" API. Call it "webstorage" and start with a copy of the "cookies" API. Then do minor changes where cookies and local storage differ.

About the https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browsingData API:
Yes, it has a "hostnames" property which can be set for "removeLocalStorage()", but this is blacklist only. What I want to have is a whitelist. To make this possible with the existing API one of the following would be needed:

  • A way to invert the "hostnames" property to switch it from "blacklist" to "whitelist".
  • A way to know which websites actually have something stored using "local storage". Meaning some kind of "query API" to get a list. Maybe add additional info to this API, like a field which tells the amount of data stored by a domain in bytes. This would allow to create a similar dialog of what Firefox Desktop has, where the amount of storage per domain is displayed.

Probably the second option would be the most useful one as it allows to populate a list where the user can pick entries from to be added to a whitelist. An Add-on could then simply get the list of domains which have something stored, remove the whitelisted entries from that and then use the filtered list for the "hostnames" property.

You need to log in before you can comment on or make changes to this bug.