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

[Feature Request] Allow JSON stringified values for matching in suppress-native-method and replace-argument #3536

Open
9 tasks done
seia-soto opened this issue Jan 28, 2025 · 0 comments

Comments

@seia-soto
Copy link

seia-soto commented Jan 28, 2025

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 YouTube, Facebook or Twitch report. These sites MUST be reported by clicking their respective links.
  • 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

Currently trusted-suppress-native-method and trusted-replace-argument do support matching arguments with regular expression. However, it's capability could be extended by allowing matching with JSON stringified value. Considering that JSON.stringify method is lighting fast, I'd say this is not a big overhead to this scriptlet. (I'm not saying this scriptlet is lightweight)

This can help more complex cases in the future by looking at the current frontend library structure. For an instance, they should pass specific code paths that are responsible for routing and rendering regardless of website complexity. In their function calls, most data are preserved as an object which hides all the details when expressed in string without a proper stringifier (e.g. [object Object]). This completely makes possible for websites to avoid being caught in this scriptlet once they avoid to use JSON.parse.

The addition of JSON.stringify is more than enough since we're able to match shapes of object with regular expression.

diff --git a/src/js/resources/replace-argument.js b/src/js/resources/replace-argument.js
index 638eaeee6..fd2e9817a 100644
--- a/src/js/resources/replace-argument.js
+++ b/src/js/resources/replace-argument.js
@@ -96,7 +96,10 @@ export function trustedReplaceArgument(
         }
         const argBefore = getArg(context);
         if ( extraArgs.condition !== undefined ) {
-            if ( safe.RegExp_test.call(reCondition, argBefore) === false ) {
+            if (
+                safe.RegExp_test.call(reCondition, argBefore) === false &&
+                safe.RegExp_test.call(reCondition, JSON.stringify(argBefore)) === false
+            ) {
                 return context.reflect();
             }
         }
diff --git a/src/js/resources/scriptlets.js b/src/js/resources/scriptlets.js
index 20a34f30e..83cc73833 100755
--- a/src/js/resources/scriptlets.js
+++ b/src/js/resources/scriptlets.js
@@ -3348,7 +3348,10 @@ function trustedSuppressNativeMethod(
                 }
             }
             if ( signatureArg.type === 'pattern' ) {
-                if ( safe.RegExp_test.call(signatureArg.re, targetArg) === false ) {
+                if (
+                    safe.RegExp_test.call(signatureArg.re, targetArg) === false &&
+                    safe.RegExp_test.call(signatureArg.re, JSON.stringify(targetArg)) === false
+                ) {
                     return context.reflect();
                 }
             }

Moreover, we could discuss about supporting optional textContent property search for HTMLElement once we feel its necessity when [object HTMLElement] level of verbosity is not enough. However, I'd say this JSON.stringify addition will solve the desire for most of cases.

A specific URL where the issue occurs.

https://namu.wiki/w/%EB%8C%80%ED%95%9C%ED%95%AD%EA%B3%B5

Steps to Reproduce

(none)

Expected behavior

In case of Vue.JS based websites, we will be able to hook most of data load path with extended scriptlet capability.
See this Object.isExtensible call for an instance: https://github.com/vuejs/core/blob/29216853d4eb2bc72c284bcc5234afbca9c81854/packages/reactivity/src/reactive.ts#L59

The given website: namu.wiki is also based on Vue.JS, which means we already know the most vulnerable code paths:

// pprint version of https://namu.wiki/skins/espejo/rigiljec.2a905515850c3f7d0f21.js
    function Ct(t) {
        return !(0,
        r.hasOwn)(t, "__v_skip") && Object.isExtensible(t) && (0,
        r.def)(t, "__v_skip", !0),
        t
    }

There're more code paths we may hook but I expect they're heavy: e.g. TextDecoder.prototype.decode.

Actual behavior

(none)

uBO version

1.62.0

Browser name and version

Version 128.0.6613.119 (Official Build, ungoogled-chromium) (arm64)

Operating System and version

Darwin MacBookPro.lan 24.2.0 Darwin Kernel Version 24.2.0: Fri Dec 6 18:40:14 PST 2024; root:xnu-11215.61.5~2/RELEASE_ARM64_T8103 arm64

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

No branches or pull requests

1 participant