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