|
|
@@ -569,50 +569,46 @@ public class FsConfServiceImpl implements IFsConfService {
|
|
|
@Override
|
|
|
public String getLogs(String uuid, String logFile, String logType) {
|
|
|
log.info(logFile);
|
|
|
- // 使用ProcessBuilder来正确处理命令字符串
|
|
|
+ // SECURITY: Use Java file reading instead of shell commands to prevent command injection.
|
|
|
+ // Previously used "sh -c cat ... | grep '" + uuid + "'" which allowed RCE via shell metacharacters.
|
|
|
String ansiRegex = "\u001b\\[[;\\d]*m"; // 匹配 ANSI 转义序列的正则表达式
|
|
|
- List<String> commands = new ArrayList<>();
|
|
|
- commands.add("sh");
|
|
|
- commands.add("-c");
|
|
|
- if (StringUtils.isBlank(uuid)) {
|
|
|
- commands.add("tail -n 20 " + logFile);
|
|
|
- } else {
|
|
|
- commands.add("cat " + logFile + " | grep '" + uuid + "'");
|
|
|
- }
|
|
|
- log.info(StringUtils.join(commands.toArray(), " "));
|
|
|
- String logs = "";
|
|
|
+ StringBuilder logs = new StringBuilder();
|
|
|
try {
|
|
|
-
|
|
|
- // 使用ProcessBuilder执行命令
|
|
|
- ProcessBuilder processBuilder = new ProcessBuilder(commands);
|
|
|
- Process process = processBuilder.start();
|
|
|
-
|
|
|
- BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
|
|
-
|
|
|
- String line;
|
|
|
- while ((line = reader.readLine()) != null) {
|
|
|
- if ("fs".equals(logType)) {
|
|
|
- try{
|
|
|
- logs += JSONObject.parseObject(line).getString("log").replaceAll(ansiRegex, "") ;
|
|
|
- }catch (Exception e) {
|
|
|
- log.error(ExceptionUtil.getExceptionMessage(e));
|
|
|
+ java.io.File file = new java.io.File(logFile);
|
|
|
+ if (!file.exists() || !file.isFile()) {
|
|
|
+ log.warn("log file not found: {}", logFile);
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ if (StringUtils.isBlank(uuid)) {
|
|
|
+ // Read last 20 lines without shell
|
|
|
+ java.util.List<String> allLines = java.nio.file.Files.readAllLines(java.nio.file.Paths.get(logFile));
|
|
|
+ int start = Math.max(0, allLines.size() - 20);
|
|
|
+ for (int i = start; i < allLines.size(); i++) {
|
|
|
+ logs.append(allLines.get(i)).append("\r\n");
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // Filter lines containing uuid without shell grep
|
|
|
+ try (java.io.BufferedReader br = new java.io.BufferedReader(new java.io.FileReader(logFile))) {
|
|
|
+ String line;
|
|
|
+ while ((line = br.readLine()) != null) {
|
|
|
+ if (line.contains(uuid)) {
|
|
|
+ if ("fs".equals(logType)) {
|
|
|
+ try {
|
|
|
+ logs.append(JSONObject.parseObject(line).getString("log").replaceAll(ansiRegex, ""));
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error(ExceptionUtil.getExceptionMessage(e));
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ logs.append(line).append("\r\n");
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
- } else {
|
|
|
- logs += line + "\r\n";
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- // 读取命令的错误输出
|
|
|
- BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
|
|
|
- String errorLine;
|
|
|
- while ((errorLine = errorReader.readLine()) != null) {
|
|
|
- log.info(errorLine);
|
|
|
- }
|
|
|
- process.waitFor(); // 等待进程结束并获取退出值
|
|
|
- } catch (IOException | InterruptedException e) {
|
|
|
- e.printStackTrace();
|
|
|
+ } catch (java.io.IOException e) {
|
|
|
+ log.error("Failed to read log file: {}", logFile, e);
|
|
|
}
|
|
|
- return logs;
|
|
|
+ return logs.toString();
|
|
|
}
|
|
|
|
|
|
@Override
|