防止命令注入的方法

  1. 使用 Apache Commons Lang 的 StringEscapeUtils:
import org.apache.commons.lang3.StringEscapeUtils;

private String escapeProcessName(String processName) {
    return StringEscapeUtils.escapeJava(processName);
}

这种方法会转义 Java 语言中的特殊字符,但可能不足以完全防止命令注入。

  1. 使用 Java 的 Pattern.quote() 方法:
import java.util.regex.Pattern;

private String escapeProcessName(String processName) {
    return Pattern.quote(processName);
}

这会将整个字符串作为字面量处理,但可能会影响命令的执行。

  1. 使用白名单方法:
private String escapeProcessName(String processName) {
    return processName.replaceAll("[^a-zA-Z0-9_.-]", "");
}

这种方法只允许字母、数字、下划线、点和连字符,删除所有其他字符。

  1. 使用 ProcessBuilder 而不是 Runtime.exec():
private Process createProcess(String processName) throws IOException {
    List<String> command = Arrays.asList("ps", "aux");
    ProcessBuilder pb = new ProcessBuilder(command);
    pb.redirectErrorStream(true);
    return pb.start();
}

然后在读取输出时过滤包含 processName 的行。这种方法避免了直接在命令中包含用户输入。

  1. 使用第三方库如 Google Guava 的 CharMatcher:
import com.google.common.base.CharMatcher;

private String escapeProcessName(String processName) {
    return CharMatcher.anyOf("$&;`()\"'|<>").replaceFrom(processName, "");
}

这种方法类似于正则表达式的方法,但可能更高效。

  1. 对于远程 Linux 系统,考虑使用 pkill 命令:
private String createCommand(String processName) {
    return String.format("pkill -f %s", processName);
}

pkill 命令会自动处理大多数特殊字符。

  1. 使用 Java 9+ 的 ProcessHandle API:
private List<ProcessHandle> findProcesses(String processName) {
    return ProcessHandle.allProcesses()
        .filter(ph -> ph.info().command().map(cmd -> cmd.contains(processName)).orElse(false))
        .collect(Collectors.toList());
}

这种方法完全避免了使用 shell 命令,但仅适用于本地进程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值