有没有办法检查本机Javascript函数是否被猴子修补?

时间:2016-07-25 08:15:05

标签: javascript

例如我在某个网站上加载了一个脚本,我想知道JSON.parse / stringify是不是没有修补过。

我注意到如果我在Chrome / FF中使用toString,JSON.stringify.toString,那么我会回来:

function stringify() {
    [native code]
}

我的问题是你认为这是验证函数是否被猴子修补的好方法吗?也很想听听这个问题的任何其他方法。

4 个答案:

答案 0 :(得分:5)

很容易假冒JSON.stringify.toString

JSON.stringify = function() {}
JSON.stringify.toString = function() {return 'ha-ha'}

console.log(JSON.stringify); //ha-ha

更强大的方法是使用Function.prototype.toString

Function.prototype.toString.call(JSON.stringify)

但真正糟糕的monkeypatcher也可以修补Function.prototype.toString:)

答案 1 :(得分:4)

是的,这是检查本机功能是否被覆盖的唯一实用方法。

const isNative = fn => !!fn.toString().match(/\[native code\]/)

console.log(isNative(JSON.stringify));

更强大的解决方案可以使用Function.prototype.toString()而不是fn.toString()的直接调用,但两者都是monkeypatble。 JavaScript的乐趣:)

答案 2 :(得分:3)

规范(http://www.ecma-international.org/ecma-262/7.0/index.html#sec-function.prototype.tostring)没有指定为内置函数返回的确切字符串:

  

19.2.3.5 Function.prototype.toString

     

在对象func上调用toString方法时,如下所示   采取的步骤:

     

如果func是Bound Function奇异物体,则返回a   依赖于实现的 func的字符串源代码表示。   表示必须符合以下规则。它是   实现依赖于表示是否包含绑定   功能信息或有关目标功能的信息。如果   Type(func)是Object,是内置函数对象或者是   一个[[ECMAScriptCode]]内部插槽,然后返回一个   依赖于实现的字符串源代码表示func。   表示必须符合以下规则。抛出TypeError   例外。 toString表示要求:

     

字符串表示必须具有a的语法   FunctionDeclaration,FunctionExpression,GeneratorDeclaration,   GeneratorExpression,ClassDeclaration,ClassExpression,ArrowFunction,   MethodDefinition或GeneratorMethod取决于实际   对象的特征。白色空间的使用和放置,   行终止符和表示字符串中的分号是   实现有关。如果使用ECMAScript定义了对象   代码和返回的字符串表示形式不是   MethodDefinition或GeneratorMethod然后表示必须   这样,如果对字符串进行求值,则在词汇上下文中使用eval   这相当于用于创建原始的词汇上下文   对象,它将导致一个新的功能等效的对象。在   这种情况下返回的源代码一定不能自由提及   原始函数没有自由提及的变量   源代码,即使这些“额外”名称最初在范围内。如果   实现无法生成满足的源代码字符串   这些标准然后它必须返回一个eval将抛出的字符串   一个SyntaxError异常。

因此,检查[Native Code]可能会也可能不会取决于解释器。此外,实现可以很好地将内置函数实现为普通的javascript代码。

因此,在回答您的问题时,您无法确定,Javascript是否指定了内置函数是否已经过猴子修补。

据说Chrome和Firefox都会返回[Native Code]字符串,但需要验证其他可能是实用解决方案的实现。

答案 3 :(得分:0)

我试图将其他答复中的一些想法发展为可行的脚本-这是

https://gist.github.com/mindplay-dk/767a5313b0052d6daf2b135fdecd775f

将其粘贴到Chrome(或Edge)控制台中,然后按ENTER键-它会打印出所有构造器和类方法的列表,这些构造器和类方法与它们的本机副本不匹配。 (它是通过与iframe中创建的document.createElement中的本机API进行比较来完成的,因此,从技术上讲,如果您打算故意这样做,则可以通过重写该方法来欺骗它;这不是安全工具。)

请注意,这目前为window.locationwindow.fetchwindow.length带来了误报-这似乎是因为这些属性没有被其本机浏览器实现正确反映出来吗?如果您知道如何解决,请发表评论。

以下是网站的示例输出,该网站未正确将某些IE11填充填充物加载到Chrome中:

enter image description here