Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use safe Function.prototype.toString() in scriptlets #2907

Open
MasterKia opened this issue Oct 26, 2023 · 4 comments
Open

Use safe Function.prototype.toString() in scriptlets #2907

MasterKia opened this issue Oct 26, 2023 · 4 comments
Labels
enhancement New feature or request

Comments

@MasterKia
Copy link
Member

MasterKia commented Oct 26, 2023

Some sites (or libraries) tamper with Function.prototype.toString which is used in these scriptlets to match against the handler function:
addEventListener-defuser, no-setInterval-if, no-setTimeout-if, adjustSetInterval, adjustSetTimeout, noeval-if

Example 1

Add:

noorlib.ir##+js(aeld, copy, dontMatch, log, 2)

Visit:
https://noorlib.ir/book/view/30999?pageNumber=10&viewType=pdf
See in console:

[uBO] addEventListener('copy', function() {
    [native code]
})

Use this userscript:

(function() {
  const safe = {
    'toString': self.Function.prototype.toString,
    'log': console.log.bind(console)
  }

  self.EventTarget.prototype.addEventListener = new Proxy(self.EventTarget.prototype.addEventListener, {
    apply(target, thisArg, args) {
      const originalToString = String(args[1]);
      const safeToString = safe.toString.call(args[1]);
      if (originalToString !== safeToString && args[0] === 'copy') {
        safe.log(`${args[0]}\n\n[Original toString] ${originalToString}\n\n[Safe toString] ${safeToString}`)
      };
      return Reflect.apply(target, thisArg, args);
    }
  });
}) ();

See in console:

function(){var r=Array.prototype.slice.call(arguments);try{n&&"function"==typeof n&&n.apply(this,arguments);var o=r.map((function(t){return _e(t,e)}));return t.apply(this,o)}catch(t){throw ye+=1,setTimeout((function(){ye-=1})),H((function(n){n.addEventProcessor((function(t){return e.mechanism&&(Object(y.b)(t,void 0,void 0),Object(y.a)(t,e.mechanism)),t.extra=Object(a.a)(Object(a.a)({},t.extra),{arguments:r}),t})),D(t)})),t}}

The tampered toString():

function(){for(var t=[],e=0;e<arguments.length;e++)t[e]=arguments[e];var n=Object(O.f)(this)||this;return He.apply(n,t)}

Example 2

On soft98.ir, enter in console:

(() => {}).toString()

See "function() { [native code] }" instead of "() => {}".

The tampered toString():

"function(){return en()}"

Example 3

On extremereportbot.com, enter in console:

iframe = document.createElement('iframe'); document.body.appendChild(iframe); safeToString = iframe.contentWindow.Function.prototype.toString; console.log(safeToString.call(Function.prototype.toString))

See function toString(){return"function"==typeof this&&this[a]||e.call(this)} instead of "function toString() { [native code] }"

gorhill/uBlock#3901

@gorhill
Copy link
Member

gorhill commented Nov 6, 2023

I would prefer to fix on a per-scriptlet basis, to minimize the chance of unforeseen breakage -- especially that I want the current dev build to enter release candidate mode. I fixed the case of aeld -- for the other sites, what are the scriptlets suffering the issue?


Ok I also added nostif, nosiif, and noraif, I think that should cover most if not all cases.

@MasterKia
Copy link
Member Author

minimize the chance of unforeseen breakage

There are 17 filters in uBO ads and annoyances list which use [native code] as their function matching.

With this here change, we might need to update those filters. I'll check them in a few days.

MasterKia added a commit to uBlockOrigin/uAssets that referenced this issue Nov 9, 2023
MasterKia added a commit to uBlockOrigin/uAssets that referenced this issue Nov 9, 2023
@MasterKia
Copy link
Member Author

Fixed all instances I could test. I'll close this issue after the next stable release is widespread.

@MasterKia MasterKia added enhancement New feature or request fixed issue has been addressed labels Nov 9, 2023
@MasterKia
Copy link
Member Author

noeval-if scriptlet breaks Cloudflare on some sites because of the toString() value.

Related: AdguardTeam/Scriptlets#481
Example site:
AdguardTeam/AdguardFilters#198508

@gorhill

@MasterKia MasterKia reopened this Feb 14, 2025
@uBlock-user uBlock-user removed the fixed issue has been addressed label Feb 15, 2025
gorhill added a commit to gorhill/uBlock that referenced this issue Feb 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants