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

时间:2016-05-04 11:33:12

标签: node.js

我有一个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.会触发,我会忽略该文件,但旁边动作将保留在后台。

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

最糟糕的情况是,如果文件被确定为不安全,是否存在完全沙箱化需求逻辑并终止进程的常规方法?

2 个答案:

答案 0 :(得分:1)

  

最糟糕的情况是,如果文件被确定为不安全,是否存在完全沙箱化需求逻辑并终止进程的常规方法?

将检查逻辑移动到特定的js文件中。当一切都很好时,process.exit(0),如果错误,请process.exit(1)

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

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

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

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

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

答案 1 :(得分:1)

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

鉴于您的方案纯粹是为了防止意外包含非指令文件,而不是防止恶意行为,使用Esprima之类的静态分析可能就足够了。 / p>

一种方法是要求每个指令文件导出某种具有name属性的对象,该属性包含指令文件的名称。由于除了字符串文字之外没有任何东西要放在那里,你可以相当确定如果你不能通过静态分析找到name属性,那么该文件不是指令文件 - 即使是像JavaScript这样的语言,也不是完全静态可分析的。

对于此线程的任何读者试图保护恶意演员,而不是意外 - 例如,当接受来自用户的不受信任的代码时:不能沙箱或仅使用Node.js'验证'JavaScript(也不使用vm模块),上述解决方案对您不起作用。您将需要系统级容器化或虚拟化来安全地运行此类代码。没有其他选择。