java劣质代码 java恶意代码( 二 )


建议
从软件工程观点来看,包作用域具有重要意义,因为它可以阻止对您想隐藏的内容进行偶然的、无意中的访问 。但不要依靠它来获取安全性 。应该将类、方法和变量显式标注为 public、private 或 protected 中适合您特定需求的那种 。
使类不可克隆
克隆允许绕过构造器而轻易地复制类实例 。
影响
即使您没有有意使类可克隆,外部源仍然可以定义您的类的子类,并使该子类实现 java.lang.Cloneable 。这就让攻击者创建了您的类的新实例 。拷贝现有对象的内存映象生成了新的实例;虽然这样做有时候是生成新对象的可接受方法,但是大多数时候是不可接受的 。清单 3 说明了因为可克隆而暴露的代码:
清单 3. 可克隆代码
class MyClass{
private int id;
private String name;
public MyClass(){
id=1;
name="HaryPorter";
}
public MyClass(int id,String name){
this.id=id;
this.name=name;
}
public void display(){
System.out.println("Id ="+id+"
"+"Name="+name);
}
}
// hackers code to clone the user class
public class Hacker extends MyClass implements Cloneable {
public static void main(String[] args){
Hacker hack=new Hacker();
try{
MyClass o=(MyClass)hack.clone();
o.display();
}
catch(CloneNotSupportedException e){
e.printStackTrace();
}
}
}
建议
要防止类被克?。?可以将清单 4 中所示的方法添加到您的类中:
清单 4. 使您的代码不可克隆
public final Object clone()
throws java.lang.CloneNotSupportedException{
throw new java.lang.CloneNotSupportedException();
}
如果想让您的类可克隆并且您已经考虑了这一选择的后果,那么您仍然可以保护您的类 。要做到这一点,请在您的类中定义一个为 final 的克隆方法,并让它依赖于您的一个超类中的一个非 final 克隆方法,如清单 5 中所示:
清单 5. 以安全的方式使您的代码可克隆
public final Object clone()
throws java.lang.CloneNotSupportedException {
super.clone();
}
类中出现 clone() 方法防止攻击者重新定义您的 clone 方法 。
使类不可序列化
序列化允许将类实例中的数据保存在外部文件中 。闯入代码可以克隆或复制实例,然后对它进行序列化 。
影响
序列化是令人担忧的,因为它允许外部源获取对您的对象的内部状态的控制 。这一外部源可以将您的对象之一序列化成攻击者随后可以读取的字节数组,这使得攻击者可以完全审查您的对象的内部状态,包括您标记为 private 的任何字段 。它也允许攻击者访问您引用的任何对象的内部状态 。
建议
要防止类中的对象被序列化,请在类中定义清单 6 中的 writeObject() 方法:
清单 6. 防止对象序列化
private final void writeObject(ObjectOutputStream out)
throws java.io.NotSerializableException {
throw new java.io.NotSerializableException("This object cannot
be serialized");
}
通过将 writeObject() 方法声明为 final , 防止了攻击者覆盖该方法 。
使类不可逆序列化
通过使用逆序列化,攻击者可以用外部数据或字节流来实例化类 。
影响
不管类是否可以序列化,都可以对它进行逆序列化 。外部源可以创建逆序列化成类实例的字节序列 。这种可能为您带来了大量风险,因为您不能控制逆序列化对象的状态 。请将逆序列化作为您的对象的另一种公共构造器 — 一种您无法控制的构造器 。
建议
要防止对对象的逆序列化,应该在您的类中定义清单 7 中的 readObject() 方法:

推荐阅读