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");

Reply via email to