是否可以通过使用 JNI 来避免 jvm 安全?

Tur*_*lov 4 java java-native-interface jvm jar java-security

我一直在思考 jvm 安全的工作方式。其原理是 jvm 始终信任并运行任何本机代码。因此,从概念上讲,如果您的代码不checkpermission(permission)显式或隐式调用,则意味着它永远不会失败任何安全验证。当然,所有这些验证调用通常都是在 Java API 类中完成的,因此我们不需要自己调用它们来获取内置权限。

现在,只要您使用诸如 之类的内置类FileOutputStream,您的代码就始终需要接受权限检查。但是想了想之后,我想知道是否可以通过使用Java Native Interface来运行c++代码来避免安全检查。

想象一下,您导入了一些 jar,而不是FileOutputStream用来写入文件,而是使用一些手工制作的 JNI,这些 JNI 绑定到文件编写 C++ 程序(显然它不调用任何checkpermission())。基于问题“如何在 JAR 中捆绑本机库和 JNI 库? ”,我了解到可以将所有内容捆绑在一个漂亮的恶意 jar 中。因此,使用此 jar 的任何代码都不再安全,因为从 jar 执行代码时不会进行安全验证。这意味着这个 c++ 程序可以有效地覆盖运行 jvm 的进程对其具有写权限的所有文件。

这是正确的思维方式,它是有意为之还是我错过了什么?

apa*_*gin 5

您是对的,本机代码不受 JVM 控制。如果 Java 安全管理器允许加载 JNI 库,请将其视为根本没有安全管理器。

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

  • @TurkhanBadalov 我不确定问题是什么。从 jar 加载类与加载本机库不同。您可以允许加载类,但拒绝加载 JNI 库 - 这些由不同的权限管理。 (2认同)
  • @TurkhanBadalov 注意到本机代码不需要实现自己的 I/O 来破坏安全性。在许多 JRE 实现中,只需将“System.security”字段设置为“null”就会禁用所有安全检查,甚至 Java 代码在错误地授予其通过访问覆盖进行反射的权限时也会执行此操作。因此,一般来说,代码应该获得完成其工作所需的最低权限,因为权限可能具有容易被忽视的含义。 (2认同)