Skip to content

Prevent uBO from hiding html or body when matched by a generic cosmetic filter #1692

Description

@peace2000

Prerequisites

I tried to reproduce the issue when...

  • uBO is the only extension
  • uBO with default lists/settings
  • using a new, unmodified browser profile

Description

There have been numerous occasions where Annoyance lists have blanked out websites because either html or body have contained values that have been matched by a generic cosmetic filter. This is a pretty common issue for Annoyance lists, though there have been a few occasions in normal adblocking as well.

Usually these issues have been fixed by adding :not(html) or :not(body) exception to the problematic generic filter.

I was wondering if it would be reasonable to add a safeguard measure to uBO: to prevent it from applying cosmetic filters, that have a match in html or body in websites where an user is visiting. I think that neither html or body should ever be blocked as that will result in a blank website.

One recent issue: easylist/easylist#8431 - https://webshop.elektroskandia.no/ was blanked out because body in that website had a value of .consent-summary-shown. It was matched by this generic GDPR banner filter: ##.consent-summary-shown. (It was later fixed by adding an exception: ##.consent-summary-shown:not(body)).

But that wasn't the only case. In Fanboy's Annoyance list, there are currently:

  • 260 :not(html) exceptions
  • 298 :not(body) exceptions

Adguard Annoyance:

  • 127 :not(html) exceptions
  • 160 :not(body) exceptions

Easylist:

  • 4 :not(html) exceptions
  • 7 :not(body) exceptions

I know these website blanking issues are mainly related to Annoyance lists that are not turned on by default in uBO, but they are still available and people use them. Not all issues get reported to filter list maintainers and there could be many unreported issues relating to these lists. Each :not(html) or :not(body) exception that currently exists, are related to fixing blank websites.

A specific URL where the issue occurs

https://webshop.elektroskandia.no/ (fixed now but this one is a recent case so I'll use it as a sample)

Steps to Reproduce

  1. Disable any possible Annoyance lists (to get rid of later added whitelistings)
  2. Add filter ##.consent-summary-shown to custom filters
  3. Go to https://webshop.elektroskandia.no/

Expected behavior

uBO would ignore this generic filter for this website, because it matches to the body element.

Actual behavior

Website is blanked, due to a match to the body element.

kuva

uBlock Origin version

1.37.3b13

Browser name and version

Firefox 91.0.1

Operating System and version

Windows 10

Activity

ghost added
enhancementNew feature or request
on Aug 22, 2021

peace2000 commented on Aug 23, 2021

@peace2000
MemberAuthor

@felix-22 thanks for links!

Yeah adding :not(body):not(html) after each generic entry systemically, would pre-emptively help and would completely solve this issue, I even suggested that same thing recently: easylist/easylist#8367 though it would bloat filterlist a bit. I don't know about performance impact. But encountering this same issue over and over again (hundreds of :not(html) and :not(body) exceptions) feels unnecessary as it would be possible to do pre-emptive measures.

kiboke commented on Aug 23, 2021

@kiboke

The best thing to do is to adjust blockers not to block body and html elements. The question is, could all major blockers work together to achieve that?

peace2000 commented on Aug 23, 2021

@peace2000
MemberAuthor

The best thing to do is to adjust blockers not to block body and html elements. The question is, could all major blockers work together to achieve that?

I hope so:

https://github.com/AdguardTeam/AdguardBrowserExtension/issues/1845
https://gitlab.com/eyeo/adblockplus/abc/adblockpluscore/-/issues/361

gorhill commented on Aug 23, 2021

@gorhill
Member

The best thing to do is to adjust blockers not to block body and html elements.

Majority of CSS selector-based cosmetic filters are enforced through user styles, this means internally each of those filters would need to be suffixed with :not(html):not(body), while ensuring they are still properly reported in the logger. It's not trivial.

mjethani commented on Aug 24, 2021

@mjethani

What if this is taken care of at the DOM surveyor level?

-            pendingNodes.add(document.querySelectorAll('[id],[class]'));
+            pendingNodes.add(document.querySelectorAll(':not(html):not(body)[id],:not(html):not(body)[class]'));

I'm guessing that this would cause issues for selectors containing descendant and child combinators.

peace2000 commented on Aug 24, 2021

@peace2000
MemberAuthor

If this were to be implemented, it still should be possible to be able e.g. to target html or body via different styling rules or via scriplets, the only thing that should be prevented is using display: none !important to them.

gorhill commented on Aug 24, 2021

@gorhill
Member

it still should be possible to be able e.g. to target html or body via different styling rules or via scriplets

The way I see it the automatic exclusion of html/body should apply only to generic cosmetic filters which are made of a single class or id identifier, so this means you would still be able to target html or body by using these explicitly.

gorhill commented on Aug 24, 2021

@gorhill
Member

I'm guessing that this would cause issues for selectors containing descendant and child combinators.

This is an interesting idea. The issue of combinators maybe could be solved by having a separate reporting for ids/classes taken directly from html/body elements.

mjethani commented on Aug 24, 2021

@mjethani

I'm guessing that this would cause issues for selectors containing descendant and child combinators.

To clarify, let's say there's a document like this:

<body>
  <article>article>
body>

And a filter like ##.page-body > article.

The document uses JS to add the page-body class to the body element.

If the DOM surveyor ignores the body element, the filter will never work?

gorhill commented on Aug 24, 2021

@gorhill
Member

If the DOM surveyor ignores the body element, the filter will never work?

When I say "separate reporting", I mean the ids/classes of html/body elements would be reported in special properties (not through these), and treated differently in the background process -- for these uBO would only look-up the complex set, and thus would be able to find and apply something like .page-body > article.

changed the title [-]Prevent Ubo from hiding html or body when matched by a generic cosmetic filter[/-] [+]Prevent uBO from hiding html or body when matched by a generic cosmetic filter[/+] on Aug 24, 2021

peace2000 commented on Aug 24, 2021

@peace2000
MemberAuthor

which are made of a single class or id identifier

There are some generics that have multiple values (samples from Fanboy's Annoyances):

##.js-stickyFooter.u-bottom0.u-fixed
##.u-zIndexMetabar.u-fixed
##.article-section > .ui-button-close
###coiOverlay[role="banner"][style*="flex"]

Though I agree that they are not very common.

peace2000 commented on Aug 24, 2021

@peace2000
MemberAuthor

Installed 1.37.3b15 and tested with the site (webshop.elektroskandia.no) and with the sample rule I gave (##.consent-summary-shown), works fine, thanks!

34 remaining items

krystian3w commented on Sep 6, 2021

@krystian3w

Maybe * aka all URL-s also need similar disable breakage.

Now possible use * to avoid create specific filter with :watch-attr() if someone must check ID/Classes/attribs injected very late into dom tree/main nodes.


E.g.:

https://czyodebrac.pl/co-to-za-numer-dzwonil/2147483647/

on page no longer works these generic filter:

##.cli-modal-open #cookie-law-info-bar

#cookie-law-info-bar is not body/html tag but "

".

or have very Race Conditon in uBO 1.37.3rc0, but 1.37.2 injected filter almost immediately.

gorhill commented on Jan 9, 2022

@gorhill
Member

High profile case involving highly generic cosmetic filter: uBlockOrigin/uAssets#11244.

gorhill commented on Jan 12, 2022

@gorhill
Member

Highly generic cosmetic filters should not longer affect html/body elements. To confirm, I used the original steps-to-reproduce, except with the following filter:

##[class*="consent-summary-shown"]

mtxadmin commented on Jan 12, 2022

@mtxadmin

I would propose to add article tag to html and body. Should I open a new issue?

gorhill commented on Jan 12, 2022

@gorhill
Member

Should I open a new issue?

No, doing what you suggest would just allow advertisers to use article to bypass cosmetic filters -- there is no restriction on the number of article tags in a page.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestfixedissue has been addressed

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions