SV.SERIAL.OVERRIDE
不要从 readObject() 方法调用可替代的方法
当一个类直接或间接地实施 java.io.Serializable 接口,但声明的方法 readObject 调用可替代的方法时,Klocwork 会针对此类报告 SV.SERIAL.OVERRIDE 问题。
漏洞与风险
readObject() 方法不得调用任何可替代的方法。从 readObject() 方法调用可替代的方法,可以为替代方法提供在对象未完成完全初始化时访问对象状态的权限。这种过早访问可能会发生,因为在反序列化中,readObject 方法扮演的是对象构造函数的角色,因此对象初始化要直到 readObject 退出才会完成。
漏洞代码示例 1
class SV_SERIAL_OVERRIDE implements Serializable {
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.readObject();
publicMethod();
protectedMethod();
}
public void publicMethod() {
}
protected void protectedMethod() {
}
}
在此示例中,Klocwork 在第 4 行和第 5 行均报告 SV.SERIAL.OVERRIDE 缺陷,分别表示“从 readObject() 方法调用了可替代的方法 publicMethod()”以及“从 readObject() 方法调用了可替代的方法 protectedMethod()”。
修正代码示例 1
class SV_SERIAL_OVERRIDE implements Serializable {
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.readObject();
publicMethod();
protectedMethod();
}
private void publicMethod() {
}
private void protectedMethod() {
}
}
在此示例中,Klocwork 在第 4 行和第 5 行不再报告 SV.SERIAL.OVERRIDE 缺陷,因为 publicMethod() 和 privateMethod() 已声明为 private,因此不会被替代。
漏洞代码示例 2
class SV_SERIAL_OVERRIDE implements Serializable {
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.readObject();
method1();
method2();
}
void method1() {
}
void method2() {
}
}
在此示例中,Klocwork 在第 4 行和第 5 行均报告 SV.SERIAL.OVERRIDE 缺陷,分别表示“从 readObject() 方法调用了可替代的方法 method1()”以及“从 readObject() 方法调用了可替代的方法 method2()”。
修正代码示例 2
class SV_SERIAL_OVERRIDE implements Serializable {
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.readObject();
method1();
method2();
}
final void method1() {
}
final void method2() {
}
}
在此示例中,Klocwork 在第 4 行和第 5 行不再报告 SV.SERIAL.OVERRIDE 缺陷,因为 method1() 和 method2() 已声明为 final,因此不会被替代。