This is an automated email from the ASF dual-hosted git repository.
gerlowskija pushed a commit to branch branch_10_0
in repository https://gitbox.apache.org/repos/asf/solr.git
The following commit(s) were added to refs/heads/branch_10_0 by this push:
new 25e1b262877 SOLR-18014: Improve filestore "getFrom" validation (#3925)
25e1b262877 is described below
commit 25e1b262877fb6794d7696624a1ab499addd3dc6
Author: Jason Gerlowski <[email protected]>
AuthorDate: Wed Feb 11 08:04:26 2026 -0500
SOLR-18014: Improve filestore "getFrom" validation (#3925)
---
.../SOLR-18014-filestore-getFrom-improvements.yml | 9 +++++++++
.../solr/client/api/endpoint/ClusterFileStoreApis.java | 4 +++-
solr/core/src/java/org/apache/solr/cloud/ZkController.java | 3 +++
.../java/org/apache/solr/filestore/ClusterFileStore.java | 14 ++++++++++++++
.../org/apache/solr/filestore/TestDistribFileStore.java | 13 +++++++++++++
5 files changed, 42 insertions(+), 1 deletion(-)
diff --git a/changelog/unreleased/SOLR-18014-filestore-getFrom-improvements.yml
b/changelog/unreleased/SOLR-18014-filestore-getFrom-improvements.yml
new file mode 100644
index 00000000000..da93aa07b59
--- /dev/null
+++ b/changelog/unreleased/SOLR-18014-filestore-getFrom-improvements.yml
@@ -0,0 +1,9 @@
+# See https://github.com/apache/solr/blob/main/dev-docs/changelog.adoc
+title: Ensure File Store API "getFrom" param rejects values not in liveNodes
+type: security # added, changed, fixed, deprecated, removed,
dependency_update, security, other
+authors:
+ - name: Jason Gerlowski
+ - name: monkeontheroof
+links:
+ - name: SOLR-18014
+ url: https://issues.apache.org/jira/browse/SOLR-18014
diff --git
a/solr/api/src/java/org/apache/solr/client/api/endpoint/ClusterFileStoreApis.java
b/solr/api/src/java/org/apache/solr/client/api/endpoint/ClusterFileStoreApis.java
index 2445b17e7aa..e8dafdd4498 100644
---
a/solr/api/src/java/org/apache/solr/client/api/endpoint/ClusterFileStoreApis.java
+++
b/solr/api/src/java/org/apache/solr/client/api/endpoint/ClusterFileStoreApis.java
@@ -107,7 +107,9 @@ public interface ClusterFileStoreApis {
@Parameter(description = "Path to a file or directory within the
filestore")
@PathParam("path")
String path,
- @Parameter(description = "An optional Solr node name to fetch the file
from")
+ @Parameter(
+ description =
+ "An optional Solr node name to fetch the file from,
typically in the form \"host:port_solr\".")
@QueryParam("getFrom")
String getFrom);
diff --git a/solr/core/src/java/org/apache/solr/cloud/ZkController.java
b/solr/core/src/java/org/apache/solr/cloud/ZkController.java
index 653cccb9a6e..06bfdf24df8 100644
--- a/solr/core/src/java/org/apache/solr/cloud/ZkController.java
+++ b/solr/core/src/java/org/apache/solr/cloud/ZkController.java
@@ -1297,6 +1297,9 @@ public class ZkController implements Closeable {
});
}
+ /**
+ * @return the "live node" name of this Solr process, in the form
"${host}:${port}_solr"
+ */
public String getNodeName() {
return nodeName;
}
diff --git a/solr/core/src/java/org/apache/solr/filestore/ClusterFileStore.java
b/solr/core/src/java/org/apache/solr/filestore/ClusterFileStore.java
index 9eb61fd5822..c3b76dca4bb 100644
--- a/solr/core/src/java/org/apache/solr/filestore/ClusterFileStore.java
+++ b/solr/core/src/java/org/apache/solr/filestore/ClusterFileStore.java
@@ -18,6 +18,7 @@
package org.apache.solr.filestore;
import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.apache.solr.common.SolrException.ErrorCode.BAD_REQUEST;
import static org.apache.solr.handler.admin.api.ReplicationAPIBase.FILE_STREAM;
import static org.apache.solr.response.RawResponseWriter.CONTENT;
@@ -320,6 +321,19 @@ public class ClusterFileStore extends JerseyResource
implements ClusterFileStore
if (path == null) {
path = "";
}
+
+ // Ensure 'getFrom' points to a node in this cluster
+ final var zkStateReader =
coreContainer.getZkController().getZkStateReader();
+ if (StrUtils.isNotBlank(getFrom)
+ && !getFrom.equals("*")
+ && !zkStateReader.isNodeLive(getFrom)) {
+ throw new SolrException(
+ BAD_REQUEST,
+ "File store cannot fetch from source node ["
+ + getFrom
+ + "] as it does not appear in live-nodes");
+ }
+
pullFileFromNode(coreContainer, fileStore, path, getFrom);
return response;
}
diff --git
a/solr/core/src/test/org/apache/solr/filestore/TestDistribFileStore.java
b/solr/core/src/test/org/apache/solr/filestore/TestDistribFileStore.java
index a4de2935534..26679369d6e 100644
--- a/solr/core/src/test/org/apache/solr/filestore/TestDistribFileStore.java
+++ b/solr/core/src/test/org/apache/solr/filestore/TestDistribFileStore.java
@@ -175,6 +175,19 @@ public class TestDistribFileStore extends
SolrCloudTestCase {
String url = baseUrl +
"/cluster/filestore/metadata/package/mypkg/v1.0?wt=javabin";
assertResponseValues(10, new Fetcher(url, jettySolrRunner), expected);
}
+
+ // Ensure that invalid 'getFrom' parameter causes failures
+ for (JettySolrRunner jettySolrRunner : cluster.getJettySolrRunners()) {
+ final var fetchReq = new
FileStoreApi.FetchFile("/package/mypkg/v1.0/runtimelibs.jar2");
+ fetchReq.setGetFrom("someFakeSolrNode:8983_solr");
+ try (final var solrClient = jettySolrRunner.newClient()) {
+ final var asdf = fetchReq.process(solrClient);
+ assertEquals(400, asdf.responseHeader.status);
+ assertThat(asdf.error.msg, containsString("File store cannot fetch
from source node"));
+ assertThat(asdf.error.msg, containsString("does not appear in
live-nodes"));
+ }
+ }
+
// Delete Jars
DistribFileStore.deleteZKFileEntry(
cluster.getZkClient(), "/package/mypkg/v1.0/runtimelibs.jar");