我正在尝试对我的自定义应用程序进行碎片化,同时保持总体设计标准。
我最近学习了使用 graalvm 在 Windows 上将 java 应用程序编译为本机 exe 文件。
我正在考虑将设计从使用许多复杂的网络应用程序改为
/**
* for example url = "https://www.webpage.com/app-one/someNativeApplicationName?param1=value1¶m2=value2...";
* url params is ascii or base64
*/
public String callNativeApplication(String url) {//
//CONSTRUCT nativeApplicationFile
String someNativeApplicationName = parseNativeApplicationNameFromUrl(url);
Path nativeApplicationsFolder = Path.of("C:\\nativeApplicationsFolder");
Path nativeApplicationFile = nativeApplicationsFolder.resolve(someNativeApplicationName);
//CHECK FOR DIR HACK
nativeApplicationFile = nativeApplicationFile.toAbsolutePath();
if(!nativeApplicationFile.startsWith(nativeApplicationsFolder)) {
throw new RuntimeException("ERROR: DIR HACK");
}
//CHECK HIDDEN COMMAND HACK
if (url.chars().filter(ch -> ch == ' ').count() != 0) {
throw new RuntimeException("ERROR: HIDDEN COMMAND HACK");
}
//CONSTRUCT command
String command = nativeApplicationFile + " " + url;
//CHECK HIDDEN CHAR HACK
if (!Charset.forName("US-ASCII").newEncoder().canEncode(command)){
throw new RuntimeException("ERROR: HIDDEN CHAR HACK");
}
//EXECUTE
Process p = java.lang.Runtime.getRuntime().exec(command);
String reply = fetchReply(p);
return reply;
}
并返回结果作为回复。
是否存在我应该额外考虑的安全风险。尝试一下安全吗?
评论中有一些关于为什么让用户执行任意 shell 代码是一个坏主意的精彩评论。然而,有一些方法可以让它至少更安全一些。例如,您可以使用枚举将端点限制为硬编码的命令集:
public enum Command {
ONE("C:/nativeApplicationsFolder/one.exe"),
TWO("C:/nativeApplicationsFolder/two.exe"),
;
private final String path;
Command(String path) {
this.path = path;
}
public String getPath() {
return path;
}
}
这样,您可以轻松检查该命令是否安全。但还是要小心:如果您需要用户传递命令行参数,您现在需要再次小心,确保用户不会访问您不希望他们访问的文件或其他应用程序。