动态代码评估: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);
        }

 }

您可以使用acceptreject方法进行更安全的反序列化操作。

示例:

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 + '\'' +
                    '}';
        }
    }
}