You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复Java应用中出现的CWE-78操作系统命令注入漏洞?

修复CWE-78操作系统命令注入漏洞

问题说明

CWE-78:对用于操作系统命令的特殊元素未进行适当的中和处理(‘操作系统命令注入’):详情:调用java.lang.Runtime.exec()存在命令注入缺陷,函数参数由不可信输入构造。攻击者若能指定命令的全部或部分内容,就可能以进程权限在服务器上执行任意命令。风险高低取决于输入验证的有效性。exec()的参数来自受污染的executeCommandsArray变量,该变量源于AnnotationVirtualController.vc_annotation_entry的调用。需验证所有不可信输入,确保符合预期格式,尽量用集中式验证程序;若用黑名单,需确保清理逻辑能彻底移除所有禁用字符;多数系统命令API支持传入字符串数组的安全版本,可防范部分命令注入。

风险代码片段:

StringBuilder sb = new StringBuilder();
sb.append("cat *" );
String bashCommand= "/bin/sh";
String optionCommand = "-c";
String[] executeCommandsArray= new String[] 
 {bashCommand,optionCommand,sb.toString()};

Runtime run = Runtime.getRuntime();
Process pr = run.exec(executeCommandsArray);
int exitcode = pr.waitFor();

修复方案

1. 替换为Java原生IO(最安全)

你的代码核心需求是读取当前目录下所有文件内容,完全不需要调用shell执行cat命令。用Java自带的文件操作API就能实现,彻底杜绝命令注入风险:

import java.io.File;
import java.io.FileReader;
import java.io.BufferedReader;

public void readAllFilesInCurrentDir() {
    File currentDir = new File(".");
    File[] files = currentDir.listFiles();
    if (files == null) return;

    for (File file : files) {
        if (!file.isFile()) continue;
        
        try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
            String line;
            while ((line = reader.readLine()) != null) {
                // 此处处理读取到的内容,比如输出或存储
                System.out.println(line);
            }
        } catch (Exception e) {
            // 异常处理,如日志记录
            e.printStackTrace();
        }
    }
}

2. 必须执行系统命令时的安全写法

如果业务场景确实需要调用系统命令,严格遵循以下规则:

  • 跳过shell解析:不要用/bin/sh -c的方式,直接传递命令和参数的字符串数组,这样shell不会解析参数中的特殊字符(如;、|、&等)
  • 强制输入验证:如果命令包含不可信输入,必须做白名单校验,只允许符合预期格式的内容

比如要执行cat读取指定文件,代码应该这样写:

public void catSpecificFile(String fileName) {
    // 白名单验证:只允许字母、数字、下划线、连字符、点
    if (!fileName.matches("[a-zA-Z0-9_\\-.]+")) {
        throw new IllegalArgumentException("非法文件名");
    }

    // 直接传递命令和参数数组,不通过shell
    String[] cmdArray = new String[]{"cat", fileName};
    try {
        Runtime.getRuntime().exec(cmdArray).waitFor();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

3. 输入验证核心原则

  • 优先白名单:白名单比黑名单可靠得多,只允许明确允许的字符/格式,避免遗漏危险字符
  • 集中验证:把输入验证逻辑封装成公共方法,所有不可信输入都走这个方法,避免重复实现
  • 拒绝黑名单清理:黑名单清理容易有漏洞(比如多次转义绕过),尽量不用

内容的提问来源于stack exchange,提问作者Shalini Gupta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 12:58:34