如何静态分析一个文件适合导入?

我有CLI程序,可以用描述指令的文件列表执行,例如

node ./my-program.js ./instruction-1.js ./instruction-2.js ./instruction-3.js 

这是我如何导入和validation目标文件是一个指令文件:

 const requireInstruction = (instructionFilePath) => { const instruction = require(instructionFilePath) if (!instruction.getInstruction) { throw new Error('Not instruction file.'); } return instruction; }; 

这种方法的问题是,它会执行文件执行,无论它是否符合预期的签名,即如果文件包含一个副作用,如连接到数据库:

 const mysql = require('mysql'); mysql.createConnection(..); module.exports = mysql; 

Not instruction file. 会开火,我会忽略这个文件,但是这个副作用会保留在后台。

如何安全地validation目标文件签名?

最糟糕的情况是,有没有一个传统的方式来完全沙箱需求逻辑和杀死进程,如果文件被确定为不安全的?

最糟糕的情况是,有没有一个传统的方式来完全沙箱需求逻辑和杀死进程,如果文件被确定为不安全的?

将检查逻辑移入特定的js文件。 使它process.exit(0)当一切正常, process.exit(1)时,它是错的。

在你当前的程序中,不是通过require来加载文件,而是使用child_process.exec来调用你的新文件,给它所需的参数来知道要testing哪个文件。

在更新的程序中,绑定closures事件以知道返回码是0还是1

如果你需要比01更多的信息,进入新的js文件,它将加载指令,打印一些JSON.stringified数据到stdout (console.log),然后检索JSON.parse它在调用callback到child_process.exec

或者,你看看AST处理? http://jointjs.com/demos/javascript-ast

它可以帮助您识别未embedded到导出函数中的代码段。

(注:我在IRC上与作者讨论过这个问题,在我的回答中可能有一些不在原始问题的背景。)

考虑到你的scheme纯粹是防止意外包含非指令文件,而不是防止恶意行为,使用类似Esprima的静态分析可能就足够了。

一种方法是要求每个指令文件都导出一些带有name属性的对象,其中包含指令文件的名称。 除了string文字之外,没有什么东西可以放在里面,你可以相当肯定地说,如果你不能通过静态分析来定位一个name属性,这个文件就不是一个指令文件 – 即使是像JavaScript这样的语言,完全可以静态分析。


对于这个线程的任何读者来说,都是为了防止恶意的行为者,而不是偶然的 – 例如,当接受来自用户的不可信的代码时:你不能单独使用Node.js来validationJavaScript(不是用vm模块) ,而上述解决scheme不适合你 。 您将需要系统级容器化或虚拟化来安全地运行此类代码。 没有其他select。