Skip to content

Resolve vulnerability: Improper neutralization of special elements used in an OS command ('OS Command Injection')

MR created from vulnerability: Improper neutralization of special elements used in an OS command ('OS Command Injection')

AI GENERATED FIX

The suggested code changes were generated by GitLab Duo Vulnerability Resolution, an AI feature. Use this feature with caution. Before you run a pipeline or apply the code changes, carefully review and test them, to ensure that they solve the vulnerability.

The large language model that generated the suggested code changes was provided with the entire file that contains the vulnerable lines of code. It is not aware of any functionality outside of this context.

Please see our documentation for more information about this feature.

Description:

User input passed to java's Runitme.exec command executor was detected. Such code might allow attackers execute commands on the server via OS command injection.

OS command injection is a critical vulnerability that can lead to a full system compromise as it may allow an adversary to pass in arbitrary commands or arguments to be executed.

User input should always be filtered before being passed to command arguments.

Consider using a native library that replicates the behavior instead of running a command if possible.

Example of safely executing an OS command:

public static void executeCommand(String userFileData) throws java.io.IOException {
    // Generate a random filename, do not use user input
    String fileName = UUID.randomUUID().toString();
    // Create a Buffered/FileWriter
    BufferedWriter writer = new BufferedWriter(new FileWriter(fileName));
    // Write the user content to our random file
    writer.write(userFileData);
    // Close the file to flush contents
    writer.close();
    // Create the process builder with a hardcoded path to the binary, and our randomly
generated filename
    ProcessBuilder processBuilder = new ProcessBuilder("/opt/app/path", fileName);
    // Start the process
    Process process = processBuilder.start();
    // Handle/redirect output of process here
    // ...
}

For more information on OS command injection, see OWASP's guide: https://cheatsheetseries.owasp.org/cheatsheets/OS_Command_Injection_Defense_Cheat_Sheet.html

Analysis:

根据漏洞报告和源代码分析,这是一个真实的命令注入漏洞(CWE-78),不是误报。主要问题在于:

  1. vul2方法中直接使用用户输入的payload参数作为Runtime.exec()的参数,没有任何过滤或验证
  2. 同样的问题也存在于vul1vul3方法中,用户输入直接被拼接进命令中执行
  3. 虽然有一个safe方法实现了命令白名单,但其他方法仍然存在风险

命令注入漏洞允许攻击者通过精心构造的输入执行任意系统命令,可能导致服务器完全被控制。根据OWASP的建议,应该:

  1. 避免直接使用用户输入构建命令
  2. 使用白名单机制限制可执行的命令
  3. 使用ProcessBuilder代替Runtime.exec()以获得更好的控制

需要修复所有三个存在漏洞的方法(vul1, vul2, vul3),采用类似safe方法的白名单机制。

Summary:

  1. 报告的漏洞:命令注入漏洞(CWE-78),用户输入直接传递给系统命令执行器,可能导致任意命令执行。

  2. 修复方案

    • 在所有存在漏洞的方法(vul1, vul2, vul3)中添加命令白名单验证
    • 使用ProcessBuilder替代Runtime.exec()以获得更好的安全性控制
    • 对于不在白名单中的命令请求,返回错误信息
    • 白名单目前只包含"ls"和"date"两个安全命令,可根据实际需求扩展
  3. 修复效果

    // 修复前:直接执行用户输入
    Runtime.getRuntime().exec(payload);
    
    // 修复后:先验证白名单
    if (!ALLOWED_COMMANDS.contains(payload)) {
        return R.error("不允许执行该命令!");
    }
    new ProcessBuilder("sh", "-c", payload).start();

    现在系统只会执行预定义的安全命令,有效防止了命令注入攻击。

Identifiers:

  • A1:2017 - Injection
  • A03:2021 - Injection
  • CWE-78
  • Find Security Bugs-find_sec_bugs.COMMAND_INJECTION-1
  • SAST Rules ID - java_inject_rule-CommandInjection
  • java-lang-cmdi-processbuilder-taint
  • SAST Rules ID - java_inject_rule-EnvInjection

合并请求报告

加载中