Chrome is right to remove the webRequest extension API

…but the proposed declarativeNetRequest API isn’t a good replacement. So where does that leave us?

Headline writers have had their fun over the last week playing on people’s mistrust of Google’s motivations and their governance of the Chromium web browser project. Despite the headlines: Google is not about to kill ad-blocking extensions in Chrome.

The crux of the matter is the proposed deprecation of the webRequest API in favor of the newer declarativeNetRequest API. The webRequest API let extension developers intercept all network requests, pause them while they evaluated and blocked or modify them in JavaScript, and only then begin fulfilling the requests.

These are quite powerful capabilities with big privacy, security, and performance implications.

The replacement declarativeNetRequest API gives extension developers much of the same capabilities, but moves evaluation of the network requests out of the extension’s JavaScript and into the browser engine itself. Extensions can prepare a list of up to 30 000 filter rules and either allow, block, or redirect a network request based on those filters. This is essentially how an ad-blocker works today.

EasyList, the most popular block list used by almost all the leading ad-blocking software, has over 70 000 rules. However, Brave Software put out a research paper in that shown that 90,2 % of those blocking rules were never used on the web’s 5000 most popular websites nor on a selection of 5000 randomly selected websites.

The selection of test websites came from Alexa Internet which is skewed towards desktop browsing. Chrome’s proposed upper limit should be more than sufficient for a pruned and well-maintained blocking list given these numbers.

The blocking list must be present in the extension at install time and can’t be updated without updating the entire extension. This is subject to Google’s extension review criteria and processes. This means you won’t be able to opt-out of something like AdBlock Plus’ Acceptable Ads program, as the proposed new API doesn’t allow for rulesets to be turned on or off in the same extension.

If anyone is looking for an anti-competition angle on this one then keep in mind that Chrome’s own built-in ad-blocker can dynamically update their blocking list independently from browser updates.

None of my own extensions that use the webRequest API today could be re-implemented using the proposed declarativeNetRequest API, despite most of their usage of the API center around redirecting requests using simple dynamic redirect rules.

declarativeNetRequest’s redirect action can only redirect to a static URL; meaning that you can’t redirect using the new API from a pattern like “*://www.youtube.com/embed/*” to “https://www.youtube-nocookie.com/embed/%2”. This is pretty much all my Privacy Enhanced Mode for Embedded YouTube Videos extension does, by the by. (Well, it also uses the webRequest API to tweak Content-Security-Policies to make websites that already whitelist youtube.com also whitelist youtube-nocookie.com.)

I don’t see any problems with the block action, however. It seems like a good idea for the vast majority of cases. Some extensions, like the EFF’s Privacy Badger that compiles lists of and blocks web beacons and trackers based on browsing activity (a method that breaks a fair number of websites), wouldn’t survive the transition.

Don’t get me wrong: removing the blocking webRequest API is a huge change that will break a lot of extensions. The API is also terrible to work with as developers can’t even use their browser’s own developer tools to inspect all the changes that their extensions are capable of making to a request.

There’s no guarantee that the webRequest API will work as browsers handle conflicts (two extensions wanting to modify or block the same request) by just ignoring one of the extensions. The extension isn’t notified when another extension is given the job in its place either, making it hard to troubleshoot. These limitations are true for webRequest in Mozilla and Microsoft’s WebExtension API; which are based on Chromium’s Extension API. declarativeNetRequest simplifies these limitations by always yielding to the most recently installed extension.

So there’s good reasons for it when extension developers tell you to remove all other extensions to use their extensions. The browser extension platform is kind of broken.

I believe we’d need to see some serious improvements to declarativeNetRequest for it to be a true replacement for webRequest, however. It must be capable of handling dynamic redirects were a new URL can be constructed using parts of the matched URL, overriding Content-Security-Policies to some limited extent (e.g. allowing the same content types to be loaded from a rewritten origin.), and adding and removing HTTP headers.

As an extension developer, I don’t want to lose the awesome powers that the old API gave me nor do I want to lose any of the cool extensions that depend on it. However, I also do concede that it was probably a huge mistake to add such a powerful API with such great potential to slow down the browser. I’m absolutely certain that Chrome would have preferred fixing the API if that was at all possible rather than replacing it with a new one.

webRequest was simply never designed to work on every network request coming out of your browser in a performant manner. declarativeNetRequest is.