动态代码评估:SerializationUtils.clone() 上的不安全反序列化
Dynamic Code Evaluation: Unsafe Deserialization on SerializationUtils.clone()
我遇到了 Fortify 问题 动态代码评估:不安全的反序列化 在以下行中:
@RequestMapping(value="/v2/doc", method=RequestMethod.POST)
public JsonDocVerifyResponse verify(@RequestBody JsonDocVerifyRequestV3 request)
JsonDocVerifyRequestV3 temp = (JsonDocVerifyRequestV3)SerializationUtils.clone(request);
不安全反序列化的解决方案是这样https://www.ibm.com/developerworks/library/se-lookahead/
但是正如您在我的代码中看到的那样,我没有使用 ByteArrayOutputStream 来反序列化对象。
这是 Fortify 的误报吗?如果没有,我该如何使用
org.apache.commons.io.serialization.ValidatingObjectInputStream
验证class?任何代码示例都会有很大帮助!
这些是片段:
@RequestMapping(value="/v2/doc", method=RequestMethod.POST)
public JsonDocVerifyResponse verify(@RequestBody JsonDocVerifyRequestV3 request) {
debugJsonRequest(request, DOC_TYPE.khIdBack);
JsonDocVerifyResponse response = new JsonDocVerifyResponse();
return response;
}
public void debugJsonRequest(JsonDocVerifyRequestV3 request, DOC_TYPE docType) {
try {
JsonDocVerifyRequestV3 temp(JsonDocVerifyRequestV3) SerializationUtils.clone(request);
LOGGER.debug("{}|{}", docType, CommonUtil.debugJsonObject(temp));
} catch(Exception e) {
LOGGER.error("Error in debug json object", e);
}
}
您可以使用accept
和reject
方法进行更安全的反序列化操作。
示例:
import com.sun.xml.internal.ws.util.ByteArrayBuffer;
import org.apache.commons.io.serialization.ValidatingObjectInputStream;
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Bar bar = new Bar("bar-test");
Foo foo = new Foo("test-foo", bar);
// write into an array buffer
ByteArrayBuffer buffer = new ByteArrayBuffer();
try (ObjectOutputStream serializeStream = new ObjectOutputStream(buffer)) {
serializeStream.writeObject(foo);
}
try (ValidatingObjectInputStream stream = new ValidatingObjectInputStream(buffer.newInputStream())) {
// add validated classes
stream.accept(Foo.class);
stream.accept(Bar.class);
Foo foo2 = (Foo) stream.readObject();
System.out.println(foo2);
}
}
public static class Foo implements Serializable {
private String name;
private Bar bar;
public Foo(String name, Bar bar) {
this.name = name;
this.bar = bar;
}
@Override
public String toString() {
return "Foo{" +
"name='" + name + '\'' +
", bar=" + bar +
'}';
}
}
public static class Bar implements Serializable {
private String name;
public Bar(String name) {
this.name = name;
}
@Override
public String toString() {
return "Bar{" +
"name='" + name + '\'' +
'}';
}
}
}
我遇到了 Fortify 问题 动态代码评估:不安全的反序列化 在以下行中:
@RequestMapping(value="/v2/doc", method=RequestMethod.POST)
public JsonDocVerifyResponse verify(@RequestBody JsonDocVerifyRequestV3 request)
JsonDocVerifyRequestV3 temp = (JsonDocVerifyRequestV3)SerializationUtils.clone(request);
不安全反序列化的解决方案是这样https://www.ibm.com/developerworks/library/se-lookahead/ 但是正如您在我的代码中看到的那样,我没有使用 ByteArrayOutputStream 来反序列化对象。
这是 Fortify 的误报吗?如果没有,我该如何使用
org.apache.commons.io.serialization.ValidatingObjectInputStream
验证class?任何代码示例都会有很大帮助!
这些是片段:
@RequestMapping(value="/v2/doc", method=RequestMethod.POST)
public JsonDocVerifyResponse verify(@RequestBody JsonDocVerifyRequestV3 request) {
debugJsonRequest(request, DOC_TYPE.khIdBack);
JsonDocVerifyResponse response = new JsonDocVerifyResponse();
return response;
}
public void debugJsonRequest(JsonDocVerifyRequestV3 request, DOC_TYPE docType) {
try {
JsonDocVerifyRequestV3 temp(JsonDocVerifyRequestV3) SerializationUtils.clone(request);
LOGGER.debug("{}|{}", docType, CommonUtil.debugJsonObject(temp));
} catch(Exception e) {
LOGGER.error("Error in debug json object", e);
}
}
您可以使用accept
和reject
方法进行更安全的反序列化操作。
示例:
import com.sun.xml.internal.ws.util.ByteArrayBuffer;
import org.apache.commons.io.serialization.ValidatingObjectInputStream;
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Bar bar = new Bar("bar-test");
Foo foo = new Foo("test-foo", bar);
// write into an array buffer
ByteArrayBuffer buffer = new ByteArrayBuffer();
try (ObjectOutputStream serializeStream = new ObjectOutputStream(buffer)) {
serializeStream.writeObject(foo);
}
try (ValidatingObjectInputStream stream = new ValidatingObjectInputStream(buffer.newInputStream())) {
// add validated classes
stream.accept(Foo.class);
stream.accept(Bar.class);
Foo foo2 = (Foo) stream.readObject();
System.out.println(foo2);
}
}
public static class Foo implements Serializable {
private String name;
private Bar bar;
public Foo(String name, Bar bar) {
this.name = name;
this.bar = bar;
}
@Override
public String toString() {
return "Foo{" +
"name='" + name + '\'' +
", bar=" + bar +
'}';
}
}
public static class Bar implements Serializable {
private String name;
public Bar(String name) {
this.name = name;
}
@Override
public String toString() {
return "Bar{" +
"name='" + name + '\'' +
'}';
}
}
}