Skip to content
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

Chrome extension manifest v3 proposal #338

Open
greghuc opened this issue Dec 13, 2018 · 171 comments
Open

Chrome extension manifest v3 proposal #338

greghuc opened this issue Dec 13, 2018 · 171 comments
Labels
Chromium specific to Chromium/Chrome something to address something to address

Comments

@greghuc
Copy link

greghuc commented Dec 13, 2018

Description

This issue is a heads-up on the proposed Chrome extension manifest version 3, which will have a significant impact on ad-blockers.

There is a tracking bug at: https://bugs.chromium.org/p/chromium/issues/detail?id=896897

In-progress design doc: https://docs.google.com/document/d/1nPu6Wy4LWR66EFLeYInl3NzzhHzc-qnk4w4PX-0XMw8/edit#

Might be worth a review, and giving feedback via the tracking bug.

regarding all dev. on dnr - https://bugs.chromium.org/p/chromium/issues/list?can=2&q=declarative+net+request

"Migrating to Manifest V3" (timeline) - https://developer.chrome.com/extensions/migrating_to_manifest_v3

@uBlock-user uBlock-user changed the title Heads up: Chrome extension manifest v3 proposal Chrome extension manifest v3 proposal Dec 13, 2018
@uBlock-user uBlock-user added the discussion weighing in community's input on a specific topic label Dec 13, 2018
@uBlock-user
Copy link
Contributor

Yes this was announced back in October - https://blog.chromium.org/2018/10/trustworthy-chrome-extensions-by-default.html

Not much for uBO to do though..

@jspenguin2017
Copy link

jspenguin2017 commented Dec 13, 2018

I'm not sure how are they planning to change the background process and origin access, it might cause some issues. Beside that, I don't see anything else that can cause problems. As for remotely-hosted code, it really should've been forbidden since the beginning.

@uBlock-user uBlock-user added something to address something to address and removed discussion weighing in community's input on a specific topic labels Jan 6, 2019
@joey04
Copy link

joey04 commented Jan 9, 2019

It appears that Google is phasing out the webRequest API in favor of their new declarativeNetRequest.

The current Manifest V3 draft states:

The declarativeNetRequest API is an alternative to the webRequest API. At its core, this API allows extensions to tell Chrome what to do with a given request, rather than have Chrome forward the request to the extension. Thus, instead of the above flow where Chrome receives the request, asks the extension, and then eventually gets the result, the flow is that the extension tells Chrome how to handle a request and Chrome can handle it synchronously. This allows us to ensure efficiency since a) we have control over the algorithm determining the result and b) we can prevent or disable inefficient rules. This is also better for user privacy, as the details of the network request are never exposed to the extension.

This API is currently being implemented, and will be available to both the current manifest version and Manifest V3, but will be the primary way to modify network requests in Manifest V3.

Looking at the new API page, it's a rather different way of doing things. I would expect big changes needed to uBO and other blockers. (Plus there's the change from background page to ServiceWorker.)

@uBlock-user uBlock-user added the Chromium specific to Chromium/Chrome label Jan 9, 2019
@uBlock-user
Copy link
Contributor

uBlock-user commented Jan 9, 2019

Another change would be dynamic Content Scripts similar to what Firefox has where extensions can inject contentScript and have it execute before page finishes loading.

@gwarser
Copy link
Member

gwarser commented Jan 9, 2019

declarativeNetRequest

Basic ABP-like syntax, 30000 filters MAX...

@uBlock-user
Copy link
Contributor

That was declarativeWebRequest, that was shelved.

@gwarser
Copy link
Member

gwarser commented Jan 9, 2019

I don't see limits to the number of the rules in declarativeWebRequest. declarativeNetRequest have better syntax, but number of rules is limited.

@gorhill
Copy link
Member

gorhill commented Jan 9, 2019

It appears that Google is phasing out the webRequest API

It is explicitly stated this is meant to phase out webRequest API? If so, where? Quickly perusing the page, I don't see such phase out being stated. If there is really such phase out planned, and if the declarativeNetRequest is strictly an implementation of static filtering à la ABP, this would be the death of uBO and uMatrix.

There is no way to transpose either either dynamic filtering, dynamic URL filtering, per-site/per-scope switch logic (let's refer to all these as "dynamic filtering"), into static filters. Dynamic filtering logic requires an arbitrary amount of block/allow rules overriding other block/allow rules based on specificity. There is no concept of specificity in static filtering -- and even more, there is no concept of dynamic filtering rules relinquishing filtering to static filters (dynamic filtering's noop rules).

Basic ABP-like syntax, 30000 filters MAX...

And there I was recently testing how uBO handled over half a million network filters with the 3rd-gen HNTrie...

a

Issues of performance and privacy lie with web sites, not uBO -- so I don't feel concerned with the issues of privacy and efficiency being put forth as advantages of using declarativeNetRequest over webRequest.

@uBlock-user
Copy link
Contributor

uBlock-user commented Jan 9, 2019

https://docs.google.com/document/d/1nPu6Wy4LWR66EFLeYInl3NzzhHzc-qnk4w4PX-0XMw8/edit#heading=h.ypclvihky0p6

Read the paragraph that's titled DeclarativeNetRequest. They will keep webRequest API but it will not block, modify or redirect anymore, that will be handled by NetRequest API with v3.

They do plan to discourage the use of webRequest API through with its new replacement - https://docs.google.com/document/d/1nPu6Wy4LWR66EFLeYInl3NzzhHzc-qnk4w4PX-0XMw8/edit#heading=h.xe5njuo7voeb

@uBlock-user
Copy link
Contributor

uBlock-user commented Jan 9, 2019

30000 is mentioned in https://developer.chrome.com/extensions/declarativeNetRequest#property-MAX_NUMBER_OF_RULES, not sure what to make of this, can you shed some light there ? I don't think it is related to 30K ABP styled filters.

@gorhill
Copy link
Member

gorhill commented Jan 9, 2019

Look at "Rule", it's clearly made to implement ABP-compatible filters:

'|' : Left/right anchor: If used at either end of the pattern, specifies the beginning/end of the url > respectively.

'||' : Domain name anchor: If used at the beginning of the pattern, specifies the start of a (sub-)domain of the URL.

'^' : Separator character: This matches anything except a letter, a digit or one of the following: _ - . %.
[and so on...]

@joey04
Copy link

joey04 commented Jan 9, 2019

This new API is even worse than being restricted to 30k ABP-style rules -- the rules must also be in a single, bundled json file. Thus any rule changes means a full extension update. (Blockers restricted to this API would be "static" in every way.)

Thinking big picture, it's not that surprising. Last year Google started to bundle a lightweight ad blocker in Chrome, and I recall thinking that something like this would happen. On the bright side, perhaps this could be a boon to Mozilla, assuming they don't foolishly neuter their API in the same way.

@Kusresa
Copy link

Kusresa commented Jan 9, 2019

It is still a draft but is really a big downgrade if it stays this way. Looks to me like Google is doing this to reduce the amount of damage malicious extensions could do using this API by severely limiting the existing one and calling it a privacy and efficiency win....while of course giving more control to Google over what ads/trackers/requests can be blocked. This affects trusted and more advanced extensions like uBO the most.

Hopefully Mozilla and other browser makers don't follow suit on this..

@jspenguin2017
Copy link

jspenguin2017 commented Jan 10, 2019

declarativeNetRequest in its current state is really underpowered and isn't going to be enough. However, assuming that they will implement a way to modify the rules and the 30k limit will be raised or removed, it looks like the only thing missing is RegExp rules.

Since we will be able to dynamically modify content scripts, we can still implement scriptlets and cosmetic filtering properly.

@uBlock-user
Copy link
Contributor

It's still not set in stone, so lets see where it goes.

@gorhill
Copy link
Member

gorhill commented Jan 21, 2019

It's still not set in stone

The fact that they are planning to remove a proper blocking webRequest API with no word of an equivalent replacement is a sign of intent, that is, reducing the level of user agency in their user agent (aka Google Chrome).

How to do this? Use privacy/performance as Trojan arguments to rationalize reducing user agency over what all bloated web sites throw at people's user agents. That new declarativeNetRequest API seriously reduces what blockers can do, to the point they will become distinguishable only by their UI, not their capabilities. As a user, I personally wouldn't accept browsing the world wild web without the advanced features in uBO, I find this unthinkable.

There are no issue of privacy/performance with uBO, rather the opposite by giving back to users the power of clamping down on what web sites throw at them, so that argument is just plain fallacious as far as uBO is concerned.

Chromium got its webRequest API at a time it was trying to gain market share against Firefox (Sep 2011), where Adblock Plus, Ghostery, Disconnect, NoScript, and other such extensions were the most or among the most popular extensions on Firefox.

I don't expect Firefox to follow suit and also deprecate its own webRequest API.[1] I am confident uBO will still exist on Firefox.[2]


[1] Actually Firefox's own webRequest API is better designed as it's possible to return a Promise, which makes it possible to defer returning an answer to some point in the future.

[2] Which is already better equipped than Chromium's version of uBO -- example, example -- (and also better equipped than the Firefox legacy version).

@uBlock-user
Copy link
Contributor

uBlock-user commented Jan 21, 2019

is a sign of intent

Yes, but they're not doing this specifically targeting uBO, other blockers will be affected by this too, won't they ? So I still think it won't end up like this. Like you said, it will be the death of these two extensions, why would they bother doing that after all this time ? If they wanted to kill uBO, they could have done this years ago by deprecating APIs or limiting them.

@gorhill
Copy link
Member

gorhill commented Jan 21, 2019

I'm not saying they are targeting uBO specifically, more that they are targeting the capabilities expressed in uBO/uMatrix.

What is being said now is that the maximum capabilities content blockers will be allowed come down to a maximum of 30,000 ABP-compatible filters.

Even without dynamic filtering and per-site switches, etc., uBO already enforces over 90,000 filters (which themselves go beyond ABP filter syntax) with just the default filter lists, not counting the regional one which may be activated automatically at first install, and other commonly used ones such as Fanboy Social. When I select only EasyList, uBO reports 42,000 network filters, so even EasyList alone won't be enforceable with the declarativeNetRequest API.

Beside the low maximum of 30,000, ABP-compatible filters have no sense of specificity, hence why dynamic filtering can't be implemented with such approach (and if they did it would be a pain to have to recompile the whole filtering profile when merely adding/removing a rule/switch through a click). Also, this makes it impossible to implement important filter option, which purpose is to override exception filters.

So I still think it won't end up like this.

My comments are made with what is being said now with regard to manifest v3.

@androidacy-user

This comment has been minimized.

@uBlock-user
Copy link
Contributor

At this juncture, assuming it will get implemented, can you do something about it like not updating to v3 ? or should Chromium users be ready to abandon ship for good ?

@gorhill
Copy link
Member

gorhill commented Jan 21, 2019

should Chromium users be ready to abandon ship for good ?

I won't tell people what to do. I am pointing out that removing the blocking ability of the webRequest API means the death of uBO, I won't work to make uBO less than what it is now. I quote the document (my emphasis):

WebRequest

Summary

In Manifest V3, we will strive to limit the blocking version of webRequest, potentially removing blocking options from most events (making them observational only). Content blockers should instead use declarativeNetRequest (see below). It is unlikely this will account for 100% of use cases (e.g., onAuthRequired), so we will likely need to retain webRequest functionality in some form.

Currently uBO uses blocking listeners on both webRequest.onBeforeRequest (to implement static-, rule-, switch-based network filtering) and webRequest.onHeadersReceived (to implement disabling or restricting JS execution, static filters' csp= options, large media filtering, and other filtering capabilities).[1]

With this information on hands, everybody is free to decide for themselves.


[1] There are four listeners in the webRequest API which can be used in blocking mode: onBeforeRequest(uBO, uMatrix), onBeforeSendHeaders(uMatrix), onAuthRequired, onHeadersReceived(uBO, uMatrix). uBO uses two of them, uMatrix uses three of them.

@androidacy-user

This comment has been minimized.

@Kusresa
Copy link

Kusresa commented Jan 22, 2019

I think the best thing people can really do for now is to get the word out to extension developers and browser developers (especially Google) that the proposed APIs and manifest should not be restricted to such an extent and that users should retain enough freedom and capabilities to easily control what to do with extensions and requests within their browser.

Once the requests API in the manifest v3 proposal is set in stone and implemented it will be too late of a surprise for the majority of unaware extension users who will notice a shifting of how and what ads/trackers/requests get blocked and it will be near impossible to rollback the changes as the browser market leader has a low incentive to do so.

I don't want to sound too dramatic but the implementation of the requests API in the manifest v3 proposal as it is right now could be the beginning of something that will have wider implications on the web and users' ability to decide how they can browse it. Due to Google's position of power on the web and influence on websites it will almost certainly affect more than just Chromium/Chrome users.

@mapx-
Copy link

mapx- commented Dec 11, 2020

https://bugs.chromium.org/p/chromium/issues/detail?id=1054624#c9

Some of the future features are exciting but there are some omissions:

No include_globs and exclude_globs.

These are parts of the existing extension API, and in some cases only globs can provide a solution. If you still want to remove them then please use histograms/metrics to confirm the usage is below the removal threshold.

Missing RequestContentScript's features.

a) The ability to specify priority to reorder the scripts without re-registering the entire list. RequestContentScript used the system of filtered events so that was an inherent feature.

b) The much more flexible URL matching, particularly the simplified RE2 regular expression syntax. The absence of both RE2 syntax and globs in the new API, while simplifying the implementation of the API for Chromium developers, will force some of the extension authors to make their scripts run on more pages than necessary and use JS checks for location.href inside. This is somewhat wasteful.

c) RCS runs content scripts before document_start when DOM doesn't even contain documentElement. For user experience, this is often much better than document_start because the page is still being downloaded in background by Chrome, no DOM work is being done. Whereas when content scripts run at document_start they compete with the page scripts for DOM rendering time, which delays the early stages of page load. It's not that rare for several extensions to delay the initial render by 100ms or even more. If they could run before document_start (say, at document_create) they could initialize their state while the page is still being downloaded.

These features aren't crucial, admittedly, but they worked for almost the entire lifetime of Chrome and solved real problems. RequestContentScript, for example, would be a real hit and is under-used only because it's marked as experimental in documentation due to a couple of edge case problems.

@mapx-
Copy link

mapx- commented Jan 13, 2021

Firefox:
from https://bugzilla.mozilla.org/show_bug.cgi?id=1684703 (Performance issues by having any ad-blocker installed)

Masatoshi Kimura [:emk] |  

(In reply to Kershaw Chang [:kershaw] from comment 2)
Do you have an idea about what we can do here?

Migrating to Manifest v3? (deprecate blocking webRequest and implement declarativeNetRequest)

@gwarser
Copy link
Member

gwarser commented Jul 3, 2021

https://www.reddit.com/r/uBlockOrigin/comments/ntlgkv/update_on_manifest_3/h0snbbn/

gorhill4, Jun 06 2021:

I looked at the declarativeNetRequest API documentation a few days ago and I see that a functionality key to uBO has been added, i.e. the ability to assign a priority to filters, which is key to implement the important filter option, and also dynamic filtering. Given this, I may give a try to implement an MV3 version as a way to find out in a concrete manner which features will still be broken.

A big hurdle not addressed yet is the inability for filter lists to be updated dynamically without having to publish an update of the extension itself -- consider how often we ask people reporting filter issues here to "update your filter lists, this has been just fixed".

In any case, this does not solve the fundamental issue that having the matching algorithm set in stone in the browser will cripple innovations in content blockers. For instance, there would have been no need for a priority property in 2013, and had the declarativeNetRequest API been designed back then according to the need of the time, this would have meant a lot of innovations brought forth since then would have been prevented.

This is the main concern with the declarativeNetRequest API, we don't know yet which innovations will be required in the future for content blockers to still be able to perform in the best interests of users.

@gorhill
Copy link
Member

gorhill commented Jul 4, 2021

the ability to assign a priority to filters, which is key to implement the important filter option, and also dynamic filtering.

I looked more into this priority property. It does now allow to support the important option1, and does allow dynamic block/allow rules to have precedence over static filters, and to also to properly implement precedence between rules themselves (though an actual prototype would tell whether I overlook something).

However, it's still not possible to implement noop rules, which purpose is to ignore inherited block/allow rules and fall back strictly on static filters, and which is a key concept to dynamic filtering.

Summary, latest version of declarativeNetRequest, as per documentation, still breaks dynamic filtering in uBO, due to the inability to implement the noop concept. Suggestions welcome if somebody can think of a way to implement noop rules which I am not seeing.

There is also the issue of denyallow filter option, not supported by the declarativeNetRequest API. It might be possible to implement using negative lookahead complex regexes (which was what denyallow was meant to prevent in the first place), but given that the number of regex-based filters are further limited, this is another pain point of the declarativeNetRequest API.

Also, still no way to implement blocking according to response header content, so preventing the no-large-media-elements per-site switch, or the new experimental header= filter option. Also, no match for strict1p, strict3p, and so on as I looked more into the latest documentation.


[1] confirmed with a mini extension locally -- a higher priority block could take precedence over a lower priority allow filter

@uBlock-user
Copy link
Contributor

@gorhill
Copy link
Member

gorhill commented Sep 27, 2021

However, it's still not possible to implement noop rules

It might be possible to maybe implement noop rules through complicated negative lookahead regex-based filters. For example:

* * 3p-frame block
* * 3p-script block
github.com amazonaws.com * noop
github.com githubapp.com * noop
github.com githubassets.com * noop
github.com render.githubusercontent.com * noop

Maybe could be achieved with:

*$thirdparty,script,subdocument,domain=~github.com
/^[\w-]+:\/\/(?!(\S+\.)?amazonaws\.com\/|(\S+\.)?githubapp\.com\/|(\S+\.)?githubassets\.com\/|(\S+\.)?render\.githubusercontent\.com\/)/$thirdparty,script,subdocument,domain=github.com

This is only for medium mode with configuration for one single site. I wonder how this would look like for my current ruleset of 391 rules.

Again, as per declarativeNetRequest documentation, regex-based filters are limited to 1000 (and also as per declarativeNetRequest, a regex-based filter can be rejected).

And each time one would click to create/remove a temporary rule as is typically often done when working in medium or hard mode, uBO would have to recompile, remove and reinstall all the dynamic rules.

On the other hand, uMatrix does not require the concept of noop, and the priority property should allow the implementation of its matching algorithm.

In the end, only an actual prototype will be required to sort out for sure what is possible or not.

@gorhill
Copy link
Member

gorhill commented Nov 2, 2021

Given how the deprecation of a blocking webRequest API put a lid on innovations (and regressions in capabilities in the case of uBO) regarding content blocking, it does seem the move could be the "Not-Owned-But-Operated" strategy applied to content blocking -- the declarativeNetRequest API means the capabilities of (not-owned) content blockers are ultimately operated by Google through the limitations of the API the content blockers must use.

@gwarser
Copy link
Member

gwarser commented Dec 15, 2021

@gorhill
Copy link
Member

gorhill commented Dec 20, 2021

An example that the declarativeNetRequest ("DNR") API is an obstacle to innovation in content blockers.

In discussion with filter list maintainers, last year I implemented a new feature, the ability to use "entity" in domain= option.[1] The DNR API does support domain= option, but it does not support "entity", which is the ability to use a wildcard in place of the effective TLD, to avoid to list all domains belonging to an entity.[2]

I can count over 420 filters currently in the default filterset which uses this feature, clearly a benefit to filter list maintainers. These filters would cease to exist in a DNR-based blocker.

The core issue is the lid on innovation, which is key for content blocker to stay reliable. If the DNR API had been designed in 2014 according to the requirements of the time, content blockers would be awfully equipped to deal properly with the current landscape. The DNR API as designed now not only set back content blockers, but condemn content blockers to stagnate innovation-wise.


[1] https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#domain

[2] #1008 (comment)

@gorhill
Copy link
Member

gorhill commented Mar 25, 2022

There is also the issue of denyallow filter option, not supported by the declarativeNetRequest API.

There has been changes in the DNR API, and new conditions have been added which I think will allow to implement denyallow:

  • excludedRequestDomains
  • requestDomains

excludedRequestDomains= should be usable directly as a replacement of denyallow=:

The rule will not match network requests when the domains matches one from the list of excludedDomains [sic].


One thing I should have mentioned is that the new requestDomains property can be used to collate all filters (with same options) of the form ||hostname^ into a single filter. Assuming there is no limitation for the number of entries in a requestDomains option, this means 10s of 1000s of filters can be converted into a single filter. (Essentially, this is what uBO does internally with its FilterHostnameDict class)

@gorhill
Copy link
Member

gorhill commented Sep 4, 2022

Following AdGuard's publication of an experimental mv3-based version of their extension, I commented on Hacker News about the fact that the extension still required broad permission which leads to the warning "Read and change all your data on all websites" at install time.

This defeats Google's widely advertised (and repeated by many) statement that declarativeNetRequest will improve privacy:

The declarativeNetRequest API is an example of how Chrome is working to enable extensions, including ad blockers, to continue delivering their core functionality without requiring the extension to have access to potentially sensitive user data.

At the time of my comment, my understanding was that the broad permission required by AdGuard.MV3 was due to the fact that it still is required to implement cosmetic filtering and scriptlet injection.

However I found out that even if sticking to solely deal with network requests (no cosmetic filtering, etc.), broad permission to "read and change all your data on all websites" is still required still when supporting redirection or header modification, i.e. the redirect=, csp=, and removeparam= filter options.

The only way to avoid broad permission requirement is to use declarativeNetRequest to only block network requests and nothing else, i.e. throw out filters which are meant to redirect to a local resource (redirect=), filters which are meant to remove query parameters (removeparam=), and filters which are meant to further limit what websites are allowed to do by adding content-security-policy headers (csp=). For example, merely adding a simple switch to toggle JS on and off would require broad host-permissions (hence triggering the warning at install time), since this requires injecting scrpt-src 'none' in response headers to prevent JS execution.

@gorhill
Copy link
Member

gorhill commented Sep 9, 2022

Follow up regarding my above comment concerning requestDomains and excludedRequestDomains properties which were added to declarativeNetRequest API at some point (Chromium 101 as per documentation, so somewhere in April 2022).

The experimental uBO Minus MV3 version confirms the requestDomains property works well to dramatically reduce the number of rules as a result of filter lists conversion. For instance, with the default uBO filter lists, all the filters of the form ||hostname^ (or hostnames from hosts files such as Peter Lowe's) are being coalesced into a single DNR rule, such that what is typically counted as ~39K distinct network filters in uBO is being coalesced into a single DNR rule.

Overall, what is counted as ~82K distinct in uBO with default lists, is converted to ~21K DNR rules, thanks to the requestDomains property. This renders the DNR rule limits as quite less of an issue -- I estimate that even after adding one of the largest regional list, the DNR rule count in uBO Minus would still be under the 30K mark. For instance, consider that I use Steven Black's hosts in my own personal configuration, and theoretically the whole hosts file would fit into a single DNR rule (unless there is an undocumented limit about the number of entries in a requestDomains property). Sidenote: uBO proper uses such coalescing internally in its filtering engine to efficiently store/lookup large set of hostnames.

And as for the excludedRequestDomains I confirm that they are properly converted denyallow= filters, which in the past I identified as not convertible to DNR rules.

Additionally, the experimental version also confirms that the DNR priority property works well to implement the important filter option.


One of the biggest issue at this point is the inability to implement the overview pane in the popup panel, thus also preventing the implementation of the advanced-user mode and the ability to point-and-click to set dynamic rules.

There also can be no information about what is not blocked, i.e. the Domains connected figure in the popup panel. I have often argued that this is a more important piece of information than the number of blocked network requests.

The no-large-media-elements feature can't be implemented as this requires to inspect response headers on the fly.

The redirect-rule= filter option is also not compatible with DNR redirect action due to differing matching algorithm. In uBO, redirect filters do not compete with block/allow filters, as the redirect directives are looked up only after a network request has been matched to a block filter, whichever that is. This works differently in the DNR matching algorithm, redirect rules compete with other block and allow rules.

There is no concept of exception modifier filters in DNR, i.e. csp=/removeparam= exceptions cannot be accurately translated to DNR rules. For a specific example, all the removeparam= filter exceptions from AdGuard URL Tracking Protection, meant to override the main *$removeparam=utm_source filter, can't be converted to DNR. At best, those exception filters maybe could be less accurately be excepted using the excludedRequestDomains property of the main *$removeparam=utm_source filter.


Side note about the experimental uBO Minus MV3 extension: I did not pick the Minus part out of spite, it's to make clear that this is not uBO proper and I want to be sure there is no expectation that this will be the case. I picked Minus for the same reason that the Plus in Adblock Plus was to highlight that this was an improvement over the previous Adblock version.

Now the fact that uBO Minus does not require broad read/modify data on all websites can be seen as an improvement over uBO proper by many people who are uncomfortable with granting such broad permissions to an extension. In that case, if you have a better qualifier than Minus, I welcome suggestions.

@gorhill
Copy link
Member

gorhill commented Sep 15, 2022

Observation: One of the touted benefits of MV3 was faster review process when submitting to the Chrome Web Store. Well so far that is not the case, it's rather slow and the dev build of uBO proper even cleared review while the MV3 version is still pending review despite having no broad host permissions. Hopefully things will get better, but now this is a pain point.

@gorhill
Copy link
Member

gorhill commented Sep 21, 2022

Technical notes following a ~2 weeks marathon to get something onto MV3, uBO Lite.

When AdGuard AdBlocker MV3 Experimental was announced earlier this month, I examined the extension behavior. The key points that stood out for me upon examination:

  1. Still require broad permissions to "Read and change all your data on all websites" at install time -- thereby defeating one of the stated benefits of MV3 regarding privacy.
  2. Worrying CPU/memory usage due to the fact that the service worker associated with the extension is constantly evicted and re-spawned, every few seconds or when navigating to a webpage (observed from the browser's Task Manager, ShiftEsc) -- thereby defeating one of stated benefits of MV3 regarding performance.
  3. Busting per-extension rule limits (30K) with just the "Block ads" list enabled resulting in ~46K DNR rules, climbing to ~71K after enabling "Block trackers" list.

This motivated me to work on an MV3 version of a content blocker, hence came out uBO Lite (uBOL), i.e. a lite version of uBO to avoid the above issues.

Does not require "Read and change all your data on all websites" at install time

The only warning at install time is "Block content on any page", because of uBOL requests the declarativeNetRequest API for network filtering purpose.

This constraint means some filtering capabilities are not enabled out of the box, for instances cosmetic filtering and scriptlet-based filtering.

This is in line with the stated benefits of MV3. For instance, you may want to avoid giving extended permissions to uBOL while browsing your bank website, though you will still benefit from network filtering to block ads, trackers, etc.

However uBOL supports optional permissions, which let the user explicitly grant extended permissions on a given site. Once extended permissions are granted on a given site, uBOL will apply cosmetic and/or scriptlet-based filtering if any of these are present for that given site. (More details)

The extended permissions can be revoked at any time, through either uBOL's own user interface, or through the browser user interface.

This takes care of point 1. above.

No service worker required for network and extended filtering

uBOL is wholly declarative, meaning there is no need for its service worker to be running. uBOL's service worker exists when the user is interacting with its user interface, i.e. popup panel or option pages. When you do not interact with uBOL, its service worker is likely to be evicted by the browser at some point, while network and content filtering is still applied by the browser.

Network filtering occurs through the declarativeNetRequest API, while content filtering occurs through the scripting API.

The scripting is a great addition to MV3, it allows for more reliable content filtering by telling the browser what CSS/JS to inject in a page in a declarative way, and how and when to do it. Once uBOL tells the browser which exact CSS/JS to inject on a page (only after you explicitly grant uBOL extended permissions on a given site), the browser from then on will inject the resources without involving uBOL's service worker, in a very efficient and reliable way.

I have observed with the dev tools that the injection takes place very reliably, as documented. This sort of reliability was not possible with MV2 -- there is no race condition issues with MV3 with regard to uBOL's injected code versus a page's own code.

This takes care of point 2. above.

Coalescing as many distinct network filters into as few DNR rules

The declarativeNetRequest has undergone many improvements since the first time I looked at it (now) years ago. To be specific:

  • The priority property: this is a great addition and this solves the issue with regarding the important filter option, as this allows to have a block DNR rule to override a DNR allow rule, and vice versa. For instance, this property would probably make uMatrix's matching algorithm portable to MV3. (my mistake, uMatrix's rules matched against the tab URL, and MV3 does not allow that, see https://bugs.chromium.org/p/chromium/issues/detail?id=1191223)

  • The requestDomains property: This is a major addition, I mentioned this a few months ago (see above). This property allows uBOL to coalesce 1000s of network filters into a single DNR rule. This helps a lot with efficiently using DNR rules which are a finite resource due to the API-imposed limits. I feared there could have been a limit to the number of hostnames which can be assigned to this property, but I haven't encountered such limit. For instance the latest version of uBOL allows to enable Steven Black's Hosts File, which contains around ~140K filters, which all fit in only two DNR rules.

  • The excludedRequestDomains property: As I mention above months ago, this property allows to convert network filters with the denyallow option, so another great addition.

For instance, uBOL's default filter lists is that of uBO (minus "Online Malicious URL Blocklist", so blocks ads, trackers, and more out of the box), and as a result of the improvements above, it only uses ~20K DNR rules which correspond to ~76K network filters in uBO. This should allow to enable one or two regional lists without busting the API-imposed soft limit of 30K DNR rules per extension.

This takes care of point 3. above.


Issues encountered when working on uBOL.

The DNR's matching algorithm differs from uBO's matching algorithm regarding modifier filters (redirect=, csp=, removeparam), so currently all of these are dropped from uBOL. More time is needed to figure out how to best convert these filters despite the DNR's different matching algorithm compared to uBO's matching algorithm.

Generic cosmetic filters are another issue to investigate and decide whether these will be supported or not.

Given that cosmetic filtering is declarative, it's not possible to have an element picker to create cosmetic filters. This could be accomplish only through a service worker dynamically injecting those content filters, which as stated above would lead to point 2. -- something I want to avoid otherwise this would defeat the Lite in uBO Lite.

Since all filtering is done declaratively, this means there is no way to force an update of filters when something is fixed in filter lists, the fix will have to be published in the next version of the extension uploaded to the CWS.


Many users of uBO will dislike the limitations of uBOL when compared to uBO. There is no point complaining about it, it's just not for you, it's meant for another kind of users -- you do not have to use it. For the record, it's not for me either (I want/need the full control uBO allows me), but I want to offer an option for those who use uBO as an install-and-forget blocker without ever interacting with it.

@uBlock-user

This comment was marked as off-topic.

@gorhill

This comment was marked as off-topic.

@uBlock-user

This comment was marked as off-topic.

@gorhill

This comment was marked as off-topic.

@gorhill
Copy link
Member

gorhill commented Sep 26, 2022

Notes regarding removeparam= filter option, specifically I was looking to integrate the AdGuard URL Tracking Protection filter list, which purpose is to remove query parameters often used for tracking purpose.

The findings are that this filter list can't really be ported on a permission-less content blocker based on declarativeNetRequest API because host permissions must be granted for both the initiator domain and the request domain -- as per API documentation:

The declarativeNetRequestWithHostAccess permission always requires host permissions to the request URL and initiator to act on a request.

A majority of filters in that list looks as follow (excerpt):

$removeparam=utm_ad
$removeparam=utm_affiliate
$removeparam=utm_brand
$removeparam=utm_campaign
$removeparam=utm_campaignid
[...]

The fact that they are meant to remove the query parameters of any outgoing network request means that for these to work in an a priori permission-less extension would require the extension to request the *://*/* broad host permission, which the browser would warn with:

Screenshot from 2022-09-25 19-55-12

At which point it becomes pointless to be permission-less, and at which point we are back to defeating one of the stated benefits of MV3 regarding privacy.

In fact, the scary warning does not make sense at all with what is actually happening.

The whole purpose here is to remove query parameters used for tracking, and these query parameters are not data owned by the user as implied by the warning, these are data only useful to some undisclosed entities which are 3rd-party to the users and possibly to even the visited websites, and wanting to remove these should not be presented with a questionable warning that the extension is asking for read/write access to your data.

@gorhill
Copy link
Member

gorhill commented Sep 29, 2022

The official announcement doesn't make it clear whether we still can push updates to MV2 extensions after January 2023. The previous announcement said that as of January 2023:

Developers may no longer push updates to existing Manifest V2 extensions.


Side note regarding performance in MV3: although uBO Lite does everything declaratively, we must not assume that MV3 extensions will automatically be measurably more performant than their MV2 counterparts. The only way to make the case of enhanced performance is actual benchmarks which measure real world scenarios, and whether the differences if any are meaningful to end users.

I see too many comments presuming content blockers in MV3 will be more performant, but the only way to make such statements is objective performance measurements of real world scenarios (example).

At the moment, content blockers which require a up and running service workers appear to be doing worse than their MV2 counterpart, and for those not requiring an up and running service worker (as in uBOL), only benchmarking will tell whether they perform better, and if so by which amount. For instance, months ago I measured that uBO's network filtering matching algorithm was more performant than another well-known one compiled to native, so we should not presume one way or another regarding performance, sometimes the results are contrary to expectations.

@gwarser
Copy link
Member

gwarser commented Sep 29, 2022

@gorhill does this look relevant: w3c/webextensions#162 (comment) ?

@gorhill
Copy link
Member

gorhill commented Sep 29, 2022

I saw these results a few days ago but I don't think we can draw conclusions about the DNR's performance, except maybe that matching does not take more time than what is reported on these graphs. The timing measurements require that a Promise be fulfilled so it's not just the matching itself involved. Currently the built-in benchmark in uBO measures 7-8µs/request on average for uBO's default filter lists, so I really doubt the DNR would be above 1ms/request for just 20K rules.

@gorhill
Copy link
Member

gorhill commented Nov 30, 2022

@mapx-

I’m especially interested in what you can’t do with DNR that you could do with Web Request

At this point, this is what I observed:

  • No support for entity concept, i.e. the replacement of effective TLD part with a wildcard. This causes rejection of many filters when converting to DNR rules. Examples:
    • *$frame,denyallow=google.com,domain=slreamplay.*
    • *$script,3p,denyallow=chatango.com|facebook.net|fbcdn.net|google.com|googleapis.com|nolive.me|plyjam.me,domain=vipleague.*
  • No support for redirect-if-blocked concept. This causes rejection of many filters making use of the redirect-rule option.
    • ||indiatimes.com^$image,redirect-rule=1x1.gif
    • *$script,redirect-rule=noopjs,domain=linkneverdie.net
  • No support for regex-based for redirect / transform / removeParams. Examples:
    • ||ad.doubleclick.net/ddm/trackclk/$removeparam=/^dc_trk_/
    • ||linkedin.com^$removeparam=/^trk/
  • No support for the concept of exception of redirect/transform or modifyHeaders rules. Examples:
    • @@||s.click.aliexpress.com/deep_link.htm?aff_short_key=$removeparam=aff_short_key
    • @@||transfernow.net/*/dltransfer$removeparam=utm_source
    • @@||hqq.*/sec/player/*$csp
    • @@||1movies.*/*.html$csp,1p
  • No support for strict-partyness. Examples:
    • /^https?:\/\/[-.0-9a-z]+\/script\.js$/$script,1p,strict3p,match-case

Addendum:

  • I overlooked this one: not possible to create DNR rules with a condition about the root frame. Currently DNR rules can't be conditional to the URL of the root frame, and this is essentially how all of dynamic filtering works in uBO. Related Chromium issue.

@mapx-
Copy link

mapx- commented Nov 30, 2022

ok, I've notified @dotproto on slack

@uBlock-user
Copy link
Contributor

uBlock-user commented Nov 30, 2022

No support for $header too ?

@gorhill
Copy link
Member

gorhill commented Nov 30, 2022

header has not come out of experimental, so it's not currently used in lists. header though is an example of the argument that DNR is an obstacle to innovation.

@gwarser
Copy link
Member

gwarser commented Apr 13, 2023

uBlock Lite vs. uBlock Origin

uBO Lite:

https://www.reddit.com/r/uBlockOrigin/comments/1067als/eli5_ublock_lite_vs_ublock_origin/

@MasterKia
Copy link
Member

MasterKia commented Nov 17, 2023

https://developer.chrome.com/en/blog/resuming-the-transition-to-mv3/

We will begin disabling Manifest V2 extensions in pre-stable versions of Chrome (Dev, Canary, and Beta) as early as June 2024, in Chrome 127 and later.

Users impacted by the rollout will see Manifest V2 extensions automatically disabled in their browser and will no longer be able to install Manifest V2 extensions from the Chrome Web Store.

Also in June 2024, Manifest V2 extensions will lose their Featured badge in the Chrome Web Store if they currently have one.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Chromium specific to Chromium/Chrome something to address something to address
Projects
None yet
Development

No branches or pull requests