java - Java 沙盒安全策略
问题描述
我正在关注本教程教程,了解如何在使用插件时实现沙盒。
这是我的主类,我从 Jar 文件加载类并运行接口函数:
import java.io.File;
import java.net.URL;
import java.security.Policy;
public class Main {
public static void main(String[] args){
Policy.setPolicy(new SandboxSecurityPolicy());
System.setSecurityManager(new SecurityManager());
try {
File file = new File("JarDummy.jar");
URL urlJar = file.toURI().toURL();
ClassLoader pluginLoader = new PluginClassLoader(urlJar);
Class<?> pluginClass = pluginLoader.loadClass("ZEngine");
IEngine plugin = (IEngine) pluginClass.newInstance();
plugin.build("file.txt");
}catch (Exception e){
e.printStackTrace();
}
}
}
这是我的界面:
public interface IEngine {
void build(String filename);
}
这是我的插件类加载器:
导入 java.net.URL;导入 java.net.URLClassLoader;
public class PluginClassLoader extends URLClassLoader {
public PluginClassLoader(URL jarFileUrl) {
super(new URL[] {jarFileUrl});
}
}
这是我的策略,如果从插件加载类,则会给予不同的权限:
import sun.plugin.security.PluginClassLoader;
import java.security.AllPermission;
import java.security.PermissionCollection;
import java.security.Permissions;
import java.security.Policy;
import java.security.ProtectionDomain;
public class SandboxSecurityPolicy extends Policy {
@Override
public PermissionCollection getPermissions(ProtectionDomain domain) {
if (isPlugin(domain)) {
return pluginPermissions();
}
else {
return applicationPermissions();
}
}
private boolean isPlugin(ProtectionDomain domain) {
return domain.getClassLoader() instanceof PluginClassLoader;
}
private PermissionCollection pluginPermissions() {
Permissions permissions = new Permissions(); // No permissions
return permissions;
}
private PermissionCollection applicationPermissions() {
Permissions permissions = new Permissions();
permissions.add(new AllPermission());
return permissions;
}
}
当我运行主类并且代码执行时plugin.build()
,我得到一个带有以下跟踪的 stackoverflow 异常:
*** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at JPLISAgent.c line: 844
*** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at JPLISAgent.c line: 844
*** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at JPLISAgent.c line: 844
Exception in thread "main" java.lang.StackOverflowError
at sun.nio.cs.UTF_8.updatePositions(UTF_8.java:77)
at sun.nio.cs.UTF_8.access$200(UTF_8.java:57)
at sun.nio.cs.UTF_8$Encoder.encodeArrayLoop(UTF_8.java:636)
at sun.nio.cs.UTF_8$Encoder.encodeLoop(UTF_8.java:691)
at java.nio.charset.CharsetEncoder.encode(CharsetEncoder.java:579)
at sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:271)
at sun.nio.cs.StreamEncoder.write(StreamEncoder.java:125)
at java.io.OutputStreamWriter.write(OutputStreamWriter.java:207)
at java.io.BufferedWriter.flushBuffer(BufferedWriter.java:129)
at java.io.PrintStream.write(PrintStream.java:526)
at java.io.PrintStream.print(PrintStream.java:669)
at java.io.PrintStream.println(PrintStream.java:806)
at SandboxSecurityPolicy.getPermissions(SandboxSecurityPolicy.java:12)
at java.security.Policy.implies(Policy.java:721)
at java.security.ProtectionDomain.implies(ProtectionDomain.java:285)
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:450)
at java.security.AccessController.checkPermission(AccessController.java:884)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
at java.lang.SecurityManager.checkPackageAccess(SecurityManager.java:1564)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:318)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at SandboxSecurityPolicy.isPlugin(SandboxSecurityPolicy.java:23)
at SandboxSecurityPolicy.getPermissions(SandboxSecurityPolicy.java:13)
我不确定为什么instanceOf
会创建导致此溢出的递归。我感谢您的帮助。谢谢!
更新:我在另一台机器上运行了相同的代码,它运行良好。这似乎是一个 JDK 错误。
解决方案
推荐阅读
- python - 使用 PostgresSQL 在 Flask 中的 SQLALChemy 中运行 db.create_all() 时出错
- c# - 需要帮助从谷歌身份验证获取电子邮件
- reactjs - 如何在反应中渲染嵌套对象中的数据?
- windows - 当线程阻塞等待事件时,SysInternals 的进程监视器可以记录吗?
- python-3.x - Extract medical marker name, values and units from analysed image?
- json - 相同结构的 Elixir 多个 Jason 编码器
- php - 如何将 XML 发送到 wsdl 端点
- python - 在 anaconda windows 中从 Python 调用 c++ 函数
- python - 消费者无法连接到 amqp || 芹菜
- java - 如何使用 Hibernate 从存储过程中检索输出参数