-
Notifications
You must be signed in to change notification settings - Fork 56
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: add cookies.removeAll() method #690
Open
aselya
wants to merge
10
commits into
w3c:main
Choose a base branch
from
aselya:removeAll
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+151
−0
Open
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
e34be81
Create Proposal: add cookies.removeAll() method.md
aselya e8dae2e
Update proposals/Proposal: add cookies.removeAll() method.md
aselya d42833a
Update Proposal: add cookies.removeAll() method.md
aselya dac145f
Update Proposal: add cookies.removeAll() method.md
aselya 5682b4c
Update Proposal: add cookies.removeAll() method.md
aselya bf51fe9
Update Proposal: add cookies.removeAll() method.md
aselya 1c7ffcf
Update Proposal: add cookies.removeAll() method.md
aselya d7d953b
Update Proposal: add cookies.removeAll() method.md
aselya 76f57be
Update Proposal: add cookies.removeAll() method.md
aselya 8f17da2
Update Proposal: add cookies.removeAll() method.md
aselya File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
**Summary** | ||
|
||
Adds a new API `cookies.removeAll()` to allow for the removal of multiple cookies with a single call. | ||
|
||
**Document Metadata** | ||
|
||
**Author:** [aselya](https://github.com/aselya) | ||
|
||
**Sponsoring Browser:** Chrome | ||
|
||
**Contributors:** | ||
|
||
**Created:** 2024-09-18 | ||
|
||
**Related Issues:** | ||
- [PrivacyCG/CHIPS issue 6 - How do Partitioned cookies interact with browser extensions?](https://github.com/privacycg/CHIPS/issues/6) | ||
- [browser.cookies.remove removes only one cookie, not all](https://bugzilla.mozilla.org/show_bug.cgi?id=1387957) | ||
- [chrome.cookies.remove does not account for paths and host-only cookies](https://issues.chromium.org/issues/40572551) | ||
|
||
## Motivation | ||
|
||
The introduction of additional cookie attributes since the creation of the `cookies.remove()` api, has resulted in the required parameters (`url` and `name`) to no longer be unique to a single [cookie](https://issues.chromium.org/issues/40572551). Because of this, handling cookies with `cookies.remove()` requires additional steps which can be simplified by the inclusion of this new API. | ||
|
||
### Objective | ||
|
||
This new API addresses two workflows which require developers to take additional steps to ensure that cookies are deleted correctly because the required parameters for `cookies.remove()` can match multiple cookies but will only delete one cookie: | ||
##### Removal of cookies with the same url and name combination but different partitionKey, path or host-only values: | ||
To remove all the cookies with the same `url` and `name` a developer must first call `cookies.getAll()` to get all of the cookies associated with the values. Then use the results of that call to make individual calls to `cookies.remove()` to delete each cookie. | ||
|
||
##### Removal of cookies associated with a topLevelSite: | ||
To remove all the cookies associated with a `topLevelSite`, a developer must first call `cookies.getAll({})` to retrieve all partitioned and unpartitioned cookies. Then filter the results to identify cookies that have a value for `topLevelSite` of their `partitionKey` match the desired `topLevelSite`. Finally the developer will need to make individual calls to `cookies.remove()` to delete each cookie. | ||
|
||
#### Use Cases | ||
|
||
##### Cookie Manager: | ||
|
||
Let's say a cookie manager extension (with host permissions) is used by users to remove their cookies. Using `cookies.removeAll()` would ensure that the cookie manager extension is removing all the cookies associated with a `topLevelSite` correctly. Instead of relying on the developer of the extension to make a call to `cookies.getAll()` followed by call(s) to `cookies.remove()`. Reducing complexity for the developers while improving performance of the extension. | ||
|
||
### Known Consumers | ||
|
||
All extensions that access and/or modify cookies with awareness of partitioned cookies, through the use of the `partitionKey` property in the `cookies` extension API. | ||
|
||
## Specification | ||
|
||
|
||
### Schema | ||
|
||
##### Syntax | ||
|
||
``` | ||
let removed = await browser.cookies.removeAll( | ||
details // object | ||
) | ||
``` | ||
##### Parameters | ||
An `object` containing information to identify the cookie(s) to remove. It contains the following properties, based on the properties recognized by `cookies.remove`: | ||
|
||
>[`name`](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/cookies/remove#name) optional: | ||
> | ||
>A `string` representing the name of the cookie to remove. | ||
> | ||
>[`partitionKey`](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/cookies/remove#partitionkey) optional: | ||
> | ||
>An object representing the storage partition containing the cookie. | ||
> | ||
>[`topLevelSite`](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/cookies/remove#toplevelsite) optional: | ||
> | ||
>A `string` representing the first-party URL of the top-level site storage partition containing the cookie. | ||
> | ||
>[`storeId`](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/cookies/remove#storeid) optional: | ||
> | ||
>A `string` representing the ID of the cookie store to find the cookie in. If unspecified, the cookie is looked for by default in the current execution context's cookie store. | ||
> | ||
>[`url`](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/cookies/remove#url) optional: | ||
> | ||
>A `string` representing the URL associated with the cookie. | ||
> | ||
>A details object must contain a `url` and/or a `topLevelSite`. | ||
|
||
##### Return | ||
|
||
> `Promise<Cookie[]>`: | ||
> | ||
> All the cookies that were removed. If list is empty then no cookies were removed. | ||
|
||
|
||
### Behavior | ||
|
||
The API will remove all cookies that match the `details` object parameter with the exception of the cases outlined in the implementation details. | ||
If the extension does not have [host permissions](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions#host_permissions) for this URL, the API call will fail. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we allow calling this API without a |
||
|
||
### New Permissions | ||
No new permissions are required. | ||
|
||
### Manifest File Changes | ||
No new manifest fields are required. | ||
|
||
## Security and Privacy | ||
Incorrect usage can lead to the removal of cookies that are not intended. | ||
|
||
### Exposed Sensitive Data | ||
None | ||
|
||
### Abuse Mitigations | ||
To remove a cookie, the extension must have host permissions for the `url` associated with the cookie. | ||
|
||
|
||
## Alternatives | ||
None | ||
|
||
### Existing Workarounds | ||
|
||
The behavior introduced by this API can be replicated by using a combination of `cookies.getAll()` and `cookies.remove()`. | ||
|
||
### Open Web API | ||
|
||
The cookies API is specific to extensions | ||
|
||
## Implementation Notes | ||
|
||
Host permissions are required for this API. | ||
#### Special cases: | ||
```cookies.removeAll({})``` | ||
|
||
>An empty details object will result in an error. | ||
|
||
``` | ||
cookies.removeAll({ | ||
partitionKey:{}}) | ||
``` | ||
|
||
>An empty `partitionKey` object in the details object, will result in both partitioned and unpartitioned cookies being removed, that also match any other values in the details object. | ||
|
||
``` | ||
cookies.removeAll({ | ||
name: “example”, | ||
url: “https://example.com”, | ||
partitionKey:{} | ||
}) | ||
``` | ||
|
||
>If `topLevelSite` is the only argument, it will result in all cookies that have that value as the `topLevelSite` in their `partitionKey` being removed. | ||
|
||
``` | ||
cookies.removeAll({ | ||
topLevelSite: “https://example.com”, | ||
partitionKey:{topLevelSite: “https://foo.com”} | ||
}) | ||
``` | ||
|
||
>If the `topLevelSite` differs from the `topLevelSite`, if present, in the `partitionKey` an error will be returned. |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Return value" is not documented in this proposal. What are you going to return?
The
remove
method returns the deleted cookie, and that could be reasonable to do the same incookies.removeAll
. A concrete use case is to allow for extensions to undo the removal. Currently extensions have to callcookies.get
orcookies.getAll
and keep track of the cookie. This tracking requires extensions to accurately predict which cookie would be removed for a givencookies.removeAll
call, but it is not easy to determine which cookies would be removed.Another option is to return nothing (undefined) and encourage extension developers to call
getAll
with the given parameters, under the assumption that thecookies.getAll
call would return exactly the same set of cookies as matched bycookies.removeAll
. In theory this is prone to TOCTOU issues, but I think that this is not that big of a deal in practice.Yet another option is to add an option to the
cookies.removeCookies
call to flag whether deleted cookies should be returned.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think returning a list of cookies that were removed makes sense here. In addition to addressing the use case you mentioned it also matches the behavior of
cookies.getAll()
.