【发布时间】:2014-10-08 13:51:44
【问题描述】:
JVM 下是否有办法(暂时)阻止对 System.out、System.in 和 System.err 的完全访问?
创建一个完全不授予权限的空白策略后,我想在下面的函数中执行一些工作。 我希望对 System.out.println 等的调用失败,但他们没有。有什么我可以做的,还是我有点控制狂? p>
编辑 #1: 按照 MrPixelDream 的使用 System.setOut 的建议,我将权限保持在最低限度,以确保 run() 中的代码也不能调用 System.setOut 或与 @ 胡闹987654324@.
编辑#2:另外,由于恶意代码可以简单地执行standardOutput.println,我宁愿根本不保留对System.out 的引用,而是使用java.io.FileDescriptor.out 将其设置回来。
// Create blank permissions that barely allow executing code
java.security.Permissions perm = new java.security.Permissions();
// CodeSource domain for which these permissions apply (all files)
java.security.CodeSource code = new java.security.CodeSource(new java.net.URL("file:/*"),
null);
// ProtectionDomain
java.security.ProtectionDomain domain = new java.security.ProtectionDomain(code, perm);
// AccessControlContext
java.security.ProtectionDomain[] domains = new java.security.ProtectionDomain[1];
domains[0] = domain;
java.security.AccessControlContext context =
new java.security.AccessControlContext(domains);
// DON'T keep reference to standard output, it could be used directly
// PrintStream standardOut = System.out;
// Redirect output to dummy stream
System.setIn(new ByteArrayInputStream(new byte[0]));
System.setOut(new PrintStream(new ByteArrayOutputStream()));
System.setErr(new PrintStream(new ByteArrayOutputStream()));
// Do an action, subject to the given security context
java.security.AccessController.doPrivileged(new java.security.PrivilegedAction<Void>() {
public Void run() {
// Do some work, side effects and all, but no I/O whatsoever
System.out.println("Will not print !");
// Try to fool around System.out with direct access from file descriptors (0, 1, 2)
java.io.PrintStream myOut =
new java.io.PrintStream(new java.io.FileOutputStream(java.io.FileDescriptor.out));
// Missing permission java.lang.RuntimePermission "setIO"
// Will throw java.security.AccessControlException
System.setOut(myOut);
// Missing permission java.lang.RuntimePermission "writeFileDescriptor"
myOut.println("Will throw java.security.AccessControlException !");
}
}, context);
// Now set back the old streams to have output again
System.setIn(new java.io.FileInputStream(java.io.FileDescriptor.in));
System.setOut(
new java.io.PrintStream(new java.io.FileOutputStream(java.io.FileDescriptor.out)));
System.setErr(
new java.io.PrintStream(new java.io.FileOutputStream(java.io.FileDescriptor.err)));
【问题讨论】:
-
“我是不是太控制狂了?”也许,你为什么要阻止它?
-
长话短说,我正在使用 System.in/System.out 在这个受限的子 JVM 和它的父 JVM 之间进行通信。子 JVM 将用户提供的 javascript 代码提交给 Nashorn,并通过 System.out 将结果返回给父 JVM。如果 JavaScript 代码也要打印,它可能会扰乱我的沟通渠道。
标签: java security io permissions jvm