xref: /OpenGrok/opengrok-indexer/src/main/java/org/opengrok/indexer/configuration/ConfigurationClassLoader.java (revision a2fc1abb4fbe809917538172e005caf2ee9fa82a)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * See LICENSE.txt included in this distribution for the specific
9  * language governing permissions and limitations under the License.
10  *
11  * When distributing Covered Code, include this CDDL HEADER in each
12  * file and include the License file at LICENSE.txt.
13  * If applicable, add the following below this CDDL HEADER, with the
14  * fields enclosed by brackets "[]" replaced with your own identifying
15  * information: Portions Copyright [yyyy] [name of copyright owner]
16  *
17  * CDDL HEADER END
18  */
19 
20 /*
21  * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
22  */
23 package org.opengrok.indexer.configuration;
24 
25 import io.micrometer.statsd.StatsdFlavor;
26 import org.opengrok.indexer.authorization.AuthControlFlag;
27 import org.opengrok.indexer.authorization.AuthorizationEntity;
28 import org.opengrok.indexer.authorization.AuthorizationPlugin;
29 import org.opengrok.indexer.authorization.AuthorizationStack;
30 import org.opengrok.indexer.authorization.IAuthorizationPlugin;
31 import org.opengrok.indexer.configuration.Configuration.RemoteSCM;
32 import org.opengrok.indexer.history.RepositoryInfo;
33 
34 import java.beans.XMLDecoder;
35 import java.util.ArrayList;
36 import java.util.Collections;
37 import java.util.HashMap;
38 import java.util.HashSet;
39 import java.util.Set;
40 import java.util.TreeSet;
41 import java.util.stream.Collectors;
42 
43 /**
44  * Temporary hack to prevent {@link XMLDecoder} to deserialize other than allowed classes. This tries to prevent
45  * calling of methods on {@link ProcessBuilder} or {@link Runtime} (or similar) which could be used for code execution.
46  */
47 public class ConfigurationClassLoader extends ClassLoader {
48 
49     private static final Set<String> allowedClasses = Set.of(
50             ArrayList.class,
51             AuthControlFlag.class,
52             AuthorizationEntity.class,
53             AuthorizationPlugin.class,
54             AuthorizationStack.class,
55             Collections.class,
56             Configuration.class,
57             Enum.class,
58             Filter.class,
59             Group.class,
60             HashMap.class,
61             HashSet.class,
62             IAuthorizationPlugin.class,
63             IgnoredNames.class,
64             LuceneLockName.class,
65             Project.class,
66             RemoteSCM.class,
67             RepositoryInfo.class,
68             Set.class,
69             StatsdConfig.class,
70             StatsdFlavor.class,
71             String.class,
72             SuggesterConfig.class,
73             TreeSet.class,
74             XMLDecoder.class
75     ).stream().map(Class::getName).collect(Collectors.toSet());
76 
77     @Override
loadClass(final String name)78     public Class<?> loadClass(final String name) throws ClassNotFoundException {
79         if (!allowedClasses.contains(name)) {
80             throw new IllegalAccessError(name + " is not allowed to be used in configuration");
81         }
82 
83         return getClass().getClassLoader().loadClass(name);
84     }
85 }
86