From 7823d9807007af78f3743f88e0cad728c6f6393e Mon Sep 17 00:00:00 2001 From: Raymond Hill Date: Mon, 6 Nov 2023 09:10:21 -0500 Subject: [PATCH] Harden scriptlets which need to serialize function code into string Related issue: https://github.com/uBlockOrigin/uBlock-issues/issues/2907 --- assets/resources/scriptlets.js | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/assets/resources/scriptlets.js b/assets/resources/scriptlets.js index 476e88d55..ae1c0635a 100644 --- a/assets/resources/scriptlets.js +++ b/assets/resources/scriptlets.js @@ -49,6 +49,8 @@ function safeSelf() { const safe = { 'Array_from': Array.from, 'Error': self.Error, + 'Function_toStringFn': self.Function.prototype.toString, + 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg), 'Math_floor': Math.floor, 'Math_random': Math.random, 'Object_defineProperty': Object.defineProperty.bind(Object), @@ -1394,7 +1396,9 @@ function addEventListenerDefuser( let type, handler; try { type = String(args[0]); - handler = String(args[1]); + handler = args[1] instanceof Function + ? String(safe.Function_toString(args[1])) + : String(args[1]); } catch(ex) { } const matchesType = safe.RegExp_test.call(reType, type); @@ -2004,7 +2008,9 @@ function noRequestAnimationFrameIf( const reNeedle = safe.patternToRegex(needle); window.requestAnimationFrame = new Proxy(window.requestAnimationFrame, { apply: function(target, thisArg, args) { - const a = String(args[0]); + const a = args[0] instanceof Function + ? String(safe.Function_toString(args[0])) + : String(args[0]); let defuse = false; if ( log !== undefined ) { log('uBO: requestAnimationFrame("%s")', a); @@ -2072,7 +2078,9 @@ function noSetIntervalIf( const reNeedle = safe.patternToRegex(needle); self.setInterval = new Proxy(self.setInterval, { apply: function(target, thisArg, args) { - const a = String(args[0]); + const a = args[0] instanceof Function + ? String(safe.Function_toString(args[0])) + : String(args[0]); const b = args[1]; if ( log !== undefined ) { log('uBO: setInterval("%s", %s)', a, b); @@ -2134,7 +2142,9 @@ function noSetTimeoutIf( const reNeedle = safe.patternToRegex(needle); self.setTimeout = new Proxy(self.setTimeout, { apply: function(target, thisArg, args) { - const a = String(args[0]); + const a = args[0] instanceof Function + ? String(safe.Function_toString(args[0])) + : String(args[0]); const b = args[1]; if ( log !== undefined ) { log('uBO: setTimeout("%s", %s)', a, b);