如何静态分析文件是否适合导入



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

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

这就是我导入和验证目标文件是指令文件的方式:

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.将启动,我将忽略该文件,但副作用将保留在后台。

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

在最坏的情况下,如果文件被确定为不安全,是否有一种传统的方法可以完全沙盒所需的逻辑并终止进程?

在最坏的情况下,如果文件被确定为不安全,是否有一种传统的方法可以完全沙盒所需的逻辑并终止进程?

将检查逻辑移动到特定的js文件中。当一切正常时,设为process.exit(0);当一切不正常时,设置为process.exit(1)

在当前程序中,使用child_process.exec调用新文件,而不是通过require加载文件,为其提供所需的参数,以便知道要测试哪个文件。

在更新后的程序中,绑定关闭事件以了解返回代码是0还是1

如果您需要比01更多的信息,请将一些JSON.字符串化的数据打印到stdout(console.log)中,然后在调用child_process.exec的回调中检索JSON.解析它。

或者,您是否研究过AST处理?http://jointjs.com/demos/javascript-ast

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

(注意:我在IRC上与作者讨论了这个问题。我的回答中可能有一些上下文不在原始问题中。)

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

一种方法是要求每个指令文件都导出某种具有name属性的对象,其中包含指令文件的名称。由于除了字符串文本之外,实际上没有任何内容可以放在其中,因此您可以非常确信,如果您无法通过静态分析定位name属性,则该文件不是指令文件,即使是在JavaScript这样不完全可静态分析的语言中也是如此。


对于该线程的任何读者,如果他们试图保护自己免受恶意行为者的攻击,而不是意外事件的攻击,例如,当接受来自用户的不受信任的代码时:您不能单独使用Node.js(也不能使用vm模块)来沙箱或"验证"JavaScript,并且上述解决方案将不适用于您。您将需要系统级容器化或虚拟化来安全地运行此类代码。没有其他选择。

最新更新