Skip to content

Scriptlet to spoof CSS property value #2618

Closed

Description

@MasterKia

Prerequisites

  • I verified that this is not a filter list issue. Report any issues with filter lists or broken website functionality in the uAssets issue tracker.
  • This is not a support issue or a question. For support, questions, or help, visit /r/uBlockOrigin.
  • I performed a cursory search of the issue tracker to avoid opening a duplicate issue.
  • The issue is not present after disabling uBO in the browser.
  • I checked the documentation to understand that the issue I am reporting is not normal behavior.

I tried to reproduce the issue when...

  • uBO is the only extension.
  • uBO uses default lists and settings.
  • using a new, unmodified browser profile.

Description

What about a scriptlet that will return a different CSS property value to counter getComputedStyle() (maybe by proxying CSSStyleDeclaration.prototype.getPropertyValue) to foil sophisticated anti-blockers that check all CSS properties of an element (like megaup, aternos, ylilauta.org)?

example.com##+js(spoof-css, a[href*="ads/redirect/"] > img, clip-path, none)
example.com##a[href*="ads/redirect/"] > img:style(clip-path: circle(0) !important;)

A specific URL where the issue occurs.

.

Steps to Reproduce

.

Expected behavior

.

Actual behavior

.

uBO version

.

Browser name and version

.

Operating System and version

.

Activity

  1. krystian3w commented on Apr 28, 2023

    @krystian3w

    Why not:

    example.com##a[href*="ads/redirect/"] > img:spoof(clip-path: none !important;)
    example.com##a[href*="ads/redirect/"] > img:style(clip-path: circle(0) !important;)

    Based on migration ra, rc to pseudo-classes syntax.

  2. MasterKia commented on Apr 28, 2023

    @MasterKia
    MemberAuthor

    Nice idea. My only concern is that we might experience the same problem with ##body:remove-attr(oncontextmenu) sometimes not working on Chromium.

  3. krystian3w commented on Apr 28, 2023

    @krystian3w

    I suppose this trouble can only apply to javascript written with html attributes:

    https://www.w3schools.com/tags/ref_eventattributes.asp

    which is not recommended - actions should be created in the file or "<script> </script>" section (https://kornel-ski.translate.goog/pl/onclick?_x_tr_sl=pl&_x_tr_tl=en&_x_tr_hl=pl&_x_tr_pto=wapp).

  4. uBlock-user commented on Apr 28, 2023

    @uBlock-user
    Member

    ##body:remove-attr(oncontextmenu)

    Use ##body:remove-attr(oncontextmenu):watch-attr(oncontextmenu) then.

  5. krystian3w commented on Apr 28, 2023

    @krystian3w

    #2618 (comment) - This solve trouble with blocked right click on 99% of pages?

    #2403 (comment)

  6. gorhill commented on May 20, 2023

    @gorhill
    Member

    Based on migration ra, rc to pseudo-classes syntax.

    Spoofing requires to patch JavaScript calls, which can only be done in the page world. Code for procedural cosmetic filters execute in content script world.

  7. krystian3w commented on May 20, 2023

    @krystian3w

    And are there any plans to e.g. on musixmatch.com replace +js(ra, oncontextmenu, body, complete) to +js(nowoif, something)?

    https://github.com/uBlockOrigin/uAssets/blob/ee4ce452e50fccf8253a6014db44122f4faf5e38/filters/annoyances.txt#L2007

  8. gorhill commented on May 20, 2023

    @gorhill
    Member

    Can I get real world examples (preferably not requiring account) for which I can test such scriptlet?

  9. peace2000 commented on May 20, 2023

    @peace2000
    Member

    Can I get real world examples (preferably not requiring account) for which I can test such scriptlet?

    https://ylilauta.org/jorma/131700539

    To spoof that ##iframe.a has value display: block even if it's truly hidden?

  10. gorhill commented on May 20, 2023

    @gorhill
    Member

    When I use ##iframe.a, the frame is not hidden, is there an exception filter? If so I am not seeing it in the logger.


    Ok never mind, code stepping I see an exception filter, not reported in logger. It works if I use ##iframe.a.a.

  11. added a commit that references this issue on May 20, 2023
  12. MasterKia commented on May 24, 2023

    @MasterKia
    MemberAuthor

    On soft98.ir when I only add:
    soft98.ir##+js(spoof-css, a[href*="s0ft98.ir"], clip-path, none) or
    soft98.ir##+js(spoof-css, a[href*="s0ft98.ir"], nonsense, none)

    I get detection after a few seconds.

    But if I use this userscript:

    // @run-at      document-start
    
    (function () {
    'use strict';
    const handler = {
      apply(target, thisArg, args) {
        let response = Reflect.apply(target, thisArg, args);
        if (args == "clip-path" || args == "clipPath") {
          response = "none";
        }
        return response;
      }
    }
    
    const myProxy = new Proxy(CSSStyleDeclaration.prototype.getPropertyValue, handler);
    CSSStyleDeclaration.prototype.getPropertyValue = myProxy;
    
    }) ();

    and then use this filter:
    soft98.ir##a[href*="s0ft98.ir"]:style(clip-path: circle(0) !important;)

    Then I get no detection.

    Edit: added @run-at.

  13. gorhill commented on May 24, 2023

    @gorhill
    Member

    But if I use this userscript:

    I tried with ViolentMonkey and I still get detection with your script.


    Ok, seems to work when using // @run-at document-start.

  14. gorhill commented on May 24, 2023

    @gorhill
    Member

    Note that your code has an issue but it accidentally works because of truthiness. Should be:

    if (args[0] === "clip-path" || args[0] === "clipPath") {
    
  15. gorhill commented on May 24, 2023

    @gorhill
    Member

    Ok the page is doing something else than just checking the properties. For spoof-css to work on that site, I had to wholly remove the proxying of getComputedStyle(), so it does something with that call that triggers the detection.

  16. 3 remaining items

  17. Yuki2718 commented on Sep 10, 2023

    @Yuki2718
    Member

    Is it possible to specify not a static value but value obtainable from elements or scripts?
    On https://github.com/uBlockOrigin/uAssets/discussions/17361#discussioncomment-6960192 an excerpt of detection code https://www.btcbitco.in/myassets/aOW9dugd31nhaaOW9dugd31nhd.js?ver= (direct access forbidden even with parameter)

    Code
    function aOW9dugd31nhests() {
                
                    var done = 20;
                    
                    if (done === 0) {
                        setTimeout(function() {
                            if ($('.l-button').length > 0) {
                                $('.l-button').hide();
                            }
                            var aOW9dugd31nhe2 = document.getElementById('aOW9dugd31nhedz');
                            var aOW9dugd31nhe4 = aOW9dugd31nhe2.clientHeight;
                            if (!aOW9dugd31nhe2 || aOW9dugd31nhe4 != 97) {
                                if (typeof gtag === "function") {
                                    gtag('event', 'session_ends');
                                }
                                alert("Session ends, thanks for using GainLink.");
                                window.location.href = 'https://www.btcbitco.in/page/endsessions';
                            }else{
                            aOW9dugd31nhest();
                            }
                        }, 4000);
                    } else {
                        if ($('.l-button').length > 0) {
                            $('.l-button').hide();
                        }
                        setTimeout(function() {
                                var aOW9dugd31nhek = document.getElementById('aOW9dugd31nhedz');
                                var aOW9dugd31nheh = aOW9dugd31nhek.clientHeight;
                                if (!aOW9dugd31nhek || aOW9dugd31nheh != 97) {
                                    if (typeof gtag === "function") {
                                        gtag('event', 'ads_blocker_detected');
                                    }
                                      var aOW9dugd31nhec = confirm("Go ahead and turn off your adblocker? Click 'OK' if you agree to turn off your adblocker or 'Cancel' to stop here.");
                                      if (aOW9dugd31nhec === false) {
                                        alert("Session ends, thanks for using GainLink.");
                                        if (typeof gtag === "function") {
                                            gtag('event', 'session_ends');
                                        }
                                        window.location.href = 'https://www.btcbitco.in/page/endsessions';
                                      } else {
                                        alert("Please disable your adblocker and reload");
                                      }
                                }else{
                                    $.ajax({
                                        url: "https://www.btcbitco.in/page/validate?ver=1d75b01ce9033fe7764904b77212315e25779b17a25e77d79aafc9500edbd20e",
                                        type: "GET",
                                        success: function(response) {
                                            if (response === "valid") {
                                                aOW9dugd31nhest();
                                            } else {
                                                alert("Invalid response received!");
                                            }
                                        },
                                        error: function() {
                                            alert("An error occurred, please reload!");
                                            location.reload();
                                        }
                                    });
                                }
                        }, 1000);
                    }
                }
                window.onload = function() {
                  var aOW9dugd31nhevd = document.createElement("iframe");
                  aOW9dugd31nhevd.src = "https://cryptocoinsad.com/ads/show.php?a=256522&b=397269";
                  aOW9dugd31nhevd.style = "width: 100%; height: 97px; overflow: hidden; border: 0px; padding: 0px; background-color: transparent;";
                  aOW9dugd31nhevd.id = "aOW9dugd31nhedz";
                            
                  var aOW9dugd31nhezd = document.getElementsByClassName("entry-content")[0];
                  var aOW9dugd31nheparent = aOW9dugd31nhezd.parentNode;
                  aOW9dugd31nheparent.replaceChild(aOW9dugd31nhevd, aOW9dugd31nhezd);
      
                  function aOW9dugd31nhemm() {
                    var aOW9dugd31nheca = document.getElementById("aOW9dugd31nhedz");
                
                    if (aOW9dugd31nheca) {
                      clearInterval(aOW9dugd31nheid);
                      aOW9dugd31nhests();
                    }
                  }
                
                  var aOW9dugd31nheid = setInterval(aOW9dugd31nhemm, 1000);
                }
    
    They create a bait element with random height (here 97px, but varies on each load) and checks it. It's not inline so rpnt can't be used. As this is iframe, I just removed cosmetic filter and redirect=noop.html is enough, but the suggested capability may be useful.
  18. JobcenterTycoon commented on Nov 22, 2023

    @JobcenterTycoon

    kiktu.com doing the same now. A bait element getting added but with visiblity: hidden while the real element has visiblity: visible. Now the site checks if the bait has visiblity: visible or the real element visiblity: hidden and if yes -> Anti adblock.

  19. BlazeFTL commented on Nov 24, 2023

    @BlazeFTL
    Member

    Another issue terabox.fun/sl/3lsTuo98O3

    script Location is 3p
    Screenshot_20231124-115033_Firefox Nightly

    Is there any way to modify script values which arent inline ?... ideally what i do is replace the element they check with a element that wouldnt be blocked with rpnt

    Would something like Replace work for such cases ?

  20. stephenhawk8054 commented on Nov 24, 2023

    @stephenhawk8054
    Member

    $replace could work, but only Firefox

  21. krystian3w commented on Nov 24, 2023

    @krystian3w

    Own replace need bumping uBo to 1.54.1+ or works like trusted- scriptlets and we should share own idea to AdGuard (So that their add-on would not require bumping in the Moz://a store)?

  22. gorhill commented on Nov 25, 2023

    @gorhill
    Member

    Own replace need bumping uBo to 1.54.1+ or works like trusted- scriptlets

    I don't understand what is being said here.

  23. krystian3w commented on Nov 25, 2023

    @krystian3w

    Would something like Replace work for such cases ?

    $replace could work, but only Firefox

    Own replace need bumping uBo to 1.54.1+ or works like trusted- scriptlets

    So I ask, if stephenhawk8054 adds a filter, will it start in uBo 1.54.0 with a differential update or a full filter list alone, because if AdGuard would add it I would have to wait for the next version of the add-on in December 2023 or January 2024.


    This could be added to the wiki that our replace does not require an update of the entire add-on or that we have identically solved this as in AdGuard and such a filter will start after a month or in beta releases.

  24. gorhill commented on Nov 25, 2023

    @gorhill
    Member

    I still don't understand. replace= is available in 1.54.0 as a trusted-source filter option.

    Differential update has nothing to do with this, I don't know why you mention this, and I also don't understand why you mention AdGuard.

  25. krystian3w commented on Nov 25, 2023

    @krystian3w

    I ask here because that's what BlazeFTL did.

    My question is whether the $replace= filter added today to filters-2023.txt requires an update of stable ubo 1.54.0 to 1.54.1 (beta) or 1.54.2 (stable) to not break the Moz://a store limitation/policy/restriction.

    For example, AdGuard $replace= has to wait for a new version of the add-on, and it is unlikely that the developers check whether the old restriction is already dead in order to keep the filter active without a forced update of the entire extension.

  26. gorhill commented on Nov 25, 2023

    @gorhill
    Member

    AdGuard $replace= has to wait for a new version of the add-on

    You have a source for this? I used the debugger in Firefox and I can see AdGuard parse replace= filters when updating AdGuard Base.

  27. BlazeFTL commented on Apr 19, 2024

    @BlazeFTL
    Member

    Spoof-css Makes Stuck At Checking Browser In FF Android
    Random Anti Adb On Chrome Based Browser🥲
    https://devuploads.com/fcdlxmzxep5o
    Filters Used

    jytechs.in,dev.miuiflash.com,djxmaza.in,thecubexguide.com##[id*="div-gpt-ad-"], [id*="google_ads_"], #featuredimage, [href*="random-affiliate.atimaze.com"]:style(visibility: collapse !important;)
    jytechs.in,dev.miuiflash.com,djxmaza.in,thecubexguide.com##+js(spoof-css, [id*="div-gpt-ad-"]\, [id*="google_ads_"]\, #featuredimage\, [href*="random-affiliate.atimaze.com"], visibility, visible)
    
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