如果我有一个游戏,我想检测是否有人在某些类中反射字段,我该怎么做?我知道他们必须将字段设置为可访问的。
我被告知,我无法检测是否有人加载了我的类,并使用反射访问字段。
我想知道我是否可以创建一个线程,不断检查是否someField.isAccessible()返回true。
这是一个好方法吗?它会起作用吗?它在我自己的类中工作,但如果有人创建一个类来加载我的jar并获取字段,它会工作吗?他们必须将其设置为可访问的,这就是为什么我问这是否是一个好方法。
有什么想法或建议吗?
如果他们真的想做这些事,你不能阻止他们。
即使你的方法有效,他们也可以反编译你的类,去掉麻烦的检查,然后编译他们自己的版本。
防止你的软件被"黑客"的唯一方法是不要分发它,而是在你自己的机器上运行它("软件即服务")。可能是"安全关键"部分的唯一选择。
如果您控制代码在中执行的JVM(托管一些用户提供的代码),则可以安装自定义SecurityManager。如其文档所述,Field。setAccessible将调用已安装的SecurityManager,它可以通过抛出SecurityException(或记录它或其他)来否决setAccessible调用。不幸的是,传递给SecurityManager的ReflectPermission对象不包含被授予访问权限的字段,因此您不能选择性地拒绝对特定字段的访问。你能做的是检查调用堆栈(使用SecurityManager.getClassContext()),如果堆栈上有任何用户提供的代码,则拒绝访问。
也可能有一种方法可以通过默认的SecurityManager实现和策略文件强制执行,但是策略文件文档中的所有示例都是关于授予权限,而不是撤销权限。这意味着您必须弄清楚非用户提供的代码所需的所有权限,并提供适当的策略文件。(白名单通常是比黑名单更好的安全策略,但需要更多的努力来设置。)
这都是基于JVM安全实现的工作文档;您可能知道,有几个基于苹果的漏洞利用漏洞来逃离JVM沙箱。最好不要在包含敏感信息的同一JVM中运行用户提供的代码,而是依靠操作系统级别的进程隔离来实现安全性。但是严格地考虑你的问题("我能检测setAccessible吗?"),如果你能控制JVM,答案是肯定的。
如果您不控制JVM,代码在中执行(您将代码交给用户自己运行),保护是徒劳的。除了在运行代码之前修改代码以删除保护之外,它们还可以简单地在修改后的JVM上运行,该JVM不强制对源自其代码的反射操作进行访问检查,或者直接修改您试图保护的任何字段。