Skip to content
This repository has been archived by the owner on Sep 9, 2022. It is now read-only.

Style injection? #161

Closed
fsmythe opened this issue Aug 19, 2014 · 25 comments
Closed

Style injection? #161

fsmythe opened this issue Aug 19, 2014 · 25 comments

Comments

@fsmythe
Copy link

fsmythe commented Aug 19, 2014

This code gets injected into the head of every page....

..Why is this happening?

<style id="ublock-preload-1ae7a5f130fc79b4fdb8a4272d9426b5">
[href^="http://www.faceporn.net/free?"]
{display:none !important;}</style>

Ignore the " "

@gorhill
Copy link
Contributor

gorhill commented Aug 19, 2014

[href^="] is not from any filter I know.

Do you have a URL which I can use to reproduce?

Never mind, your comment was mangled due to Github's markdown, I added proper escape code.

This filter is injected when there is a DOM element which matches [href^="http://www.face"] on the page. Usually it's because of the ubiquitous links to Facebook on so many pages.

Edit1: This is a filter present in EasyList: ##a[href^="http://www.faceporn.net/free?"].

Edit2: For the record: Adblock Plus injects the same rule in everypage unconditionally (along with 14,000+ others). uBlock injects only when there is a DOM element which matches [href^="http://www.face"] (so not every page). With Adblock Plus though, the rule is inserted in a shadow DOM directly as a CSS rule object, so although it can be found when inspecting the DOM, it's less obvious than with uBlock.

@gorhill gorhill closed this as completed Aug 20, 2014
@stuartpb
Copy link

stuartpb commented Oct 9, 2014

Why is this injected for every page with a [href^="http://www.face"]? And why isn't it in a shadow DOM like ABP?

@gorhill
Copy link
Contributor

gorhill commented Oct 9, 2014

Why is this injected for every page with a [href^="http://www.face"]

It's explained above... Injecting in every page with [href^="http://www.face"] is way less worst than injecting in every page, period (ABP). There are various kind of generic cosmetic filters, and the current one falls into the "high-medium generic" category, which purpose is to deal as efficiently as possible with filters in the form [href^="*://*"].

And why isn't it in a shadow DOM like ABP?

Because no code is taken from ABP, it's written from scratch.

@stuartpb
Copy link

stuartpb commented Oct 9, 2014

But why is it injected for [href^="http://www.face"] and not a[href^="http://www.faceporn.net/free?"]?

@gorhill
Copy link
Contributor

gorhill commented Oct 9, 2014

Because a dictionary is used to find matching cosmetic filters: the first 8 characters of the URL are used to lookup an entry in the dictionary. I chose to use 8 characters after analyzing the distribution of such filters in EasyList. More characters would cause too many of that kind of filters to end up in the high-high generic category, the most expensive in term of CPU. Less character would lead to even lower granularity, i.e. injecting more unrelated cosmetic filters.

I am not going to pick a less efficient implementation of such cosmetic filters because of the word faceporn. The same filter is injected unconditionally by ABP in every page. It is a complete non-issue for me.

@stuartpb
Copy link

stuartpb commented Oct 9, 2014

How about, after it finds a match on the shortened filter, it runs a check on the whole filter, so we don't get reduced selector performance on the live page? That won't reduce performance for the 99.9% of short filters that don't match, and it will increase CSS performance / DOM cleanliness by not injecting a rule for false positives.

@gorhill
Copy link
Contributor

gorhill commented Oct 9, 2014

How did you conclude of a "reduced selector performance"? You have a benchmark?

If there is was performance gain, I would do it. But there is none. This is the cosmetic filters which end up in the www.face dictionary entry when using "Fanboy's Social":

[href^="http://www.faceporn.net/free?"],
[href^="https://www.facebook.com/sharer/sharer.php?u="],
[href^="https://www.facebook.com/sharer.php?"],
[href^="http://www.facebook.com/sharer/sharer.php?"],
[href^="http://www.facebook.com/sharer.php?"],
[href^="http://www.facebook.com/share.php?u="]

So you have five true positives for one false positive. This means in the big picture that finer grained injection in the case of high-medium generics is likely to not be a net benefit CPU-wise. Note that these high-medium generics are as a rule injected at the same time of other CSS styles, so not injecting [href^="http://www.faceporn.net/free?"] is a non-issue style-injection-overhead-wise.

Your solution would require that all the above entry be checked against maybe all the URLs matching www.face. Not a good idea. In the big picture, the high-medium cosmetic filters are just one of the task uBlock has to perform, so I am not going to unduly focus on a non-issue of the word faceporn tucked away in the live DOM of a web page.

Having ideas about implementation is easy, validating them through real working prototypes is however the harder part.

@gorhill
Copy link
Contributor

gorhill commented Oct 9, 2014

Just for a bit of perspective re "DOM cleanliness", in the above exemple, I used this page, and uBlock injected a grand total of 20 CSS selectors.

With the same filter lists, ABP injected 19,386 CSS selectors.

This means uBlock injected 20 / 19,386 => 0.1% of what ABP injects.

I say uBlock is not doing bad re. DOM cleanliness. I am open to improve, but that will be on the basis of real data from benchmarking, just like I have been doing so far.

@stuartpb
Copy link

stuartpb commented Oct 9, 2014

On the subject of DOM cleanliness, why not put the style in a shadow root?

@gorhill
Copy link
Contributor

gorhill commented Oct 9, 2014

Open an issue, I will look into this in more details, I would want to check first cost or benefit mem and cpu-wise, if any.

I suppose not being in plain view of other javascript code is an advantage, as this would prevent uBlock's injected style tags from being tampered with by external js code.

@hmemcpy
Copy link

hmemcpy commented Mar 3, 2015

Hi, sorry to bump an old topic, but I just noticed the same thing on my own site:

[href^="http://www.linkbucks.com/referral/"],
[href^="http://www.faceporn.net/free?"]
{display:none !important;}

From what I can guess, this is the result of matching face* and the other link here must be because of LinkedIn (matching link*).
My question is, can't those rules be relaxed a bit? It is certainly alarming to find those links in the Chrome dev tools for those who are not familiar with how ad-blocking works.
Either way, aren't face* and link* (possibly others) just too general?

@gorhill
Copy link
Contributor

gorhill commented Mar 3, 2015

My question is, can't those rules be relaxed a bit?

EasyList is 3rd-party to this project, you need to contact maintainers of EasyList: https://forums.lanik.us/index.php

@gorhill
Copy link
Contributor

gorhill commented Mar 3, 2015

By the way, I used to identify the style tag(s) with an id/class which made it clear that this was injected by uBlock, however as it was pointed out to me recently, doing so sort of leaked information that the user was using uBlock, so I removed that id/class.

@mnpenner
Copy link

I just saw this injected into a blank page. There were no hyperlinks at all on my page, never mind one that started with http://face.

@gorhill
Copy link
Contributor

gorhill commented Mar 25, 2015

@mnpenner Any reason to not provide the URL?

@mnpenner
Copy link

@gorhill Yes. It occurred on a POST on a page I was debugging, after I got a white screen of death. Not something shareable.

I'm not quite sure what you're getting at with those source code links. Are you suggesting the filters were cached for domain? If so, that would explain it. I don't doubt there were facebook links on other pages.

@gorhill
Copy link
Contributor

gorhill commented Mar 25, 2015

I'm not quite sure what you're getting at with those source code links

Cosmetic filters for a site are cached as soon as they are used on at least one page of that site (site = hostname in URL).

The cached cosmetic filters for a site are injected on all pages of that site -- this allows to inject CSS style rules before the page loads.

So if there was one single page on the site for which [href="www.face"] was a match, the CSS selector [href^="http://www.faceporn.net/free?"] would be cached, and the site-based cache reused for other pages of the same site.

@murraybiscuit
Copy link

@hmemcpy I would be one of those devs that found it in the DOM inspector. I'll be honest, I thought it was something nefarious injected either server-side or at a browser level... glad to see it's innocuous.

@stuartpb
Copy link

It looks like this doesn't happen any more. Has this been tightened up?

@maxfenton
Copy link

+1 for the suggestion to relax this on www.face* and www.link* since just about a zillion websites have sharing links to Facebook or LinkedIn. Even just www.facep and www.linkb would make a difference.

@dvorapa
Copy link

dvorapa commented Jun 20, 2015

Another dev who just found it in Google Chrome devtools, but I've made a list of things I don't like and I want to change on this behavior:

What's wrong with that?

  • It adds this content as an last child of the body or head and alternating, once body, another time head. Why?
  • It shows even on webpages without any add at all
  • CSS selectors like E:nth-last-child(n) could be messed up
  • [href^="http://www.face"] and [href^="http://www.link"] are just too much specific

more in #1460

@Paul-Reed
Copy link

I'm having the same issue here:

[href^="http://www.faceporn.net/free?"],

appearing when I save the source of a webpage in google chrome.

@nico3333fr
Copy link

Sorry to come back to this issue, but inserting inline-styles is a bad idea for websites that have CSP policies activated and refusing inline styles. See https://github.com/nico3333fr/CSP-useful/blob/master/csp-wtf/README.md#ublock-and-faceporn-yes for example.

@AhmedHelalAhmed
Copy link

I have the same problem

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests