Skip to content

Commit 0f09b4a

Browse files
committed
Add Public Suffix API proposal
1 parent 12d0eda commit 0f09b4a

File tree

1 file changed

+227
-0
lines changed

1 file changed

+227
-0
lines changed

proposals/public-suffix.md

+227
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
# Proposal: Public Suffix API
2+
3+
**Summary**
4+
5+
API to obtain the topmost *registrable domain / eTLD+1 (effective Top Level Domain+1)*
6+
from a domain name or URL.
7+
8+
**Document Metadata**
9+
10+
**Author:** [Francis McKenzie](https://github.com/mckenfra)
11+
12+
**Sponsoring Browser:** Mozilla Firefox
13+
14+
**Contributors:** N/A
15+
16+
**Created:** 2024-08-19
17+
18+
**Related Issues:** [#231](https://github.com/w3c/webextensions/issues/231)
19+
20+
## Motivation
21+
22+
### Objective
23+
24+
This API enables developers to obtain the topmost *registrable domain / eTLD+1*
25+
from a domain name or URL. This functionality is already implemented for internal
26+
use by all the major browsers. Therefore the effect of this API is to expose
27+
existing built-in browser functionality to extensions developers.
28+
29+
The primary objective of this API is to eliminate the possibility of inconsistencies
30+
between the host browser and hosted extensions when deriving topmost
31+
*registrable domain / eTLD+1*s from domain names / URLs.
32+
33+
Secondary objectives of this API are to:
34+
35+
1. Improve extension developer experience by reducing complexity and maintenance overhead,
36+
since developers will no longer need to roll their own solutions for obtaining and parsing
37+
the [Public Suffix List (PSL)](https://publicsuffix.org/list/).
38+
2. Reduce extensions' resource usage (CPU, memory, disk space), since extensions
39+
will no longer be duplicating work already done by the host browser.
40+
41+
#### Use Case #1: Wildcard Domains
42+
43+
This API is relevant to any extension that gives the user control over which
44+
domain names / URLs the extension's functionality should apply to. For example,
45+
Mozilla's [multi-account-containers](https://github.com/mozilla/multi-account-containers)
46+
extension allows users to create containers for web pages as they visit them.
47+
48+
Users may want the ability to apply the extension's functionality to a
49+
*wildcard domain*, such that all subdomains of some base domain are
50+
automatically included.
51+
52+
This API allows the extension to automatically propose the topmost *registrable domain / eTLD+1*
53+
as a possible *wildcard domain* for the user to choose. It also allows the
54+
extension to prevent the user from accidentally choosing a *public suffix / eTLD*
55+
as a wildcard domain, e.g. `*.com`.
56+
57+
#### Use Case #2: Grouping Domains in UI
58+
59+
Where extensions present lists of domain names / URLs to users, it can be beneficial
60+
from a UX perspective to group them by their topmost *registrable domain / eTLD+1*s.
61+
62+
##### Ungrouped domains
63+
64+
| |
65+
| --------------------- |
66+
| example.co.uk |
67+
| example2.com |
68+
| foo.bar.example.co.uk |
69+
| foo.bar.example2.com |
70+
| www.example.co.uk |
71+
| www.example2.com |
72+
73+
##### Grouped domains
74+
75+
| example.co.uk | |
76+
| -------------- | --------------------- |
77+
| | example.co.uk |
78+
| | foo.bar.example.co.uk |
79+
| | www.example.co.uk |
80+
81+
| example2.com | |
82+
| -------------- | --------------------- |
83+
| | example2.com |
84+
| | foo.bar.example2.com |
85+
| | www.example2.com |
86+
87+
### Known Consumers
88+
89+
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
90+
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
91+
anticipated subdomains of a base domain, and this manual approach is cumbersome and
92+
error-prone.
93+
94+
Apart from this, any other extension that already rolls its own solution in order to parse
95+
the PSL could potentially benefit from this API, for example [uBlock Origin](https://github.com/gorhill/uBlock).
96+
97+
## Specification
98+
99+
### Schema
100+
101+
A new API `publicSuffix` is added as follows:
102+
103+
```ts
104+
//
105+
// Example:
106+
//
107+
// let domain = await browser.publicSuffix.getRegistrableDomain("www.example.co.uk");
108+
// ==> 'example.co.uk'
109+
//
110+
Promise<string> browser.publicSuffix.getRegistrableDomain(
111+
// The domain name or URL whose registrable domain we want to find
112+
domainNameOrUrl: string,
113+
)
114+
```
115+
116+
### Behavior #1: Returned Promise
117+
118+
The promise returned by `getRegistrableDomain()` method will either:
119+
120+
1. Resolve with the topmost *registrable domain / eTLD+1* if it can be determined from
121+
the `domainNameOrUrl`.
122+
2. Reject with an `Error` / populate `browser.runtime.lastError`.
123+
124+
### Behavior #2: Private Domains
125+
126+
By default, the lookup performed by `getRegistrableDomain()` should **exclude** private domains
127+
contained in the PSL dataset.
128+
129+
See [Future work](#1-extend-the-api).
130+
131+
### New Permissions
132+
133+
| Permission Added | Suggested Warning |
134+
| ---------------- | ----------------- |
135+
| publicSuffix | Read the public suffix list |
136+
137+
### Manifest File Changes
138+
139+
There are no changes to the manifest.
140+
141+
## Security and Privacy
142+
143+
### Exposed Sensitive Data
144+
145+
The only data exposed by this API is the [public suffix list](https://publicsuffix.org/list/).
146+
147+
### Abuse Mitigations
148+
149+
This does not expose any new non-public data so there are no new abuse vectors.
150+
151+
### Additional Security Considerations
152+
153+
N/A
154+
155+
## Alternatives
156+
157+
### Existing Workarounds
158+
159+
Developers can download the PSL dataset, bundle it with their extensions, and implement
160+
logic that parses and interprets the dataset in order to determine the topmost
161+
*registrable domain / eTLD+1* for a domain name. There are several drawbacks to
162+
this approach:
163+
164+
1. Potential for inconsistencies in the determination of topmost *registrable domain / eTLD+1*
165+
by the extension and the host browser, due to differences in the version
166+
of the PSL dataset used, and differences in the implementations that the host
167+
browser and the extension use in order to interpret this dataset.
168+
2. Increased complexity and maintenance costs of extensions.
169+
3. Increased performance overhead of extensions due to bundling of bulky
170+
PSL dataset, leading to increase in memory, disk usage and increase in CPU usage
171+
due to possibly suboptimal extension implementations and repeating work already
172+
done by the host browser.
173+
174+
### Open Web API
175+
176+
The purpose of this API is to eliminate the potential for inconsistency between
177+
the host browser and its hosted extensions. The simplest way of achieving this
178+
is for extensions to access this functionality via the host browser itself rather
179+
than via some external source, such as an Open Web API.
180+
181+
It is then a determination for the host browser itself as to whether
182+
the functionality (used by both the host browser and its extensions)
183+
should ultimately be obtained by means of an Open Web API.
184+
185+
## Implementation Notes
186+
187+
Since the major browsers all already implement internal methods for determining
188+
topmost *registrable domain / eTLD+1*s, it is hoped that the implementation will
189+
involve little more than providing the relevant mechanism for exposing these same methods
190+
to extensions:
191+
192+
| Browser | Registrable Domain Method |
193+
| ------- | ------------------------- |
194+
| Chrome | [GetDomainAndRegistry](https://source.chromium.org/chromium/chromium/src/+/main:net/base/registry_controlled_domains/registry_controlled_domain.h;l=182;drc=4f516be19f2c1d35dc3240d050d84d10f0d6f726) |
195+
| Firefox | [getBaseDomain](https://searchfox.org/mozilla-central/rev/e9f9bf31d1c0057a1cd339b5a853a75d1b16db39/netwerk/dns/nsIEffectiveTLDService.idl#94) |
196+
| Safari | [topPrivatelyControlledDomain](https://github.com/WebKit/WebKit/blob/01eba7c416725cfd4eec57ab16daffa25b8124b4/Source/WebCore/platform/PublicSuffixStore.h#L43) |
197+
198+
## Future Work
199+
200+
### 1. Extend the API
201+
202+
The major browsers provide additional methods/parameters internally for getting
203+
information related to the *registable domain / eTLD+1*. The API could be extended
204+
to expose more of these internal methods/parameters, for example:
205+
206+
1. Provide an option to include private domains when getting the *registrable domain / eTLD+1*.
207+
2. Provide method `getPublicSuffix()` to get the *public suffix / eTLD*.
208+
3. Provide methods `isRegistrableDomain()` and/or `isPublicSuffix()` for possibly improved
209+
efficiency in certain use cases.
210+
211+
### 2. Batching
212+
213+
Extensions may want to obtain *registrable domain / eTLD+1*s for large numbers of
214+
domain names / URLs at once. A possible enhancement to the API would be to
215+
provide a method that performed a lookup on multiple domain names / URLs with a
216+
single method call.
217+
218+
### 3. Change Notifications
219+
220+
The PSL dataset, used by the browsers to determine *registrable domain / eTLD+1*s,
221+
is a dynamic dataset that can change at any time. This API proposal currently provides no
222+
mechanism for notifying extensions when the host browser's PSL dataset changes.
223+
It is understood that such changes are only made currently when a new browser version
224+
is released, however this may not always be the case.
225+
226+
It may be useful to implement a notification mechanism so that extensions can take
227+
appropriate action when the host browser's PSL dataset changes.

0 commit comments

Comments
 (0)