Apache Solr: Solr Schema Designer blindly "trusts" all configsets, possibly leading to RCE by unauthenticated users
Description
Incorrect Permission Assignment for Critical Resource, Improper Control of Dynamically-Managed Code Resources vulnerability in Apache Solr.
This issue affects Apache Solr: from 8.10.0 through 8.11.2, from 9.0.0 before 9.3.0.
The Schema Designer was introduced to allow users to more easily configure and test new Schemas and configSets. However, when the feature was created, the "trust" (authentication) of these configSets was not considered. External library loading is only available to configSets that are "trusted" (created by authenticated users), thus non-authenticated users are unable to perform Remote Code Execution. Since the Schema Designer loaded configSets without taking their "trust" into account, configSets that were created by unauthenticated users were allowed to load external libraries when used in the Schema Designer.
Users are recommended to upgrade to version 9.3.0, which fixes the issue.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
In Apache Solr, the Schema Designer fails to check configSet trust, allowing unauthenticated users to load external libraries and achieve remote code execution.
Root
Cause CVE-2023-50292 is an improper permission assignment and dynamic code resource vulnerability in Apache Solr's Schema Designer. The issue affects Solr versions from 8.10.0 through 8.11.2 and 9.0.0 before 9.3.0 [2]. The Schema Designer was introduced to simplify schema and configSet configuration, but it did not check whether a configSet was "trusted" (i.e., created by an authenticated user) before loading it. This oversight allowed configSets created by unauthenticated users to be used in the Schema Designer [1][2].
Exploitation
External library loading is normally restricted to trusted configSets, which are only created by authenticated users; this prevents unauthenticated Remote Code Execution (RCE) [2]. Because the Schema Designer bypassed the trust check, an unauthenticated attacker could submit a malicious configSet that includes an external library reference. When the Schema Designer loads that configSet, Solr loads the external library, enabling code execution [4]. No additional authentication is required, as the Schema Designer is accessible to unauthenticated users by default.
Impact
Successful exploitation allows an unauthenticated attacker to achieve RCE on the Solr server, compromising the confidentiality, integrity, and availability of the system [2].
Mitigation
Users are strongly recommended to upgrade to Solr version 9.3.0, which fixes the issue by properly managing configSet trust in the Schema Designer [1][2][3]. The commit d07751c updates the ZkConfigSetService to check trust before loading configSets in the designer [3]. No workaround is provided for earlier versions; upgrading is the only fully effective measure.
AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.apache.solr:solr-coreMaven | >= 9.0.0, < 9.3.0 | 9.3.0 |
org.apache.solr:solr-coreMaven | >= 8.10.0, < 8.11.3 | 8.11.3 |
Affected products
3- osv-coords2 versions
>= 6.0.0, < 8.11.3+ 1 more
- (no CPE)range: >= 6.0.0, < 8.11.3
- (no CPE)range: >= 9.0.0, < 9.3.0
- Apache Software Foundation/Apache Solrv5Range: 8.10.0
Patches
26e9ed203b309SOLR-16777: Schema Designer now correctly manages trust of the ConfigSets it is managing
6 files changed · +87 −21
solr/CHANGES.txt+2 −0 modified@@ -37,6 +37,8 @@ Bug Fixes * SOLR-16452: Do not update PRS states if local version is newer (Hitesh Khamesra via noble) +* SOLR-16777: Schema Designer now correctly manages trust of the ConfigSets it is managing. (Ishan Chattopadhyaya, Skay, Houston Putman) + Optimizations --------------------- * SOLR-16555: SolrIndexSearcher - FilterCache intersections/andNot should not clone bitsets repeatedly (Kevin Risden, David Smiley)
solr/core/src/java/org/apache/solr/handler/admin/ConfigSetsHandler.java+29 −2 modified@@ -16,6 +16,7 @@ */ package org.apache.solr.handler.admin; +import java.io.IOException; import java.io.InputStream; import java.lang.invoke.MethodHandles; import java.nio.charset.StandardCharsets; @@ -311,7 +312,7 @@ private void ensureOverwritingUntrustedConfigSet(SolrZkClient zkClient, String c } } - private static boolean isCurrentlyTrusted(SolrZkClient zkClient, String configSetZkPath) { + public static boolean isCurrentlyTrusted(SolrZkClient zkClient, String configSetZkPath) { byte[] configSetNodeContent; try { configSetNodeContent = zkClient.getData(configSetZkPath, null, null, true); @@ -329,7 +330,33 @@ private static boolean isCurrentlyTrusted(SolrZkClient zkClient, String configSe return (boolean) contentMap.getOrDefault("trusted", true); } - static boolean isTrusted(SolrQueryRequest req, AuthenticationPlugin authPlugin) { + public void setConfigMetadata(String configName, Map<String, Object> data) throws IOException { + try { + coreContainer.getZkController().getZkClient().makePath( + ZkConfigManager.CONFIGS_ZKNODE + "/" + configName, + Utils.toJSON(data), + CreateMode.PERSISTENT, + null, + false, + true); + } catch (KeeperException | InterruptedException e) { + throw new IOException("Error setting config metadata", SolrZkClient.checkInterrupted(e)); + } + } + + public void removeConfigSetTrust(String configSetName) { + try { + Map<String, Object> metadata = Collections.singletonMap("trusted", false); + setConfigMetadata(configSetName, metadata); + } catch (IOException e) { + throw new SolrException( + SolrException.ErrorCode.SERVER_ERROR, + "Could not remove trusted flag for configSet " + configSetName + ": " + e.getMessage(), + e); + } + } + + public static boolean isTrusted(SolrQueryRequest req, AuthenticationPlugin authPlugin) { if (authPlugin != null && req.getUserPrincipal() != null) { log.debug("Trusted configset request"); return true;
solr/core/src/java/org/apache/solr/handler/designer/SchemaDesignerAPI.java+9 −2 modified@@ -65,6 +65,7 @@ import org.apache.solr.core.CoreContainer; import org.apache.solr.core.SolrConfig; import org.apache.solr.core.SolrResourceLoader; +import org.apache.solr.handler.admin.ConfigSetsHandler; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.RawResponseWriter; import org.apache.solr.response.SolrQueryResponse; @@ -112,8 +113,8 @@ public SchemaDesignerAPI(CoreContainer coreContainer) { this.coreContainer = coreContainer; this.schemaSuggester = schemaSuggester; this.sampleDocLoader = sampleDocLoader; - this.settingsDAO = new SchemaDesignerSettingsDAO(coreContainer); this.configSetHelper = new SchemaDesignerConfigSetHelper(this.coreContainer, this.schemaSuggester); + this.settingsDAO = new SchemaDesignerSettingsDAO(coreContainer, configSetHelper); } public static SchemaSuggester newSchemaSuggester(CoreContainer coreContainer) { @@ -233,11 +234,12 @@ public void updateFileContents(SolrQueryRequest req, SolrQueryResponse rsp) thro byte[] data = DefaultSampleDocumentsLoader.streamAsBytes(extractSingleContentStream(req, true).getStream()); Exception updateFileError = null; + boolean requestIsTrusted = ConfigSetsHandler.isTrusted(req, coreContainer.getAuthenticationPlugin()); if (SOLR_CONFIG_XML.equals(file)) { // verify the updated solrconfig.xml is valid before saving to ZK (to avoid things blowing up later) try { InMemoryResourceLoader loader = new InMemoryResourceLoader(coreContainer, mutableId, SOLR_CONFIG_XML, data); - SolrConfig.readFromResourceLoader(loader, SOLR_CONFIG_XML, true, null); + SolrConfig.readFromResourceLoader(loader, SOLR_CONFIG_XML, requestIsTrusted, null); } catch (Exception exc) { updateFileError = exc; } @@ -260,6 +262,11 @@ public void updateFileContents(SolrQueryRequest req, SolrQueryResponse rsp) thro } catch (KeeperException | InterruptedException e) { throw new IOException("Failed to save data in ZK at path: " + zkPath, SolrZkClient.checkInterrupted(e)); } + // If the request is untrusted, and the configSet is trusted, remove the trusted flag on the + // configSet. + if (ConfigSetsHandler.isCurrentlyTrusted(zkClient, ZkConfigManager.CONFIGS_ZKNODE + "/" + mutableId) && !requestIsTrusted) { + coreContainer.getConfigSetsHandler().removeConfigSetTrust(mutableId); + } configSetHelper.reloadTempCollection(mutableId, false);
solr/core/src/java/org/apache/solr/handler/designer/SchemaDesignerConfigSetHelper.java+33 −4 modified@@ -610,10 +610,9 @@ ManagedIndexSchema deleteNestedDocsFieldsIfNeeded(ManagedIndexSchema schema, boo } SolrConfig loadSolrConfig(String configSet) { - SolrResourceLoader resourceLoader = cc.getResourceLoader(); - ZkSolrResourceLoader zkLoader = - new ZkSolrResourceLoader(resourceLoader.getInstancePath(), configSet, resourceLoader.getClassLoader(), new Properties(), cc.getZkController()); - return SolrConfig.readFromResourceLoader(zkLoader, SOLR_CONFIG_XML, false, null); + ZkSolrResourceLoader zkLoader = zkLoaderForConfigSet(configSet); + boolean trusted = isConfigSetTrusted(configSet); + return SolrConfig.readFromResourceLoader(zkLoader, SOLR_CONFIG_XML, trusted, null); } ManagedIndexSchema loadLatestSchema(String configSet) { @@ -1075,4 +1074,34 @@ void deleteConfig(String configSet) throws IOException { void copyConfig(String from, String to) throws IOException { configManager.copyConfigDir(from, to); } + + public boolean isConfigSetTrusted(String configSetName) { + try { + return cc.getConfigSetsHandler().isCurrentlyTrusted(cc.getZkController().getZkClient(), ZkConfigManager.CONFIGS_ZKNODE + "/" + configSetName); + } catch (Exception e) { + throw new SolrException( + SolrException.ErrorCode.SERVER_ERROR, + "Could not load conf " + configSetName + ": " + e.getMessage(), + e); + } + } + + public void removeConfigSetTrust(String configSetName) { + try { + Map<String, Object> metadata = Collections.singletonMap("trusted", false); + cc.getConfigSetsHandler().setConfigMetadata(configSetName, metadata); + } catch (IOException e) { + throw new SolrException( + SolrException.ErrorCode.SERVER_ERROR, + "Could not remove trusted flag for configSet " + configSetName + ": " + e.getMessage(), + e); + } + } + + protected ZkSolrResourceLoader zkLoaderForConfigSet(final String configSet) { + SolrResourceLoader resourceLoader = cc.getResourceLoader(); + ZkSolrResourceLoader zkLoader = + new ZkSolrResourceLoader(resourceLoader.getInstancePath(), configSet, resourceLoader.getClassLoader(), new Properties(), cc.getZkController()); + return zkLoader; + } }
solr/core/src/java/org/apache/solr/handler/designer/SchemaDesignerSettingsDAO.java+12 −12 modified@@ -24,7 +24,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Properties; import org.apache.solr.cloud.ZkController; import org.apache.solr.cloud.ZkSolrResourceLoader; @@ -33,7 +32,6 @@ import org.apache.solr.core.CoreContainer; import org.apache.solr.core.PluginInfo; import org.apache.solr.core.SolrConfig; -import org.apache.solr.core.SolrResourceLoader; import org.apache.solr.update.processor.UpdateRequestProcessorChain; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.data.Stat; @@ -49,14 +47,15 @@ class SchemaDesignerSettingsDAO implements SchemaDesignerConstants { private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); private final CoreContainer cc; + private final SchemaDesignerConfigSetHelper configSetHelper; - SchemaDesignerSettingsDAO(CoreContainer cc) { + SchemaDesignerSettingsDAO(CoreContainer cc, SchemaDesignerConfigSetHelper configSetHelper) { this.cc = cc; + this.configSetHelper = configSetHelper; } SchemaDesignerSettings getSettings(String configSet) { - SolrConfig solrConfig = - SolrConfig.readFromResourceLoader(zkLoaderForConfigSet(configSet), SOLR_CONFIG_XML, true, null); + SolrConfig solrConfig = configSetHelper.loadSolrConfig(configSet); return getSettings(solrConfig); } @@ -97,8 +96,14 @@ boolean persistIfChanged(String configSet, SchemaDesignerSettings settings) thro } if (changed) { - ZkController.persistConfigResourceToZooKeeper(zkLoaderForConfigSet(configSet), overlay.getZnodeVersion(), - ConfigOverlay.RESOURCE_NAME, overlay.toByteArray(), true); + try (ZkSolrResourceLoader resourceLoader = configSetHelper.zkLoaderForConfigSet(configSet)) { + ZkController.persistConfigResourceToZooKeeper( + resourceLoader, + overlay.getZnodeVersion(), + ConfigOverlay.RESOURCE_NAME, + overlay.toByteArray(), + true); + } } return changed; @@ -160,9 +165,4 @@ private boolean hasFieldGuessingURPChain(final SolrConfig solrConfig) { } return hasPlugin; } - - private ZkSolrResourceLoader zkLoaderForConfigSet(final String configSet) { - SolrResourceLoader loader = cc.getResourceLoader(); - return new ZkSolrResourceLoader(loader.getInstancePath(), configSet, loader.getClassLoader(), new Properties(), cc.getZkController()); - } }
solr/core/src/test/org/apache/solr/handler/designer/TestSchemaDesignerSettingsDAO.java+2 −1 modified@@ -69,7 +69,8 @@ public void testDAO() throws Exception { CollectionAdminRequest.createCollection(collection, configSet, 1, 1).process(cluster.getSolrClient()); CollectionsHandler.waitForActiveCollection(collection, cc, rsp); - SchemaDesignerSettingsDAO dao = new SchemaDesignerSettingsDAO(cc); + SchemaDesignerConfigSetHelper csh = new SchemaDesignerConfigSetHelper(cc, null); + SchemaDesignerSettingsDAO dao = new SchemaDesignerSettingsDAO(cc, csh); SchemaDesignerSettings settings = dao.getSettings(configSet); assertNotNull(settings);
d07751cfaa80SOLR-16777: Make SchemaDesigner use ConfigSet trust
12 files changed · +111 −54
solr/CHANGES.txt+1 −1 modified@@ -229,7 +229,7 @@ Bug Fixes * SOLR-13605: Fix setting client scoped socket and connect timeouts when using HttpSolrClient.Builder.withHttpClient() method. (Eric Pugh, Alex Deparvu) -* SOLR-16777: Fix for Schema Designer blindly trusting potentially malicious configsets (Ishan Chattopadhyaya, Skay) +* SOLR-16777: Schema Designer now correctly manages trust of the ConfigSets it is managing. (Ishan Chattopadhyaya, Skay, Houston Putman) * SOLR-16771: Fixed behavior and handling of 'unset' logging levels in /admin/info/logging API and related Admin UI (hossman)
solr/core/src/java/org/apache/solr/cloud/ZkConfigSetService.java+2 −2 modified@@ -101,9 +101,9 @@ public SolrResourceLoader createCoreResourceLoader(CoreDescriptor cd) { } @Override - protected NamedList<Object> loadConfigSetFlags(CoreDescriptor cd, SolrResourceLoader loader) - throws IOException { + protected NamedList<Object> loadConfigSetFlags(SolrResourceLoader loader) throws IOException { try { + // ConfigSet flags are loaded from the metadata of the ZK node of the configset. return ConfigSetProperties.readFromResourceLoader(loader, "."); } catch (Exception ex) { log.debug("No configSet flags", ex);
solr/core/src/java/org/apache/solr/core/ConfigSetService.java+28 −14 modified@@ -29,7 +29,6 @@ import java.util.regex.Pattern; import org.apache.solr.cloud.ZkConfigSetService; import org.apache.solr.cloud.ZkController; -import org.apache.solr.cloud.ZkSolrResourceLoader; import org.apache.solr.common.ConfigNode; import org.apache.solr.common.SolrException; import org.apache.solr.common.util.NamedList; @@ -220,6 +219,31 @@ public static void bootstrapConf(CoreContainer cc) throws IOException { } } + /** + * Return whether the given configSet is trusted. + * + * @param name name of the configSet + */ + public boolean isConfigSetTrusted(String name) throws IOException { + Map<String, Object> contentMap = getConfigMetadata(name); + return (boolean) contentMap.getOrDefault("trusted", true); + } + + /** + * Return whether the configSet used for the given resourceLoader is trusted. + * + * @param coreLoader resourceLoader for a core + */ + public boolean isConfigSetTrusted(SolrResourceLoader coreLoader) throws IOException { + // ConfigSet flags are loaded from the metadata of the ZK node of the configset. (For the + // ZKConfigSetService) + NamedList<?> flags = loadConfigSetFlags(coreLoader); + + // Trust if there is no trusted flag (i.e. the ConfigSetApi was not used for this configSet) + // or if the trusted flag is set to "true". + return (flags == null || flags.get("trusted") == null || flags.getBooleanArg("trusted")); + } + /** * Load the ConfigSet for a core * @@ -233,16 +257,7 @@ public final ConfigSet loadConfigSet(CoreDescriptor dcore) { try { // ConfigSet properties are loaded from ConfigSetProperties.DEFAULT_FILENAME file. NamedList<?> properties = loadConfigSetProperties(dcore, coreLoader); - // ConfigSet flags are loaded from the metadata of the ZK node of the configset. - NamedList<?> flags = loadConfigSetFlags(dcore, coreLoader); - - boolean trusted = - (coreLoader instanceof ZkSolrResourceLoader - && flags != null - && flags.get("trusted") != null - && !flags.getBooleanArg("trusted")) - ? false - : true; + boolean trusted = isConfigSetTrusted(coreLoader); SolrConfig solrConfig = createSolrConfig(dcore, coreLoader, trusted); return new ConfigSet( @@ -290,7 +305,7 @@ public ConfigSetService(SolrResourceLoader loader, boolean shareSchema) { * @return a SolrConfig object */ protected SolrConfig createSolrConfig( - CoreDescriptor cd, SolrResourceLoader loader, boolean isTrusted) { + CoreDescriptor cd, SolrResourceLoader loader, boolean isTrusted) throws IOException { return SolrConfig.readFromResourceLoader( loader, cd.getConfigName(), isTrusted, cd.getSubstitutableProperties()); } @@ -364,8 +379,7 @@ protected NamedList<Object> loadConfigSetProperties(CoreDescriptor cd, SolrResou /** Return the ConfigSet flags or null if none. */ // TODO should fold into configSetProps -- SOLR-14059 - protected NamedList<Object> loadConfigSetFlags(CoreDescriptor cd, SolrResourceLoader loader) - throws IOException { + protected NamedList<Object> loadConfigSetFlags(SolrResourceLoader loader) throws IOException { return null; }
solr/core/src/java/org/apache/solr/handler/configsets/ConfigSetAPIBase.java+2 −7 modified@@ -109,7 +109,7 @@ protected InputStream ensureNonEmptyInputStream(SolrQueryRequest req) throws IOE return contentStreamsIterator.next().getStream(); } - protected boolean isTrusted(Principal userPrincipal, AuthenticationPlugin authPlugin) { + public static boolean isTrusted(Principal userPrincipal, AuthenticationPlugin authPlugin) { if (authPlugin != null && userPrincipal != null) { log.debug("Trusted configset request"); return true; @@ -118,11 +118,6 @@ protected boolean isTrusted(Principal userPrincipal, AuthenticationPlugin authPl return false; } - protected boolean isCurrentlyTrusted(String configName) throws IOException { - Map<String, Object> contentMap = configSetService.getConfigMetadata(configName); - return (boolean) contentMap.getOrDefault("trusted", true); - } - protected void createBaseNode( ConfigSetService configSetService, boolean overwritesExisting, @@ -146,7 +141,7 @@ protected void createBaseNode( * Fail if an untrusted request tries to update a trusted ConfigSet */ private void ensureOverwritingUntrustedConfigSet(String configName) throws IOException { - boolean isCurrentlyTrusted = isCurrentlyTrusted(configName); + boolean isCurrentlyTrusted = configSetService.isConfigSetTrusted(configName); if (isCurrentlyTrusted) { throw new SolrException( SolrException.ErrorCode.BAD_REQUEST,
solr/core/src/java/org/apache/solr/handler/configsets/CreateConfigSetAPI.java+1 −1 modified@@ -64,7 +64,7 @@ public void create(PayloadObj<CreateConfigPayload> obj) throws Exception { if (!DISABLE_CREATE_AUTH_CHECKS && !isTrusted(obj.getRequest().getUserPrincipal(), coreContainer.getAuthenticationPlugin()) - && isCurrentlyTrusted(createConfigPayload.baseConfigSet)) { + && configSetService.isConfigSetTrusted(createConfigPayload.baseConfigSet)) { throw new SolrException( SolrException.ErrorCode.UNAUTHORIZED, "Can't create a configset with an unauthenticated request from a trusted "
solr/core/src/java/org/apache/solr/handler/configsets/UploadConfigSetAPI.java+4 −1 modified@@ -106,7 +106,10 @@ public void uploadConfigSet(SolrQueryRequest req, SolrQueryResponse rsp) throws // If the request is doing a full trusted overwrite of an untrusted configSet (overwrite=true, // cleanup=true), then trust the configSet. - if (cleanup && requestIsTrusted && overwritesExisting && !isCurrentlyTrusted(configSetName)) { + if (cleanup + && requestIsTrusted + && overwritesExisting + && !configSetService.isConfigSetTrusted(configSetName)) { Map<String, Object> metadata = Collections.singletonMap("trusted", true); configSetService.setConfigMetadata(configSetName, metadata); }
solr/core/src/java/org/apache/solr/handler/designer/SchemaDesignerAPI.java+10 −2 modified@@ -72,6 +72,7 @@ import org.apache.solr.core.CoreContainer; import org.apache.solr.core.SolrConfig; import org.apache.solr.core.SolrResourceLoader; +import org.apache.solr.handler.configsets.ConfigSetAPIBase; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.RawResponseWriter; import org.apache.solr.response.SolrQueryResponse; @@ -113,9 +114,9 @@ public SchemaDesignerAPI(CoreContainer coreContainer) { this.coreContainer = coreContainer; this.schemaSuggester = schemaSuggester; this.sampleDocLoader = sampleDocLoader; - this.settingsDAO = new SchemaDesignerSettingsDAO(coreContainer); this.configSetHelper = new SchemaDesignerConfigSetHelper(this.coreContainer, this.schemaSuggester); + this.settingsDAO = new SchemaDesignerSettingsDAO(coreContainer, configSetHelper); } public static SchemaSuggester newSchemaSuggester(CoreContainer coreContainer) { @@ -244,13 +245,15 @@ public void updateFileContents(SolrQueryRequest req, SolrQueryResponse rsp) DefaultSampleDocumentsLoader.streamAsBytes( extractSingleContentStream(req, true).getStream()); Exception updateFileError = null; + boolean requestIsTrusted = + ConfigSetAPIBase.isTrusted(req.getUserPrincipal(), coreContainer.getAuthenticationPlugin()); if (SOLR_CONFIG_XML.equals(file)) { // verify the updated solrconfig.xml is valid before saving to ZK (to avoid things blowing up // later) try { InMemoryResourceLoader loader = new InMemoryResourceLoader(coreContainer, mutableId, SOLR_CONFIG_XML, data); - SolrConfig.readFromResourceLoader(loader, SOLR_CONFIG_XML, true, null); + SolrConfig.readFromResourceLoader(loader, SOLR_CONFIG_XML, requestIsTrusted, null); } catch (Exception exc) { updateFileError = exc; } @@ -275,6 +278,11 @@ public void updateFileContents(SolrQueryRequest req, SolrQueryResponse rsp) throw new IOException( "Failed to save data in ZK at path: " + zkPath, SolrZkClient.checkInterrupted(e)); } + // If the request is untrusted, and the configSet is trusted, remove the trusted flag on the + // configSet. + if (configSetHelper.isConfigSetTrusted(mutableId) && !requestIsTrusted) { + configSetHelper.removeConfigSetTrust(mutableId); + } configSetHelper.reloadTempCollection(mutableId, false);
solr/core/src/java/org/apache/solr/handler/designer/SchemaDesignerConfigSetHelper.java+33 −8 modified@@ -685,14 +685,10 @@ ManagedIndexSchema deleteNestedDocsFieldsIfNeeded(ManagedIndexSchema schema, boo } SolrConfig loadSolrConfig(String configSet) { - SolrResourceLoader resourceLoader = cc.getResourceLoader(); - ZkSolrResourceLoader zkLoader = - new ZkSolrResourceLoader( - resourceLoader.getInstancePath(), - configSet, - resourceLoader.getClassLoader(), - cc.getZkController()); - return SolrConfig.readFromResourceLoader(zkLoader, SOLR_CONFIG_XML, false, null); + ZkSolrResourceLoader zkLoader = zkLoaderForConfigSet(configSet); + boolean trusted = isConfigSetTrusted(configSet); + + return SolrConfig.readFromResourceLoader(zkLoader, SOLR_CONFIG_XML, trusted, null); } ManagedIndexSchema loadLatestSchema(String configSet) { @@ -1221,4 +1217,33 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) } return baos.toByteArray(); } + + public boolean isConfigSetTrusted(String configSetName) { + try { + return cc.getConfigSetService().isConfigSetTrusted(configSetName); + } catch (IOException e) { + throw new SolrException( + SolrException.ErrorCode.SERVER_ERROR, + "Could not load conf " + configSetName + ": " + e.getMessage(), + e); + } + } + + public void removeConfigSetTrust(String configSetName) { + try { + Map<String, Object> metadata = Collections.singletonMap("trusted", false); + cc.getConfigSetService().setConfigMetadata(configSetName, metadata); + } catch (IOException e) { + throw new SolrException( + SolrException.ErrorCode.SERVER_ERROR, + "Could not remove trusted flag for configSet " + configSetName + ": " + e.getMessage(), + e); + } + } + + protected ZkSolrResourceLoader zkLoaderForConfigSet(final String configSet) { + SolrResourceLoader loader = cc.getResourceLoader(); + return new ZkSolrResourceLoader( + loader.getInstancePath(), configSet, loader.getClassLoader(), cc.getZkController()); + } }
solr/core/src/java/org/apache/solr/handler/designer/SchemaDesignerSettingsDAO.java+12 −17 modified@@ -33,7 +33,6 @@ import org.apache.solr.core.CoreContainer; import org.apache.solr.core.PluginInfo; import org.apache.solr.core.SolrConfig; -import org.apache.solr.core.SolrResourceLoader; import org.apache.solr.update.processor.UpdateRequestProcessorChain; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.data.Stat; @@ -47,15 +46,15 @@ class SchemaDesignerSettingsDAO implements SchemaDesignerConstants { private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); private final CoreContainer cc; + private final SchemaDesignerConfigSetHelper configSetHelper; - SchemaDesignerSettingsDAO(CoreContainer cc) { + SchemaDesignerSettingsDAO(CoreContainer cc, SchemaDesignerConfigSetHelper configSetHelper) { this.cc = cc; + this.configSetHelper = configSetHelper; } SchemaDesignerSettings getSettings(String configSet) { - SolrConfig solrConfig = - SolrConfig.readFromResourceLoader( - zkLoaderForConfigSet(configSet), SOLR_CONFIG_XML, true, null); + SolrConfig solrConfig = configSetHelper.loadSolrConfig(configSet); return getSettings(solrConfig); } @@ -97,12 +96,14 @@ boolean persistIfChanged(String configSet, SchemaDesignerSettings settings) thro } if (changed) { - ZkController.persistConfigResourceToZooKeeper( - zkLoaderForConfigSet(configSet), - overlay.getVersion(), - ConfigOverlay.RESOURCE_NAME, - overlay.toByteArray(), - true); + try (ZkSolrResourceLoader resourceLoader = configSetHelper.zkLoaderForConfigSet(configSet)) { + ZkController.persistConfigResourceToZooKeeper( + resourceLoader, + overlay.getVersion(), + ConfigOverlay.RESOURCE_NAME, + overlay.toByteArray(), + true); + } } return changed; @@ -169,10 +170,4 @@ private boolean hasFieldGuessingURPChain(final SolrConfig solrConfig) { } return hasPlugin; } - - private ZkSolrResourceLoader zkLoaderForConfigSet(final String configSet) { - SolrResourceLoader loader = cc.getResourceLoader(); - return new ZkSolrResourceLoader( - loader.getInstancePath(), configSet, loader.getClassLoader(), cc.getZkController()); - } }
solr/core/src/test/org/apache/solr/handler/designer/TestSchemaDesignerSettingsDAO.java+2 −1 modified@@ -71,7 +71,8 @@ public void testDAO() throws Exception { .process(cluster.getSolrClient()); CollectionsHandler.waitForActiveCollection(collection, cc, rsp); - SchemaDesignerSettingsDAO dao = new SchemaDesignerSettingsDAO(cc); + SchemaDesignerConfigSetHelper csh = new SchemaDesignerConfigSetHelper(cc, null); + SchemaDesignerSettingsDAO dao = new SchemaDesignerSettingsDAO(cc, csh); SchemaDesignerSettings settings = dao.getSettings(configSet); assertNotNull(settings);
solr/solr-ref-guide/modules/indexing-guide/pages/schema-designer.adoc+15 −0 modified@@ -79,6 +79,21 @@ Previously uploaded sample documents are indexed in the temporary collection eve Click on the btn:[Edit Documents] button on the *Query Results* panel to load a JSON representation of indexed documents into the text area. ==== +=== Trusted Config Sets + +ConfigSet trust is necessary when loading extra libraries from the `solrconfig.xml` and using certain features of Solr. +Refer to the xref:configuration-guide:configsets-api.adoc#configsets-upload[ConfigSet API] section for more information on trusted configSets. + +Using the Schema Designer API has the same effect on the trust of a ConfigSet as using the xref:configuration-guide:configsets-api.adoc#configsets-upload[ConfigSet Upload API]. + +* If you are authenticated: +** If your source configSet **is** trusted, then the temporary configSets you are modifying will remain trusted. +** If your source configSet **is not** trusted, then the temporary configSet you are modifying will never be trusted. +* If you are unauthenticated: +** The temporary configSet created for you will **not** be trusted. + +When <<publish,publishing the temporary configSet>>, the trust of the temporary configSet is used to set the trust of the permanent configSet. + === Iteratively Post Sample Documents If you have sample documents spread across multiple files, you can POST them to the Schema Designer API and then load your schema in the Designer UI to design your schema.
solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-9.adoc+1 −0 modified@@ -91,6 +91,7 @@ The sysProp `-Dsolr.redaction.system.pattern` has been deprecated, use the above The `<hiddenSysProps>` solr.xml element under `<metrics>` has been deprecated. Instead, use the xref:configuration-guide:configuring-solr-xml.adoc#hiddenSysProps[<hiddenSysProps>] tag under `<solr>`, which accepts a comma-separated string. +* The xref:indexing-guide:schema-designer.adoc[] now utilizes the same trust model as the xref:configuration-guide:configsets-api.adoc#configsets-upload[ConfigSet Upload API]. === Official Docker Image * The customization of the Official Solr Dockerfile has been changed.
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
7- github.com/advisories/GHSA-4wxw-42wx-2wfxghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2023-50292ghsaADVISORY
- solr.apache.org/security.htmlghsavendor-advisoryWEB
- www.openwall.com/lists/oss-security/2024/02/09/3ghsaWEB
- github.com/apache/lucene-solr/commit/6e9ed203b30958396bdfd41760d426b386646865ghsaWEB
- github.com/apache/solr/commit/d07751cfaa8065bea8bd43f59e758e50d50c2419ghsaWEB
- issues.apache.org/jira/browse/SOLR-16777ghsaWEB
News mentions
0No linked articles in our index yet.