[DNR] Implement domainType (firstParty / thirdParty) condition
Categories
(WebExtensions :: Request Handling, enhancement, P3)
Tracking
(firefox128 fixed)
Tracking | Status | |
---|---|---|
firefox128 | --- | fixed |
People
(Reporter: robwu, Assigned: rpl)
References
(Blocks 1 open bug)
Details
(Keywords: dev-doc-complete, Whiteboard: [addons-jira])
Attachments
(1 file)
The DNR API contains a "domainType" condition with the values "firstParty" and "thirdParty".
Before implementing this, examine whether it would help extension developers with a substantial use case. Here is a thread that questions the current behavior of domainType in Chromium's issue tracker: https://bugs.chromium.org/p/chromium/issues/detail?id=1191223
Updated•3 years ago
|
Updated•3 years ago
|
Updated•3 years ago
|
Reporter | ||
Updated•2 years ago
|
Reporter | ||
Comment 1•2 years ago
|
||
It would be trivial to implement this, but only once we decide what "thirdParty" / "firstParty" means.
Common across all browsers, the generally understood meaning is "same domain" (or "same-site" or even "same-origin") relative to the top-level document. At least, in the context of cookies (third-party cookies on MDN), that has consistently been the case, and is also reflected in various mechanisms to isolate cookies. For example, all of the following define first/third-party in relation to the top level document:
- Tracking protection, storage partitioning, first-party isolation in Firefox.
- Cookies Having Independent Partitioned State (CHIPS) and Firsty-Party Sets in Chrome.
- WebKit's Tracking Protection in Safari.
In Firefox, there is an interpretation of "third-party" exposed in the details.thirdParty
in the webRequest API: "Indicates whether the request and its content window hierarchy are third party." In other words, if all documents up to the top are same-domain to the requested URL, then it's first-party. Otherwise it's third-party.
In Safari 15+, in contrast to the above definition of "first-party" (same-site), the domainType
in DNR is translated to the "first-party" / "third-party" trigger of the internal Content Blocking API and means "first-party triggers only if the resource has the same scheme, domain, and port as the main page resource. third-party triggers if the resource isn’t from the same domain as the main page resource." . The unusual part here is that the check is "same-origin" instead of "same-domain".
Inconsistent with existing conventions, Chrome, domainType
in DNR is documented to mean "whether the network request is first-party or third-party to the domain from which it originated.". In other words, whether the requested URL and "request initiator" are same-domain. Chrome's DNR is backed by a subresource_filter
, and its very first implementation already had this interpretation of "first-party" (source of indexed_ruleset.cc, part of commit, still present in the latest version of indexed_ruleset.cc). This implementation has been called out as defective by extension devs, e.g. at https://bugs.chromium.org/p/chromium/issues/detail?id=1191223#c6
To sum up, here are three potential ways to interpret what "first-party" means for a given request URL:
- (Chrome's DNR) First-party iff same-domain to (sub)document that initiates the request. Third-party otherwise.
- (Safari's DNR) First-party iff same-origin to top-level document. Third-party otherwise.
- (Firefox's webRequest) First-party iff same-domain for the whole frame hierarchy. Third-party otherwise.
The following are true:
- first-party in Firefox implies first-party in Chrome
- and first-party in Firefox would also have implied first-party in Safari, but since Safari's "same-origin" is stricter than Firefox's "same-domain", it is possible for something to be first-party in Firefox, yet third-party in Safari (e.g. scheme differs).
- third-party in Chrome implies third-party in Firefox, but not necessarily third-party in Safari.
- third-party in Safari implies third-party in Firefox, but not necessarily third-party in Chrome.
- first-party in Chrome or Safari does not guarantee first-party in the other browsers.
Reporter | ||
Comment 2•2 years ago
|
||
In addition to the detailed comparison in comment 1, I'd also like to note that the "allowAllRequests" action was originally designed to support domain hierarchy matching:
- Chromium Issue 1038831: Declarative Net Request: Add action to allow all requests within a frame hierarchy.
- Firefox implementation in bug 1797403.
But despite the generic API design of allowAllRequests
, it does not sufficiently cover the use cases of extension devs, evidenced by:
- Chromium Issue 1191223: Extension Mv3: Implement DNR rule conditions based on domains in frame hierarchy
- Chromium Issue 1385727: [DNR] Add tabDomains/excludedTabDomains rule conditions
The distinction between "domainType" (this bug + comment 1) and "allowAllRequests" (and follow-ups) is that domainType describes first/third-party relations (to be decided: immediate initiator, top-level initiator, all frame ancestors), whereas the latter describes relations with explicit domains.
Comment 3•2 years ago
•
|
||
to be decided: immediate initiator, top-level initiator, all frame ancestors
EasyList semantic for its third-party
option is "immediate initiator". Implementing a different semantic would make it impossible to properly convert filter lists compliant with EasyList syntax, which is what all top content blockers use, i.e. at least six of the eight top content blockers by usage in Mozilla's AMO: uBO, ABP, Adblock Ultimate, AdBlock, Ghostery, AdGuard. For the remaining two (DuckDuckGo Privacy Essentials, Privacy Badger), I didn't look into it.
Reporter | ||
Comment 4•2 years ago
|
||
(In reply to rhill@raymondhill.net from comment #3)
to be decided: immediate initiator, top-level initiator, all frame ancestors
EasyList semantic for its
third-party
option is "immediate initiator".
In case of iframes, the initiator (of the navigation) may have a different domain/origin than the embedder of the frame. For example, if A embeds B, the initiator and embedder of B is A in both cases. But if B navigates to C, then the C request is initiated by B while the parent is A.
Which domain should be used to determine whether a navigation request is same-party?
Often, the "domain" can directly be inferred from the document (or Worker) that initiates a request. That is not always the case, e.g. with sandboxed documents. What's the desired behavior here?
Assignee | ||
Comment 5•1 year ago
|
||
Updated•1 year ago
|
Reporter | ||
Comment 6•11 months ago
|
||
For future reference, the domainType
that we're going to implement here matches Chrome's behavior, mentioned at https://phabricator.services.mozilla.com/D212267?id=870402#inline-1177146
For reference, Chrome's behavior is as follows:
- first_party_origin = initiator or no origin
- document requests: sub_frame = parent origin, main frame = no origin
- ^ https://source.chromium.org/chromium/chromium/src/+/main:extensions/browser/api/declarative_net_request/request_params.cc;l=181-221;drc=ac83a5a2d3c04763d86ce16d92f3904cc9566d3a
- opaque origin (=no origin, null origin including sandboxed domain) = third party
- same base domain = first party, otherwise third-party
- ^ https://source.chromium.org/chromium/chromium/src/+/main:extensions/browser/api/declarative_net_request/request_params.cc;l=38;drc=ac83a5a2d3c04763d86ce16d92f3904cc9566d3a
This behavior in its turn is based on the meaning of "third-party" option in adblocker filters (aka 3p in uBlock Origin).
uBlock Origin also has a strict3p option (https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#strict3p), which is currently not supported in DNR. If you feel that this feature is necessary, consider filing a feature request in the WECG.
Comment 8•11 months ago
|
||
bugherder |
Assignee | ||
Updated•11 months ago
|
Changes are ready for review:
- MDN Documentation for declarativeNetRequest.RuleCondition.domainType impl #34577
- BCD Add declarativeNetRequest.RuleCondition.domainType details #23639
However, I was uncertain whether additional documentation was needed for the comments about the definition of first and third-party. I noted that nothing additional was provided in the Chrome documentation.
Description
•