-
Notifications
You must be signed in to change notification settings - Fork 72
Proposal: Public Suffix API #676
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
Open
mckenfra
wants to merge
7
commits into
w3c:main
Choose a base branch
from
mckenfra:publicsuffix
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.
Open
Changes from 1 commit
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
0f09b4a
Add Public Suffix API proposal
mckenfra 3301526
Update Public Suffix API proposal
mckenfra c217156
Update Public Suffix API proposal
mckenfra b874592
Update Public Suffix API proposal
mckenfra 5ba391f
Update Public Suffix API proposal
mckenfra f1d81e5
Update Public Suffix API proposal
mckenfra e0f2835
Update Public Suffix API proposal
mckenfra 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 hidden or 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,227 @@ | ||
# Proposal: Public Suffix API | ||
|
||
**Summary** | ||
|
||
API to obtain the topmost *registrable domain / eTLD+1 (effective Top Level Domain+1)* | ||
from a domain name or URL. | ||
|
||
**Document Metadata** | ||
|
||
**Author:** [Francis McKenzie](https://github.com/mckenfra) | ||
|
||
**Sponsoring Browser:** Mozilla Firefox | ||
|
||
**Contributors:** N/A | ||
|
||
**Created:** 2024-08-19 | ||
|
||
**Related Issues:** [#231](https://github.com/w3c/webextensions/issues/231) | ||
|
||
## Motivation | ||
|
||
### Objective | ||
|
||
This API enables developers to obtain the topmost *registrable domain / eTLD+1* | ||
from a domain name or URL. This functionality is already implemented for internal | ||
use by all the major browsers. Therefore the effect of this API is to expose | ||
existing built-in browser functionality to extensions developers. | ||
|
||
The primary objective of this API is to eliminate the possibility of inconsistencies | ||
between the host browser and hosted extensions when deriving topmost | ||
*registrable domain / eTLD+1*s from domain names / URLs. | ||
|
||
Secondary objectives of this API are to: | ||
|
||
1. Improve extension developer experience by reducing complexity and maintenance overhead, | ||
since developers will no longer need to roll their own solutions for obtaining and parsing | ||
the [Public Suffix List (PSL)](https://publicsuffix.org/list/). | ||
2. Reduce extensions' resource usage (CPU, memory, disk space), since extensions | ||
will no longer be duplicating work already done by the host browser. | ||
|
||
#### Use Case #1: Wildcard Domains | ||
|
||
This API is relevant to any extension that gives the user control over which | ||
domain names / URLs the extension's functionality should apply to. For example, | ||
Mozilla's [multi-account-containers](https://github.com/mozilla/multi-account-containers) | ||
extension allows users to create containers for web pages as they visit them. | ||
|
||
Users may want the ability to apply the extension's functionality to a | ||
*wildcard domain*, such that all subdomains of some base domain are | ||
automatically included. | ||
|
||
This API allows the extension to automatically propose the topmost *registrable domain / eTLD+1* | ||
as a possible *wildcard domain* for the user to choose. It also allows the | ||
extension to prevent the user from accidentally choosing a *public suffix / eTLD* | ||
as a wildcard domain, e.g. `*.com`. | ||
|
||
#### Use Case #2: Grouping Domains in UI | ||
|
||
Where extensions present lists of domain names / URLs to users, it can be beneficial | ||
from a UX perspective to group them by their topmost *registrable domain / eTLD+1*s. | ||
|
||
##### Ungrouped domains | ||
|
||
| | | ||
| --------------------- | | ||
| example.co.uk | | ||
| example2.com | | ||
| foo.bar.example.co.uk | | ||
| foo.bar.example2.com | | ||
| www.example.co.uk | | ||
| www.example2.com | | ||
|
||
##### Grouped domains | ||
|
||
| example.co.uk | | | ||
| -------------- | --------------------- | | ||
| | example.co.uk | | ||
| | foo.bar.example.co.uk | | ||
| | www.example.co.uk | | ||
|
||
| example2.com | | | ||
| -------------- | --------------------- | | ||
| | example2.com | | ||
| | foo.bar.example2.com | | ||
| | www.example2.com | | ||
|
||
### Known Consumers | ||
|
||
Mozilla intends to make use of this API in its [multi-account-containers](https://github.com/mozilla/multi-account-containers) extension to allow users to create containers | ||
that include wildcard domain names: [PR #2352](https://github.com/mozilla/multi-account-containers/pull/2352). Currently, users must manually curate their containers to capture all | ||
anticipated subdomains of a base domain, and this manual approach is cumbersome and | ||
error-prone. | ||
|
||
Apart from this, any other extension that already rolls its own solution in order to parse | ||
the PSL could potentially benefit from this API, for example [uBlock Origin](https://github.com/gorhill/uBlock). | ||
|
||
## Specification | ||
|
||
### Schema | ||
mckenfra marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
A new API `publicSuffix` is added as follows: | ||
mckenfra marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
```ts | ||
// | ||
// Example: | ||
// | ||
// let domain = await browser.publicSuffix.getRegistrableDomain("www.example.co.uk"); | ||
// ==> 'example.co.uk' | ||
// | ||
Promise<string> browser.publicSuffix.getRegistrableDomain( | ||
// The domain name or URL whose registrable domain we want to find | ||
domainNameOrUrl: string, | ||
mckenfra marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
) | ||
``` | ||
|
||
### Behavior #1: Returned Promise | ||
|
||
The promise returned by `getRegistrableDomain()` method will either: | ||
|
||
1. Resolve with the topmost *registrable domain / eTLD+1* if it can be determined from | ||
the `domainNameOrUrl`. | ||
2. Reject with an `Error` / populate `browser.runtime.lastError`. | ||
mckenfra marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
||
### Behavior #2: Private Domains | ||
|
||
By default, the lookup performed by `getRegistrableDomain()` should **exclude** private domains | ||
mckenfra marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
contained in the PSL dataset. | ||
|
||
See [Future work](#1-extend-the-api). | ||
|
||
### New Permissions | ||
|
||
| Permission Added | Suggested Warning | | ||
| ---------------- | ----------------- | | ||
| publicSuffix | Read the public suffix list | | ||
mckenfra marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
||
### Manifest File Changes | ||
|
||
There are no changes to the manifest. | ||
|
||
## Security and Privacy | ||
|
||
### Exposed Sensitive Data | ||
|
||
The only data exposed by this API is the [public suffix list](https://publicsuffix.org/list/). | ||
|
||
### Abuse Mitigations | ||
|
||
This does not expose any new non-public data so there are no new abuse vectors. | ||
mckenfra marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
||
### Additional Security Considerations | ||
|
||
N/A | ||
|
||
## Alternatives | ||
|
||
### Existing Workarounds | ||
|
||
Developers can download the PSL dataset, bundle it with their extensions, and implement | ||
logic that parses and interprets the dataset in order to determine the topmost | ||
*registrable domain / eTLD+1* for a domain name. There are several drawbacks to | ||
this approach: | ||
|
||
1. Potential for inconsistencies in the determination of topmost *registrable domain / eTLD+1* | ||
by the extension and the host browser, due to differences in the version | ||
of the PSL dataset used, and differences in the implementations that the host | ||
browser and the extension use in order to interpret this dataset. | ||
2. Increased complexity and maintenance costs of extensions. | ||
3. Increased performance overhead of extensions due to bundling of bulky | ||
PSL dataset, leading to increase in memory, disk usage and increase in CPU usage | ||
due to possibly suboptimal extension implementations and repeating work already | ||
done by the host browser. | ||
|
||
### Open Web API | ||
|
||
The purpose of this API is to eliminate the potential for inconsistency between | ||
mckenfra marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
the host browser and its hosted extensions. The simplest way of achieving this | ||
is for extensions to access this functionality via the host browser itself rather | ||
than via some external source, such as an Open Web API. | ||
oliverdunk marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
||
It is then a determination for the host browser itself as to whether | ||
the functionality (used by both the host browser and its extensions) | ||
should ultimately be obtained by means of an Open Web API. | ||
|
||
## Implementation Notes | ||
|
||
Since the major browsers all already implement internal methods for determining | ||
topmost *registrable domain / eTLD+1*s, it is hoped that the implementation will | ||
involve little more than providing the relevant mechanism for exposing these same methods | ||
to extensions: | ||
|
||
| Browser | Registrable Domain Method | | ||
| ------- | ------------------------- | | ||
| Chrome | [GetDomainAndRegistry](https://source.chromium.org/chromium/chromium/src/+/main:net/base/registry_controlled_domains/registry_controlled_domain.h;l=182;drc=4f516be19f2c1d35dc3240d050d84d10f0d6f726) | | ||
| Firefox | [getBaseDomain](https://searchfox.org/mozilla-central/rev/e9f9bf31d1c0057a1cd339b5a853a75d1b16db39/netwerk/dns/nsIEffectiveTLDService.idl#94) | | ||
| Safari | [topPrivatelyControlledDomain](https://github.com/WebKit/WebKit/blob/01eba7c416725cfd4eec57ab16daffa25b8124b4/Source/WebCore/platform/PublicSuffixStore.h#L43) | | ||
|
||
## Future Work | ||
|
||
### 1. Extend the API | ||
|
||
The major browsers provide additional methods/parameters internally for getting | ||
information related to the *registable domain / eTLD+1*. The API could be extended | ||
to expose more of these internal methods/parameters, for example: | ||
|
||
1. Provide an option to include private domains when getting the *registrable domain / eTLD+1*. | ||
mckenfra marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
2. Provide method `getPublicSuffix()` to get the *public suffix / eTLD*. | ||
3. Provide methods `isRegistrableDomain()` and/or `isPublicSuffix()` for possibly improved | ||
efficiency in certain use cases. | ||
|
||
### 2. Batching | ||
|
||
Extensions may want to obtain *registrable domain / eTLD+1*s for large numbers of | ||
domain names / URLs at once. A possible enhancement to the API would be to | ||
provide a method that performed a lookup on multiple domain names / URLs with a | ||
single method call. | ||
|
||
### 3. Change Notifications | ||
|
||
The PSL dataset, used by the browsers to determine *registrable domain / eTLD+1*s, | ||
is a dynamic dataset that can change at any time. This API proposal currently provides no | ||
mechanism for notifying extensions when the host browser's PSL dataset changes. | ||
It is understood that such changes are only made currently when a new browser version | ||
is released, however this may not always be the case. | ||
|
||
It may be useful to implement a notification mechanism so that extensions can take | ||
appropriate action when the host browser's PSL dataset changes. |
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.
Uh oh!
There was an error while loading. Please reload this page.