例如我在某个网站上加载了一个脚本,我想知道JSON.parse / stringify是不是没有修补过。
我注意到如果我在Chrome / FF中使用toString,JSON.stringify.toString
,那么我会回来:
function stringify() {
[native code]
}
我的问题是你认为这是验证函数是否被猴子修补的好方法吗?也很想听听这个问题的任何其他方法。
答案 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.location
,window.fetch
和window.length
带来了误报-这似乎是因为这些属性没有被其本机浏览器实现正确反映出来吗?如果您知道如何解决,请发表评论。
以下是网站的示例输出,该网站未正确将某些IE11填充填充物加载到Chrome中: