181511796SAdam Hornacek /* 281511796SAdam Hornacek * CDDL HEADER START 381511796SAdam Hornacek * 481511796SAdam Hornacek * The contents of this file are subject to the terms of the 581511796SAdam Hornacek * Common Development and Distribution License (the "License"). 681511796SAdam Hornacek * You may not use this file except in compliance with the License. 781511796SAdam Hornacek * 881511796SAdam Hornacek * See LICENSE.txt included in this distribution for the specific 981511796SAdam Hornacek * language governing permissions and limitations under the License. 1081511796SAdam Hornacek * 1181511796SAdam Hornacek * When distributing Covered Code, include this CDDL HEADER in each 1281511796SAdam Hornacek * file and include the License file at LICENSE.txt. 1381511796SAdam Hornacek * If applicable, add the following below this CDDL HEADER, with the 1481511796SAdam Hornacek * fields enclosed by brackets "[]" replaced with your own identifying 1581511796SAdam Hornacek * information: Portions Copyright [yyyy] [name of copyright owner] 1681511796SAdam Hornacek * 1781511796SAdam Hornacek * CDDL HEADER END 1881511796SAdam Hornacek */ 1981511796SAdam Hornacek 2081511796SAdam Hornacek /* 2181511796SAdam Hornacek * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. 2281511796SAdam Hornacek */ 2381511796SAdam Hornacek package org.opengrok.indexer.configuration; 2481511796SAdam Hornacek 2581511796SAdam Hornacek import io.micrometer.statsd.StatsdFlavor; 2681511796SAdam Hornacek import org.opengrok.indexer.authorization.AuthControlFlag; 2781511796SAdam Hornacek import org.opengrok.indexer.authorization.AuthorizationEntity; 2881511796SAdam Hornacek import org.opengrok.indexer.authorization.AuthorizationPlugin; 2981511796SAdam Hornacek import org.opengrok.indexer.authorization.AuthorizationStack; 3081511796SAdam Hornacek import org.opengrok.indexer.authorization.IAuthorizationPlugin; 3181511796SAdam Hornacek import org.opengrok.indexer.configuration.Configuration.RemoteSCM; 3281511796SAdam Hornacek import org.opengrok.indexer.history.RepositoryInfo; 3381511796SAdam Hornacek 3481511796SAdam Hornacek import java.beans.XMLDecoder; 3581511796SAdam Hornacek import java.util.ArrayList; 3681511796SAdam Hornacek import java.util.Collections; 3781511796SAdam Hornacek import java.util.HashMap; 38*a2fc1abbSAdam Hornacek import java.util.HashSet; 3981511796SAdam Hornacek import java.util.Set; 4081511796SAdam Hornacek import java.util.TreeSet; 4181511796SAdam Hornacek import java.util.stream.Collectors; 4281511796SAdam Hornacek 4381511796SAdam Hornacek /** 4481511796SAdam Hornacek * Temporary hack to prevent {@link XMLDecoder} to deserialize other than allowed classes. This tries to prevent 4581511796SAdam Hornacek * calling of methods on {@link ProcessBuilder} or {@link Runtime} (or similar) which could be used for code execution. 4681511796SAdam Hornacek */ 4781511796SAdam Hornacek public class ConfigurationClassLoader extends ClassLoader { 4881511796SAdam Hornacek 4981511796SAdam Hornacek private static final Set<String> allowedClasses = Set.of( 5081511796SAdam Hornacek ArrayList.class, 5181511796SAdam Hornacek AuthControlFlag.class, 5281511796SAdam Hornacek AuthorizationEntity.class, 5381511796SAdam Hornacek AuthorizationPlugin.class, 5481511796SAdam Hornacek AuthorizationStack.class, 5581511796SAdam Hornacek Collections.class, 5681511796SAdam Hornacek Configuration.class, 57*a2fc1abbSAdam Hornacek Enum.class, 5881511796SAdam Hornacek Filter.class, 5981511796SAdam Hornacek Group.class, 6081511796SAdam Hornacek HashMap.class, 61*a2fc1abbSAdam Hornacek HashSet.class, 6281511796SAdam Hornacek IAuthorizationPlugin.class, 6381511796SAdam Hornacek IgnoredNames.class, 6481511796SAdam Hornacek LuceneLockName.class, 6581511796SAdam Hornacek Project.class, 6681511796SAdam Hornacek RemoteSCM.class, 6781511796SAdam Hornacek RepositoryInfo.class, 68*a2fc1abbSAdam Hornacek Set.class, 6981511796SAdam Hornacek StatsdConfig.class, 7081511796SAdam Hornacek StatsdFlavor.class, 7181511796SAdam Hornacek String.class, 7281511796SAdam Hornacek SuggesterConfig.class, 7381511796SAdam Hornacek TreeSet.class, 7481511796SAdam Hornacek XMLDecoder.class 7581511796SAdam Hornacek ).stream().map(Class::getName).collect(Collectors.toSet()); 7681511796SAdam Hornacek 7781511796SAdam Hornacek @Override loadClass(final String name)7881511796SAdam Hornacek public Class<?> loadClass(final String name) throws ClassNotFoundException { 7981511796SAdam Hornacek if (!allowedClasses.contains(name)) { 8081511796SAdam Hornacek throw new IllegalAccessError(name + " is not allowed to be used in configuration"); 8181511796SAdam Hornacek } 8281511796SAdam Hornacek 8381511796SAdam Hornacek return getClass().getClassLoader().loadClass(name); 8481511796SAdam Hornacek } 8581511796SAdam Hornacek } 86