【发布时间】:2013-11-20 07:40:21
【问题描述】:
在 Java 中,private 访问修饰符被认为是安全的,因为它在类之外是不可见的。那么外界也不知道这种方法。
但我认为 Java 反射可以用来打破这个规则。考虑以下情况:
public class ProtectedPrivacy{
private String getInfo(){
return "confidential";
}
}
现在我要从另一个班级获得信息:
public class BreakPrivacy{
public static void main(String[] args) throws Exception {
ProtectedPrivacy protectedPrivacy = new ProtectedPrivacy();
Method method = protectedPrivacy.getClass().getDeclaredMethod("getInfo", null);
method.setAccessible(true);
Object result = method.invoke(protectedPrivacy);
System.out.println(result.toString());
}
}
此时我只是认为私有方法仍然是安全的,因为要执行上述操作,我们必须知道方法名称。但是,如果类包含由其他人编写的私有方法,我们将无法看到这些。
但是由于下面的代码行,我的观点变得无效。
Method method[] = new ProtectedPrivacy().getClass().getDeclaredMethods();
现在这个method[] 包含了上面所有需要做的事情。我的问题是,有没有办法避免使用 Java 反射做这种事情?
我引用Java Documentation 的一些观点来澄清我的问题。
选择访问级别的提示:
如果其他程序员使用你的类,你要确保错误 不会发生误用。访问级别可以帮助您做到这一点。使用 对特定的有意义的最严格的访问级别 成员。除非您有充分的理由不这样做,否则请使用私有。
【问题讨论】:
-
使用混淆器可能会有所帮助,因为
getDeclaredMethods会返回看起来像垃圾的名称。 -
私人、受保护的公共等不是为了安全,而是为了避免善意的人犯错。不要将其用作安全措施
-
Java 代码无论如何都是可反编译的。 “攻击者”可以下载 Java 反编译器并读取您的代码,或者将“私有”更改为“公共”。
-
详细说明@RichardTingle 的评论(+1 顺便说一句)。安全性和安全性之间存在巨大而重要的区别。后者是使用访问修饰符缓解的问题;不要意外弄坏东西
-
对于不存在访问修饰符的程序员来说,这一切都很清楚,比如在 Python 中。在这些语言中,私有/公共只是通过名称中的约定来区分(在 python 中,任何以单个下划线开头的东西都应该被认为是私有的)。这清楚地表明,将某些内容标记为“私有”确实不会增加任何安全性,但这只是说明人们应该使用您的 API 的一种简单方式。我怀疑让编译器检查这些东西是否有帮助,因为在没有“外部”帮助的情况下很容易遵循约定。
标签: java reflection private access-modifiers