最近正在使用 Node.js 构建一个 API,该 API 接收不受信任的代码以使用 vm2 运行它。问题是我想运行异步函数,所以我需要使用NodeVM
不支持无限循环超时的方法,我发现所有关于使用子进程的解决方案,如果它不起作用则将其杀死。
但是我将代码作为字符串接收,并且我想防止其中出现无限循环,所以我想使用正则表达式来注入带有超时条件的 while/for 循环,或者在发生无限循环时抛出异常。
那可能吗?
最近正在使用 Node.js 构建一个 API,该 API 接收不受信任的代码以使用 vm2 运行它。问题是我想运行异步函数,所以我需要使用NodeVM
不支持无限循环超时的方法,我发现所有关于使用子进程的解决方案,如果它不起作用则将其杀死。
但是我将代码作为字符串接收,并且我想防止其中出现无限循环,所以我想使用正则表达式来注入带有超时条件的 while/for 循环,或者在发生无限循环时抛出异常。
那可能吗?
对我有用的完美解决方案是使用AST。所以我了解了更多关于它的信息,所以我可以在任何我想要的地方注入字符串。
然后我按照以下步骤操作:
Esprima
1- 使用解析器将字符串代码转换为 AST 。
2-注入无限循环代码保护,即:
// Before any loop
let myvar = Date.now();
// Inside the loop
if (Date.now() - myvar > 1000) { break;}
使用break
或抛出错误,请注意每次捕获循环时都需要一个唯一的变量名生成器。
3- 使用 . 将其转换回字符串escodegen
。
您永远无法确保用户提供的代码在不阻塞节点进程的情况下以良好的方式执行。例如,CPU 密集型计算会阻塞主节点进程。最好的解决方案是在它自己的进程中执行此类代码,如果它没有及时完成,则停止该进程。
worker-farm是一个包,它有一个简单的 API 来启动具有可配置超时的工作进程。在这样的工作进程中执行用户提供的代码,而不是在您的主节点进程中执行。
如果你想限制用户代码使用某些库,你可以使用 VM2 来实现。