使用JNI能否避免JVM安全问题?

4
我一直在思考jvm安全性的工作方式。原则是 jvm 总是信任并运行任何本机代码。因此,从概念上讲,如果您的代码没有明确或隐含地调用 checkpermission(permission),那么它就永远不会失败于任何安全验证。当然,所有这些验证调用通常都是在Java API类中完成的,所以我们不需要为内置权限自己调用它们。
只要您使用像 FileOutputStream 这样的内置类,您的代码始终受到权限检查的影响。但是,经过一段时间的思考后,我想知道是否可以通过使用Java Native Interface来运行 c++ 代码来避免安全检查。
想象一下,您导入了一些 jar 包,该包与其使用 FileOutputStream 写入文件不同,而是使用一些手工制作的 JNI 与写入文件的 C++ 程序绑定(显然不会调用任何 checkpermission())。根据问题“如何将本机库和 JNI 库捆绑到 JAR 中?”(How to bundle a native library and a JNI library inside a JAR?),我了解到可能会将所有内容捆绑在一个好的恶意 jar 包中。因此,使用此 jar 包的任何代码都不再安全,因为执行来自jar的代码时不会进行任何安全验证。这意味着,此 c++ 程序可以有效地覆盖 jvm 运行进程具有写权限的所有文件。
我是否正确思考,并且这是有意的还是我漏掉了什么?
1个回答

5

你说得对,本地代码超出了JVM的控制范围。如果Java安全管理器允许加载JNI库,则应将其视为根本不存在安全管理器。

这就是为什么,如果使用SecurityManager,重要的是不要授予loadLibrary.* 权限


那么我应该如何通过互联网加载一个类呢?我知道可以使用UrlClassLoader,但不确定如何将其运用到需要从远程jar文件加载类的情况中。 - Turkhan Badalov
2
@TurkhanBadalov 我不确定问题出在哪里。从jar中加载类与加载本地库不同。您可以允许加载类,但拒绝加载JNI库 - 这些由不同的权限管理。 - apangin
哦,好的,我的错。所以loadLibrary.*是专门用于本地库的,明白了。谢谢! - Turkhan Badalov
2
@TurkhanBadalov 注意,本地代码不需要实现自己的I/O来破坏安全性。在许多JRE实现中,只需将字段System.security设置为null即可禁用所有安全检查,这是一种甚至Java代码也可能犯的错误,当授予其具有访问权限覆盖的反射权限时。因此,通常,代码应该获得执行其工作所需的最低权限,因为权限可能具有易于忽视的影响。 - Holger
这与小应用程序相同,并通过对小应用程序进行签名以确保它们的安全性来解决。 - user1889970

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接