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

Closed
MasterKia opened this issue Oct 26, 2023 · 3 comments
Closed

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

MasterKia opened this issue Oct 26, 2023 · 3 comments
Labels
enhancement New feature or request fixed issue has been addressed

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request fixed issue has been addressed
Projects
None yet
Development

No branches or pull requests

2 participants