有没有办法在 Java 中执行不安全的代码(禁用安全管理器)?
Posted
技术标签:
【中文标题】有没有办法在 Java 中执行不安全的代码(禁用安全管理器)?【英文标题】:Is there a way to execute unsafe code (disable security manager) in Java? 【发布时间】:2013-03-11 22:05:02 【问题描述】:请不要发布“你不应该这样做”的答案。我不打算在生产代码中使用它,而只是为了一些黑客的乐趣。
在回答this question 时,我想运行一些任意不安全的Java 代码来取乐。有问题的代码只涉及查找 Java TreeMap
的 leaf 节点。
运行下面的代码结果
Exception in thread "main" java.lang.SecurityException: Prohibited package name: java.util
根据this question,我可以使用System.setSecurityManager(null)
来绕过大部分这些限制。但我不能这样做,因为加载我的类时会弹出错误。
我已经知道,在禁用安全管理器后,我可以使用反射来做所有我想做的事情。但这会使代码更难看。 核心 Java 开发人员如何编写他们的单元测试,例如,如果他们无法在 java.util
中打包东西?
我也尝试了-Djava.security.manager=...
,但是当我将其设置为null
时,这会导致 JVM 初始化错误,而且我不确定我还能将其设置为什么。有什么想法吗?
package java.util;
import java.util.TreeMap.Entry;
public class TreeMapHax
static <K,V> List<Entry<K, V>> getLeafEntries(TreeMap<K, V> map)
Entry<K, V> root = map.getFirstEntry();
while( root.parent != null ) root = root.parent;
List<Entry<K,V>> l = new LinkedList<Entry<K,V>>();
visitInOrderLeaves(root, l);
return l;
static <K,V> void visitInOrderLeaves(Entry<K, V> node, List<Entry<K, V>> accum)
if( node.left != null ) visitInOrderLeaves(node.left, accum);
if( node.left == null && node.right == null ) accum.add(node);
if( node.right != null ) visitInOrderLeaves(node.right, accum);
public static void main(String[] args)
TreeMap<String, Integer> map = new TreeMap<String, Integer>();
for( int i = 0; i < 10; i++ )
map.put(Integer.toString(i), i);
System.out.println(getLeafEntries(map));
【问题讨论】:
我猜核心开发人员要么乐于将他们的测试放在不同的包中(因为他们应该测试公共接口),要么有一个没有这些安全限制的 JVM 构建。毕竟,Oracle 是编写 JVM 代码的公司。 也许尝试获取源(冰茶或类似的东西),将您的文件偷偷放入“正确”的包中,然后编译整个东西?我不知道这是否可行,但它可能足以欺骗系统。这就是我要尝试的。 您可以使用引导类路径。创建您自己的 jar,其中包含 rt.jar 和此类中的所有内容。这是一个丑陋的黑客,但你说你确实想黑客。 【参考方案1】:简单回答你的问题,没有通常的方法
java.* 中的类不受安全管理器的限制, 它们受到类加载器的限制。
做你想做的事,你需要找到一种方法来破解 jvm。 或者就像你提到的那样,通过反思来做。 或者只是在您自己的包中创建树图的副本(源克隆)。
【讨论】:
【参考方案2】:如果您创建了一个自定义的java.lang.SecurityManager 并删除了所有安全逻辑,并将其编译到自定义 JVM 中,您应该能够通过将“java.security.manager”属性设置为自定义管理器来引用它.
由于Launcher 在您的程序启动之前读取该属性,因此您必须将自定义 SecurityManager 放在 JVM 认可的类路径中,而不是您自己的程序中(例如捆绑在核心 rt.jar 文件中)。
回答您关于核心开发人员如何处理此问题的问题:此类测试可能会针对自定义 JVM 运行,因为它们不遵守生产 JVM 的传统安全性。可以在here 找到此类存根的一个示例。
【讨论】:
【参考方案3】:我认为您可以尝试为您的自定义 Java 包创建 jar 并将其放入 $JRE_HOME/lib/ext 并看到魔法!
【讨论】:
以上是关于有没有办法在 Java 中执行不安全的代码(禁用安全管理器)?的主要内容,如果未能解决你的问题,请参考以下文章