用户恶意代码示例
执行超时
/**
* 无限睡眠(阻塞程序执行)
*/
public class Main {
public static void main(String[] args) throws InterruptedException {
long ONE_HOUR = 60 * 60 * 1000L;
Thread.sleep(ONE_HOUR);
System.out.println("睡完了");
}
}
对于这种危险,我们可以增加超时控制来解决这个问题:
// 超时控制
new Thread(() -> {
try {
Thread.sleep(TIME_OUT);
System.out.println("超时了,中断");
runProcess.destroy();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}).start();
解读
设置自动的超时时间 TIME_OUT,当程序执行时间超过时,就是强制的执行销毁进程指令。
占用内存
import java.util.ArrayList;
import java.util.List;
/**
* 无限占用空间(浪费系统内存)
*/
public class Main {
public static void main(String[] args) throws InterruptedException {
List<byte[]> bytes = new ArrayList<>();
while (true) {
bytes.add(new byte[10000]);
}
}
}
对于这种危险,我们可以通过两种方式限制:
- 通过操作系统自身的程序限制:Linux 的
cgroup; - 通过 JVM 参数来限制:
读文件,信息泄露
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
/**
* 读取服务器文件(文件信息泄露)
*/
public class Main {
public static void main(String[] args) throws InterruptedException, IOException {
String userDir = System.getProperty("user.dir");
String filePath = userDir + File.separator + "src/main/resources/application.yml";
List<String> allLines = Files.readAllLines(Paths.get(filePath));
System.out.println(String.join("\n", allLines));
}
}
写文件,植入木马
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
/**
* 向服务器写文件(植入危险程序)
*/
public class Main {
public static void main(String[] args) throws InterruptedException, IOException {
String userDir = System.getProperty("user.dir");
String filePath = userDir + File.separator + "src/main/resources/木马程序.bat";
String errorProgram = "java -version 2>&1";
Files.write(Paths.get(filePath), Arrays.asList(errorProgram));
System.out.println("写木马成功,你完了哈哈");
}
}
运行其他程序
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* 运行其他程序(比如危险木马)
*/
public class Main {
public static void main(String[] args) throws InterruptedException, IOException {
String userDir = System.getProperty("user.dir");
String filePath = userDir + File.separator + "src/main/resources/木马程序.bat";
Process process = Runtime.getRuntime().exec(filePath);
process.waitFor();
// 分批获取进程的正常输出
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
// 逐行读取
String compileOutputLine;
while ((compileOutputLine = bufferedReader.readLine()) != null) {
System.out.println(compileOutputLine);
}
System.out.println("执行异常程序成功");
}
}
通用安全方法
SecurityManager
这个方法在 jdk 17 之前有效,现在这个类已经在 jdk 17 中废除了。不过哪怕在适合的版本,也不推荐使用,因为该类很难用,例如需要通过加白名单的方式来排除对于 jar 包的校验。
Docker
这是最适合的方法了。
