我听说反射机制打破了Java的安全性。请有人解释一下吗?
答案 0 :(得分:2)
显然,如果反射API明显破坏了applet安全性,那么现在有人会注意到。
首先,我们需要一些背景知识。不同寻常的是,Java平台/可以/为运行不受信任的代码提供安全的环境(给出或接受奇怪的错误 - 如果找到,请让Oracle安全响应团队知道)。但是,Java的大多数用法都忽略了这一点。
当安全地运行时,反射API会限制不受信任的代码可以做大致无需反射的功能(除了一些标准的Java安全检查之外,还会检查直接调用者 - 请参阅Secure Coding Guidelines for the Java Programming Language)。例如,不受信任的代码可以访问同一个包中的“package private”类,但不能访问其他包中的类。
你为什么要用反射?通常,因为它允许您以代表某些客户端代码的开放式类型集合以相同的方式操作。客户端代码通常位于其他一些包中,但反射API将限制基于反射使用代码的访问。因此,除非使用反射使用代码,否则客户端代码具有访问权限,不应该被允许。这是一个丰富的漏洞来源。
如果没有安全运行,您可以读/写文件,运行程序等,那么谁在乎?
答案 1 :(得分:1)
您可以访问私人字段&使用反射的对象方法
例如
public class Foo {
private String privateString = null;
public Foo(String privateString) {
this.privateString = privateString;
}
}
Foo privateObject = new Foo("The Private Value");
Field privateStringField = Foo.class.
getDeclaredField("privateString");
privateStringField.setAccessible(true);
String fieldValue = (String) privateStringField.get(privateObject);
System.out.println("fieldValue = " + fieldValue);
答案 2 :(得分:1)
使用reflection几乎可以做任何事情:通过setting them as accessable访问私有变量,并修改不可变对象
一个常见示例是更改String:
public static void main(String[] args) throws Exception {
String s = "before";
System.out.println(s);
Field value = String.class.getDeclaredField("value");
value.setAccessible(true);
Field count = String.class.getDeclaredField("count");
count.setAccessible(true);
char[] after = {'a','f','t','e','r','\0' };
value.set(s, after);
count.set(s,5);
System.out.println(s);
}
在此示例中 - 实际的字符串对象正在更改!
请注意,使用反射来更改不可变对象有其自身的问题,您可以在this post
中看到