Privacy updates

Procedural filtering for better adblocking

By the Brave Privacy Team

This is the 31st post in an ongoing series describing new privacy features in Brave. This post describes work done by Anton Lazarev (Senior Adblock Research Engineer), Stephen Heaps (Senior Software Engineer, iOS), and Pete Snyder (Principal Privacy Researcher). This post was written by Shivan Kaul Sahib (Lead for Privacy Engineering).

Starting with version 1.73 on all platforms, Brave is significantly improving its adblocking capabilities by adding support for procedural cosmetic filtering of page elements. This means that Brave will block more ads, break fewer websites, and be more precise with blocking intrusive page elements.

Brave already offers best-in-class ad and tracker blocking. We block privacy-harmful network requests to trackers, which prevents ad companies and data brokers from following you around the Web. This also has the nice side effect of boosting performance and making the Web less cluttered. Sometimes, however, blocking third-party ads will cause websites to break visually: there’s blank space where the ad would’ve been. Plus, in some cases, it’s not possible to block ads via network request blocking because the ad content is mixed in with the website’s content.

To get around this, Brave does cosmetic filtering of unwanted page elements, where we hide page elements using CSS selectors. In the following example, we can find and block the ad element by targeting elements using CSS classes “post” and “ad”.

An example of markup where ad elements are clearly identifiable

Not all elements can be hidden by CSS selectors. CSS is declarative, meaning it controls the appearance and layout of a page based on the page’s structure rather than content. This makes it harder for us to tell the difference between an ad and other page content when an ad is made to look similar to the rest of the page. In the following example, the CSS class name for the element that contains a friend’s social media post (that the user wants to see) is the same as the CSS class name for a promoted ad element (that the user does not want to see). CSS alone cannot block the ad without also hiding other posts, which would effectively break the website. Additionally, in cases where the website’s CSS class attributes are auto-generated, non-distinctive, and constantly changing, matching on CSS causes frequent breakage.

An example of markup where ad elements are not clearly identifiable

Procedural (as opposed to declarative) cosmetic filtering overcomes this by letting us describe how to target an element to hide. Procedural filtering lets us define conditions like “block list elements containing the text BUY THIS PRODUCT”. This allows for fine-grained matching on page elements: we can target elements containing specific words, meeting a minimum text length, or with a particular HTML ancestor. All in all, this significantly expands the kind of unwanted content we can block on the Web.

A list of procedural operators, and how they behave

As a reminder, Brave blocks third-party ads and trackers by default. We also offer an optional Aggressive blocking mode that blocks all ads, even first-party. We expect procedural filtering to be especially impactful in Aggressive mode.

Procedural filtering is a long-awaited feature that was technically challenging to pull off in a performant way. We’re excited to have you see the benefits!

Related articles

Ready for a better Internet?

Brave’s easy-to-use browser blocks ads by default, making the Web faster, safer, and less cluttered for people all over the world.