如何在没有 toString() 的情况下获取函数值?

GMe*_*GMe 5 javascript tostring

我需要确保某些特定的原生 Javascript 函数没有被修补或覆盖。

不幸的是,我无法通过访问.toString()函数或Function.prototype.toString使用 bind apply 或 call 之一来做到这一点,因为这Function.prototype.toString是我必须测试的函数之一。

有没有其他方法可以返回函数的值(函数本身)?(或者[Native Code]对于原生 JS 函数)

编辑:此测试的目的之一是检查客户端是否是修补某些 JS 功能的机器人。Function.prototype.toString在这种情况下,创建新框架并获取其值将不起作用

Gio*_*mes 1

回应编辑

如果恶意客户端无法或不会更新其机器人脚本来响应您的检查,则只需将Function.prototype.toString()HTML 标头中的 using javascript 的副本保存到临时变量即可。然后对照此检查客户端是否已更改 js。

如果客户端是恶意的并且试图通过更改他们的机器人来主动避免您的检查,那么根本没有铁定的方法来阻止他们。这将成为一场军备竞赛,你修补检查,他们修补修复作为回应。最终,客户对其浏览器中运行的内容拥有最终决定权,因此您可能需要再次考虑为什么要进行这些检查,以查看是否有另一种可行的方法来解决您的问题。

初步答复

您可以重新请求整个 .js 文件并将其全部解析为字符串。您必须对每个 js 文件执行此操作,并找到一个好的模式来确定您的函数是否已被覆盖,因此它可能无法满足您的需求。

// my JS file is being served from giorgiosjames.com/myjs.js

const myJs = await fetch('giorgiosjames.com/myjs.js').then(res => res.text());

// parse myJs here, something like
if (myJs.includes('Function.prototype.toString = ')) // do something
Run Code Online (Sandbox Code Playgroud)

如果您可以限制使用最新的 Firefox,则可以使用该方法.toSource(),但没有其他浏览器支持它并且它不是标准的。更多阅读这里

// only in latest Firefox
const x = () => 'wow';
console.log(x.toSource())
// returns "() => 'wow'"
Run Code Online (Sandbox Code Playgroud)

作为框架挑战,您可能仍然可以使用(可以说)最好的方法Function.prototype.toString:

  1. 首先检查 toString 是否有效。

  2. .toString()如果已被覆盖则重置。

  3. 检查您的其他功能.toString()
  4. .toString()必要时取消修复
let temp = null;

if (Function.prototype.toString.toString() !== 'function toString() { [native code] }') {
    // save overridden function if you need to come back to it
    temp = Function.prototype.toString;

    // getting the original toString function by creating an iframe
    const iframe = docuemnt.createElement('iframe');
    iframe.style.display = 'none';
    document.body.appendChild(iframe);
    Function.prototype.toString = iframe.contentWindow.Function.prototype.toString;
}

// do your other checks here ex//
if (Array.prototype.includes.toString() !== iframe.contentWindow.Array.prototype.includes.toString()) {
    // do something
}

// ..or however you're planning on checking for overridden functions

// restore toString from temp if needed.
Function.prototype.toString = temp;
Run Code Online (Sandbox Code Playgroud)