是否可以判断某些 javascript 代码是否调用特定函数?

发布于 2024-09-15 03:50:36 字数 221 浏览 1 评论 0原文

我正在尝试构建某种 javascript“防病毒”,它会尝试捕获特定的函数调用。

假设我有一些随机的 javascript 文件,我可以检查它是否在任何地方都没有使用函数 jQuery.trim() 吗?

这似乎是一个相当复杂的任务,而且还有eval和基本编码可以将任何代码转换为一堆字符。

PHP 中可以写这样的东西吗?有没有可以提供帮助的库和工具?

I am trying to build some sort of a javascript "antivirus" that would try to catch particular function calls.

So lets say I've got some random javascript file, can I check if it doesn't use function jQuery.trim() (just for example sake) anywhere?

It seems like pretty complicated task, plus there are eval and base encodings which could transform any code to a pile of characters.

Would it be possible to write something like this in PHP? Are there any libraries and tools that could help?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

素罗衫 2024-09-22 03:50:36

不。一般来说,您不能仅通过检查代码来做出此决定。

即使您忽略 eval(说起来容易做起来难——有很多方法可以隐藏函数调用),它仍然是不可判定的。

例如:

somestring[data_from_remote_server](...)

where data_from_remote_server is "indexOf". That code can call indexOf. Is it likely to? Who knows.

即使没有远程服务器,也不难想象编写计算字符串“indexOf”的代码而不实际包含字符串“indexOf”。

No. You can not make this determination in general by merely inspecting the code.

Even if you ignore eval (easier said than done--there are lots of ways to hide a function call), it's still not decidable.

For example:

somestring[data_from_remote_server](...)

where data_from_remote_server is "indexOf". That code can call indexOf. Is it likely to? Who knows.

Even without a remote server, it's not hard to imagine writing code that computes the string "indexOf" without actually containing the string "indexOf".

酒解孤独 2024-09-22 03:50:36

JavaScript 是一种动态语言,即使没有像 eval 这样的函数,也很难确定脚本是否正在调用特定函数。我能想到的最好的解决方案类似于@pixl coer的重写函数本身,并有选择地调用它而不是总是阻止它。

考虑这个示例,通过将数组引用为断开的字符串来间接调用数组的 pop 方法。

var p = 'p';
var o = 'o'
[2,3,4][p + o + p]();

通过包装实际的方法,您可以选择性地决定是让该方法通过还是在运行时阻止它。

但请注意,即使这样也不是万无一失的。每个 iframe 都有自己的方法副本,例如 eval。有人可以创建一个一次性的 iframe,从那里获取 eval 方法,然后执行它。

总之,这个决定根本不能静态地做出。即使是动态的,您也必须修补很多东西以确保特定的函数永远不会被调用。

JavaScript is a dynamic language and even without functions like eval, it becomes very difficult to figure out if a script is calling a particular function. The best solution I can think of is similar to @pixl coer's to override the function itself, and selectively call it instead of always blocking it.

Consider this example that calls the pop method on an Array indirectly by referring to it as a broken string.

var p = 'p';
var o = 'o'
[2,3,4][p + o + p]();

By wrapping the actual method, you can selectively decide whether to let the method pass through or block it at runtime.

However, note that even this is not fool-proof. Each iframe gets it own copy of the methods such as eval. Somebody could just create a disposable iframe, get the eval method from there and then execute it.

Is short, this determination can not be made statically at all. Even dynamically, you would have to patch up a lot of things to ensure that a particular function never gets called.

半步萧音过轻尘 2024-09-22 03:50:36

在任何脚本运行之前,您可以将您不想运行的每个函数设置为您自己的函数,例如可以记录脚本尝试运行此函数
假设您不希望脚本使用 eval:

window.eval = function(){
     console.log("The script tried to call eval");  
};

或者您不希望它对字符串调用 indexOf

String.prototype.indexOf = function(){
     console.log("The script tried to call indexOf on the string" + this);
}

编辑:
如果您想继续使用这些函数,您可以创建副本,然后在替换函数中执行它们,如下所示:

    var evalCopy = window.eval;
    window.eval = function () {
        console.log("Eval was called again");
        return evalCopy.apply(this,arguments);
    }

Before any script runs you could set each of the functions you don't want to run to your own function, which for example could log that the script tried to run this function
Say you didn't want the script to use eval:

window.eval = function(){
     console.log("The script tried to call eval");  
};

or if you didn't want it to call indexOf on strings

String.prototype.indexOf = function(){
     console.log("The script tried to call indexOf on the string" + this);
}

Edit:
If you want to continue using the functions you can create copies and then execute them inside your replacement function like so:

    var evalCopy = window.eval;
    window.eval = function () {
        console.log("Eval was called again");
        return evalCopy.apply(this,arguments);
    }
初熏 2024-09-22 03:50:36

有一个 PHP Javascript 解析器和标记器可能会有所帮助。您可以查看解析树中的函数调用以及别名,以确保用户不会将函数分配给另一个名称,然后使用该新名称。一旦您禁止 eval 和类似函数(例如,FunctionsetTimeout 等),编码内容就不应该成为问题,因为 eval 是执行代码所需的。

http://web.2point1.com/2009/11 /14/jparser-and-jtokenizer-released/

解析树示例: http://timwhitlock.info/plug/examples/JavaScript/JParser.php

编辑:没关系,即使这样也无法捕获一些边缘情况。我唯一能想到的另一件事是通过 Javascript 引擎运行代码并监视任何邪恶的函数调用。但即使这样也不能捕获所有内容(来自远程服务器的数据就是一个例子)。

There's a PHP Javascript parser and tokenizer that might help. You could look through the parse tree for function calls, as well as aliases to make sure users don't assign the function to another name and then use that new name. Once you disallow eval and similar functions (e.g., Function, setTimeout, etc.), encoded content shouldn't be a problem since eval is required to execute the code.

http://web.2point1.com/2009/11/14/jparser-and-jtokenizer-released/

Example of parse tree: http://timwhitlock.info/plug/examples/JavaScript/JParser.php

EDIT: Nevermind, even this wouldn't catch some of the edge cases. The only other thing I could think of would be to run the code through a Javascript engine and monitor for any evil function calls. But even that wouldn't catch everything (data from a remote server is one example).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文