【问题标题】:Sanitize/escape argument that's going into a SSH command进入 SSH 命令的清理/转义参数
【发布时间】:2011-10-12 23:04:07
【问题描述】:

我需要做什么才能正确清理/转义正在输入到编程 SSH 命令中的参数?

例如路径参数-

public boolean exists(String path) {

    try {
        ChannelExec c = (ChannelExec) session.openChannel("exec");

        //Here *** would like to be sure that the path is completely valid
        c.setCommand("[ -f " + path + " ] && echo \"File exists\" || echo \"File does not exists\"");

        InputStream in = c.getInputStream();

        c.connect();

        ByteArrayOutputStream out = new ByteArrayOutputStream();

        IOUtils.copy(in, out);

        in.close();
        out.close();

        System.out.println(out.toString("UTF-8"));
        c.disconnect();

    } catch (JSchException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    // TODO Auto-generated method stub
    return false;
}

不安全的原因是路径参数可能来自用户上传的文件。从技术上讲,恶意用户可以上传带有无效文件名的文件。虽然我可以事先检查(我正在这样做),但我也想在这里检查一下。

【问题讨论】:

  • 我想这取决于您所说的“无效”。
  • 恶意。确保它本身没有进行“SSH 注入”...
  • 只是反斜杠所有不“正常”的东西,所以它肯定是一个文件名,我猜?尤其是分号,当然。
  • 是的,我认为这就是我要采取的方法。感谢您的建议。

标签: java ssh jsch


【解决方案1】:

我认为这里的一个好主意是确保它作为单个参数传递给[,而不是多个参数(甚至是多个命令)。所以只需将其包装在' 中,并将字符串中的任何' 替换为'\''

private String escape(String s) {
    return "'" + s.replace("'", "'\\''") + "'";
}

您也可以在命令的echo 部分使用' 而不是\",只要您不需要在服务器端进行变量扩展(并且这些字符串中没有变量):

c.setCommand("[ -f " + escape(path) + " ] && " +
              "echo 'File exists' || echo 'File does not exist'");

(请注意,我还做了一个小的语法修复。)

【讨论】:

  • 我喜欢它的发展方向......非常感谢您的回答。它返回文件不存在。不过我会继续修改它,看看我是否可以让它工作
  • 为什么还要使用'\'' 而不是只使用\' 转义?
  • 我从this Unix & Linux question 得到了这个引用机制,它很好地解释了它。 Bourne-like shell 的单引号实际上是文字(这意味着您不能使用它来引用单引号字符本身)。
  • 得到它的工作,这是我的路径......它不喜欢文件路径中的波浪字符,这不是问题。再次感谢:)
  • 啊,是的,~' 引用的字符串中的含义与在未引用的单词中的含义不同(它将被扩展)。
猜你喜欢
  • 1970-01-01
  • 2013-05-29
  • 1970-01-01
  • 1970-01-01
  • 2012-09-03
  • 1970-01-01
  • 2011-04-24
  • 1970-01-01
  • 2018-05-15
相关资源
最近更新 更多