1 /*
2 * This file is part of dependency-check-core.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * Copyright (c) 2016 Jeremy Long. All Rights Reserved.
17 */
18 package org.owasp.dependencycheck.utils;
19
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.io.InvalidClassException;
23 import java.io.ObjectInputStream;
24 import java.io.ObjectStreamClass;
25 import java.util.ArrayList;
26 import java.util.Arrays;
27 import java.util.List;
28
29 /**
30 * An ObjectInputStream that will only deserialize expected classes.
31 *
32 * @author Jeremy Long
33 */
34 public class ExpectedOjectInputStream extends ObjectInputStream {
35
36 /**
37 * The list of fully qualified class names that are able to be deserialized.
38 */
39 private List<String> expected = new ArrayList<String>();
40
41 /**
42 * Constructs a new ExpectedOjectInputStream that can be used to securely deserialize an object by restricting the classes
43 * that can deserialized to a known set of expected classes.
44 *
45 * @param inputStream the input stream that contains the object to deserialize
46 * @param expected the fully qualified class names of the classes that can be deserialized
47 * @throws IOException thrown if there is an error reading from the stream
48 */
49 public ExpectedOjectInputStream(InputStream inputStream, String... expected) throws IOException {
50 super(inputStream);
51 this.expected.addAll(Arrays.asList(expected));
52 }
53
54 /**
55 * Only deserialize instances of expected classes by validating the class name prior to deserialization.
56 *
57 * @param desc the class from the object stream to validate
58 * @return the resolved class
59 * @throws java.io.IOException thrown if the class being read is not one of the expected classes or if there is an error
60 * reading from the stream
61 * @throws java.lang.ClassNotFoundException thrown if there is an error finding the class to deserialize
62 */
63 @Override
64 protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
65 if (!this.expected.contains(desc.getName())) {
66 throw new InvalidClassException("Unexpected deserialization ", desc.getName());
67 }
68 return super.resolveClass(desc);
69 }
70 }