JavaScript - 使代理无法检测

2023-12-19

据我了解,ES 规范是这么说的Proxy(用于代理对象、函数和类的全局构造函数)不可检测。这意味着如果我代理一个函数,使用该代理函数的任何人都无法检测到我使用了代理。然而,显然我误解了它,因为代理功能是可以检测到的。

例如,new Proxy(a=>a,{apply:a=>a})+''抛出错误。它说

Uncaught TypeError: Function.prototype.toString requires that 'this' be a Function

然而,typeof new Proxy(a=>a,{apply:a=>a})确实是"function",但它以某种方式无法对代理进行字符串化。因此,显然,在这种情况下,代理函数的行为与非代理函数的行为不同。Function.prototype.toString能够区分代理函数和非代理函数。

我的目标是代理一个函数,使其变得不可检测。我的第一个想法是像这样真正代理代理:

Proxy.toString = (a => () => a)(Proxy + '');
Proxy = new Proxy(Proxy, {
  construct: (f, args) => {
    if(typeof args[0] == 'function'){
      var a = args[0] + '';
      args[0].toString = () => a;
    }
    return new f(...args);
  }
});

但遗憾的是,这是可以检测到的。如果有人打电话Function.prototype.toString绑定到我的代理函数,就会发生错误,因此他可以检测到我的函数实际上是代理。所以,我尝试代理Function and Function.prototype并且Function.prototype.toString,但后来我意识到我无法代理Function因为即使我覆盖全局属性Function,有人可以使用它来访问它(a=>a).constructor.

所以,这就是我在这里问这个问题的原因,因为我没有想法了。如何代理一个函数以使其完全无法检测到?在 ES 规范中明确指出“代理无法检测到”,那么作为一个附带问题,为什么代理一个函数可以被检测到呢?

Edit

我试图实现这一目标的原因是因为我正在为 Chrome 开发增强型广告拦截扩展。我正在处理非常激进的网站,该网站利用大量 JavaScript 技巧来检测我是否正在查看广告。所以,基本上,我删除了一个广告,然后他们的脚本检查是否有特定元素,如果没有,那么我无法访问该网站。所以,我尝试代理document.getElementById,但他们会检查它是否被代理,如果是,我将无法访问该网站,因此我必须使其无法检测到。


我对这个问题有几个部分答案/评论:

1.首先:浏览器的行为似乎同时发生了变化。 Chrome 106 和 Firefox 105 都不再抛出初始示例中描述的类型错误,但它们仍然为toString()方法比原始对象:

 new Proxy(a=>a, {apply:a=>a}) + ''

导致以下结果toString()返回值:

'function () { [native code] }'

而原始 lambda 表达式(a=>a) + ''简单地产生

'a=>a'

2. OP 试图改变toString代理对象的实际上正在改变toString- 目标方法args[0](这是a=>a)通过始终对其自身进行评估args[0] + ''(从而消除任何this)。因此,当重新定义toString使用代理调用目标的函数,如下所示this争论,已经没有什么区别了。

对于任何在搜索如何分配自定义的问题时绊倒的人toString对于代理(不要求不可检测),也许应该提及在不更改目标的情况下执行此操作的标准方法: 可以用以下方法完成get https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/get- 处理程序的陷阱,因此将处理程序扩展为:

{
    apply: a=>a,
    get(target, prop, receiver) {
       if(prop == "toString") {
          return target.toString.bind(target);
       } else {
          return Reflect.get(target, prop, receiver); // or your favorite forwarding
       }
    }
}

这也产生相同的结果toString()代理和目标的答案。通过将其他函数属性一般绑定到目标,可以使“else”情况变得更有用,至少如果它们没有显式绑定到不同的接收器(请参阅私有财产转发 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy#no_private_property_forwarding).

3. OP的全局替换问题Function不过,这是可以克服的。至少我是这么认为的。确实有参考原著的Function其实例的构造函数:

(a=>a).constructor === Function; // true

但我们不需要替换 Function 本身,只需替换它的属性,或者更准确地说,甚至不需要替换这些属性,而只需替换其属性的属性之一。考虑以下简单的重新定义。它不是很复杂(仅针对一个代理),但至少可以完成这项工作toString该代理的属性:

const proxy = new Proxy(a=>a,{apply:a=>a});
{
    const nativeToString = Function.prototype.toString;
    Function.prototype.toString = function() {
        return this === proxy? "a=>a" : nativeToString.call(this);
    }
}

现在至少这个测试是成功的:

 (x=>x).constructor.prototype.toString.call(proxy); // returns "a=>a" 

4.然而,作为@jmrk 在他的回答中指出 https://stackoverflow.com/questions/45688944/javascript-make-proxy-undetectable/45698826#45698826,代理可检测的原因是存在一些特殊的内部槽,这些槽无法通过代理处理程序陷阱拦截。后者仅拦截标准对象内部方法 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy#object_internal_methods。因此,任务是找到通过外部 javascript 调用触发这些内部槽的所有方法,然后覆盖相应的全局可访问函数,就像使用toString()多于。我不确定触发内部插槽的进一步方法Function,但是当尝试使用代理来替代代理时也会出现同样的问题HTMLElement https://stackoverflow.com/questions/56008415/how-to-create-a-proxy-for-htmlelement,我们称之为htmlProxy。在这种情况下调用getComputedStyle(htmlProxy)抛出类型错误,即使htmlProxy标识为 HTMLElement。相似地element.insertNode(htmlElementProxy)抛出异常。似乎需要重新定义所有这些全局可访问的触发函数,以使代理无法检测到。

内部槽可以看作是内置对象的私有属性。因此,非内置类/对象的私有属性出现同样的问题也就不足为奇了。可以使用上面(第 2 点)提到的私有财产转发 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy#no_private_property_forwarding当通过代理调用访问私有属性的方法时,获得与目标对象相同的代理行为。假设我们有someObject类型的SomeClass与私人成员#member和一个公共吸气剂getMember。然后我们可以做代理someObject通过转发也成功调用此函数this到目标,这样proxy.getMember()只会给成员someObject。但是,如果有人打电话SomeClass.prototype.getMember.call(proxy),又会出现异常,唯一的办法就是重新定义SomeClass.prototype.getMember.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JavaScript - 使代理无法检测 的相关文章

  • 在特定页面上执行 javascript 的正确“Rails”方式

    我试图在特定页面上运行 javascript 而我唯一的解决方案似乎是反模式 我有controller js内部生成的assets javascripts 我在用着gem jquery turbolinks 我的代码类似于以下内容 docu
  • 从函数返回函数的目的是什么?

    阅读一些遗留代码 发现 A prototype setSize function var v1 new Vector2 return function size var halfSize v1 copy size multiplyScala
  • 位置特征检测:固定

    我正在尝试找到一个脚本来检测设备是否放置position fixed元素相对于视口而不是整个文档 目前 标准桌面浏览器和 Mobile Safari 适用于 iOS 5 都是这样做的 而 Android 设备则相对于整个文档放置固定元素 我
  • 如何在没有 jQuery 的情况下删除 Javascript 中的元素

    我试图通过以下方式从 DOM 中删除 Div a 标签嵌套在其中 我想我正在寻找的是 jQuery 的纯 Javascript 版本 div remove 这是html设置 div a href Click me to remove the
  • .push() 将多个对象放入 JavaScript 数组中返回“未定义”

    当我将项目添加到beats数组然后console log用户时 我得到了数组中正确的项目数 但是当我检查 length 时 我总是得到 1 尝试调用索引总是会给我 未定义 如下所示 Tom beats 1 我想我错过了一些明显的东西 但这让
  • 在版本 4.4.6 中禁用 ckeditor 上下文菜单

    我在 Rails4 项目中使用 ckeditor 我尝试了 ckeditor gem 和 ckeditor rails gem 来提供 ckeditor 库 这里有多个帖子 人们希望删除 ckeditor 上下文菜单 以便可以显示本机浏览器
  • SignalR 更新无法在 Chrome 上正常运行

    我创建了一个带有 SignalR 通知的 ASP MVC 4 应用程序 我在本地以调试模式运行它 并通过 IIS 发布在服务器上运行它 使用 Internet Explorer 11 时 这基本上可以正常工作 稍后解释 HTML1300 N
  • 如何使用 Playwright 使用选择器查找框架 (iframe)

    我有一个小问题 无法找到使用 Microsoft Playwright 框架的答案 根据您可以使用以下代码获取 iframe const frame page frame frame login 但是如何使用选择器来查找 iframe 并与
  • 如何使用javascript确保元素仅在圆上朝一个方向移动?

    好吧 我承认我对三角学真的很糟糕 出于上下文的考虑 我将添加我在这里提到的问题中的内容 参考问题 https stackoverflow com a 39429290 168492 https stackoverflow com a 394
  • 为什么 setTimeout 在 Chrome 中触发两次,而在 IE 或 Firefox 中则不然?

    有人能告诉我为什么 javascript 函数 生成新号码 在 Chrome 中触发两次 但在 IE 或 Firefox 中则不会 使用 Chrome 20 0 1132 57 IE9 和 Firefox 13
  • 将 Firebase 云消息传递与 Windows 应用程序结合使用

    我在 Android 和 iOS 应用程序中使用 Firebase Cloud Messaging 但是我还有此应用程序的 Windows Mac OS 版本 我想保留相同的逻辑 我知道 Firebase Cloud Messaging 可
  • 使用 JavaScript 移动页面上的按钮

    我的按钮可以移动 但奇怪的是 我无法弄清楚偏移是否有问题 我希望我的按钮随着鼠标光标移动 但现在它的移动方式不是我想要的 有时它会消失 另外 创建的新按钮是重叠的 我不知道如何解决这个问题并拥有更好的外观 var coorA var coo
  • 使用 Javascript 设置 cookie [重复]

    这个问题在这里已经有答案了 我正在尝试构建我的第一个移动应用程序 它需要连接到我的 mysql 数据库并使用 json 返回数据 这很好 目前我有一个登录系统 一旦确定用户名和密码存在 它就会返回一条成功消息 对于下一步 我想在我的页面上使
  • 使用 Jade 评估自定义 javascript 方法 (CircularJSON)

    我想通过 Jade 将一个对象解析为客户端 JavaScript 通常这会起作用 script var object JSON parse JSON stringify object but my object is circular ht
  • Rails 3.1+ 的 Jasmine 与 Mocha JavaScript 测试 [已关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我对茉莉花有经验并且非常喜欢它 有谁有 Jasmine 和 Mocha 的经验 特别是 Rails 的经验吗 我想知道是否值得转用 我已经在 J
  • Highcharts jQuery 渲染问题 - 所有浏览器

    我在尝试使用构建堆积柱形图时遇到了一个奇怪的问题高图表 http www highcharts com 当图表呈现时 在您调整浏览器大小之前 不会显示列无论如何 导致图表重绘 我认为 图表的其余部分显示 轴 标题等 但不显示列本身 我在 I
  • 滚动顶部不符合预期

    Note 由于上次忘记奖励而重新开放赏金 A Woff 大师已经给出答案 我想在用户展开某一行时到达该行 这样当最后一个可见行展开时 用户不必向下滚动即可查看内容 I used example tbody on click td green
  • 什么是 WKWebView 中的 WKErrorDomain 错误 4

    fatal error LPWebView encounters an error Error Domain WKErrorDomain Code 4 A JavaScript exception occurred UserInfo 0x7
  • 如何通过索引访问 JSON 对象中的字段

    我知道这不是最好的方法 但我别无选择 我必须通过索引访问 JSONObject 中的项目 访问对象的标准方法是只写this objectName or this objectName 我还找到了一种获取 json 对象内所有字段的方法 fo
  • 使用velocity.js制作可拖动元素的动画

    我正在使用velocity js 为用户拖动的可拖动 SVG 元素设置动画 然而 velocity js 将先前的 mousemove 坐标排队并通过所有后续的 mousemove 坐标进行动画处理 我想要的是velocity js 不要对

随机推荐