强化问题 - 命令注入

时间:2018-05-02 22:36:18

标签: java command code-injection processbuilder fortify

我正在尝试为我的java应用程序执行hp fortify安全扫描。我有几个问题,我已经解决了。但我无法找到以下问题的修复方法。

  1. 命令注入

    String hostname = execReadToString("hostname").split("\\.")[0];
    public static String execReadToString(String execCommand) throws IOException {
     try (Scanner s = new Scanner(Runtime.getRuntime().exec(execCommand).getInputStream()).useDelimiter("\\A")) {
        return s.hasNext() ? s.next() : "";
    }
    

    execReadToString()方法调用exec()来执行命令。此调用可能允许攻击者注入恶意命令。

  2. 所以我也尝试过使用流程构建器。

    private static void gethostname(String cmd1) throws IOException {
            if(Pattern.matches("[A-Za-z]+", cmd1)) {
            ProcessBuilder pb = new ProcessBuilder(cmd1);
            Process p = pb.start();
                BufferedReader reader = new BufferedReader(new InputStreamReader(
                        p.getInputStream()));
                String readline;
                while ((readline = reader.readLine()) != null) {
                    System.out.println(readline);
                }
            }
        }
    

    即使这会给我一个安全问题此start()调用可能允许攻击者注入恶意命令。

    这个问题的理想解决方案是什么?

    提前致谢

1 个答案:

答案 0 :(得分:0)

通常这是因为您使用用户输入来构建命令字符串,其中用户可以注入恶意代码来操纵最终运行的命令(即使您添加验证,也会有办法绕过它)。

在你的情况下,你似乎是硬编码命令所以这不应该是一个问题,但是,请参阅hardcoded command invocation上的OWASP页面(强调我的):

  

与前面的示例不同,此示例中的命令是   硬编码,因此攻击者无法控制传递给的参数   系统()。但是,由于程序没有指定绝对路径   for make,并且不会在之前擦除任何环境变量   调用该命令后,攻击者可以将其$ PATH变量修改为   指向名为make的恶意二进制文件并执行CGI脚本   shell提示符。而且由于程序已经安装了setuid root,   攻击者的make版本现在以root权限运行。

     

环境在系统执行中发挥着重要作用   程序中的命令。 system()和exec()之类的函数使用   调用它们的程序环境,因此也就是攻击者   有可能影响这些电话的行为

分辨率:

  1. 使用本机Java API /库来实现您的需求,而不是运行命令 - 这可能是最佳选择。仅在不可避免时使用命令,例如:没有Java客户端库的第三方工具。这种方法具有更便携的附加优点,并且在大多数情况下也更有效。 This库可能会对您的方案有所帮助。
  2. 如果 运行命令,请确保不要间接使用用户提供的数据或外部数据来构建命令。
  3. 或者,如果您要从命令硬编码命令,请使用命令的绝对路径,不要将环境变量用作其中的一部分。对于hostname(假设您使用内置命令),这通常是/usr/bin/hostname,但您可以使用which hostname找到适合您环境的命令路径。