You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ja...@apache.org on 2017/01/29 21:31:23 UTC

lucene-solr:branch_5_5: SOLR-10031: Validation of filename params in ReplicationHandler

Repository: lucene-solr
Updated Branches:
  refs/heads/branch_5_5 ddb008d96 -> ae789c252


SOLR-10031: Validation of filename params in ReplicationHandler


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/ae789c25
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/ae789c25
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/ae789c25

Branch: refs/heads/branch_5_5
Commit: ae789c252687dc8a18bfdb677f2e6cd14570e4db
Parents: ddb008d
Author: Jan H�ydahl <ja...@apache.org>
Authored: Sat Jan 28 01:04:16 2017 +0100
Committer: Jan H�ydahl <ja...@apache.org>
Committed: Sat Jan 28 01:04:16 2017 +0100

----------------------------------------------------------------------
 solr/CHANGES.txt                                |  2 ++
 .../apache/solr/handler/ReplicationHandler.java | 24 +++++++++++++++++---
 .../solr/handler/TestReplicationHandler.java    | 16 +++++++++++++
 3 files changed, 39 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ae789c25/solr/CHANGES.txt
----------------------------------------------------------------------
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index f861137..f1ee0ca 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -26,6 +26,8 @@ Other Changes
 
 * SOLR-9819: Upgrade commons-fileupload to 1.3.2, fixing a potential vulnerability CVE-2016-3092 (Anshum Gupta)
 
+* SOLR-10031: Validation of filename params in ReplicationHandler (Hrishikesh Gadre, janhoy)
+
 ======================= 5.5.3 =======================
 
 Consult the LUCENE_CHANGES.txt file for additional, low level, changes in this release.

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ae789c25/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java b/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java
index 80188fe..8c1a29d 100644
--- a/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java
@@ -28,6 +28,8 @@ import java.nio.ByteBuffer;
 import java.nio.channels.FileChannel;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.NoSuchFileException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -42,7 +44,6 @@ import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
 import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.locks.ReentrantLock;
@@ -1328,8 +1329,9 @@ public class ReplicationHandler extends RequestHandlerBase implements SolrCoreAw
       params = solrParams;
       delPolicy = core.getDeletionPolicy();
 
-      fileName = params.get(FILE);
-      cfileName = params.get(CONF_FILE_SHORT);
+      fileName = validateFilenameOrError(params.get(FILE));
+      cfileName = validateFilenameOrError(params.get(CONF_FILE_SHORT));
+      
       sOffset = params.get(OFFSET);
       sLen = params.get(LEN);
       compress = params.get(COMPRESSION);
@@ -1343,6 +1345,22 @@ public class ReplicationHandler extends RequestHandlerBase implements SolrCoreAw
       rateLimiter = new RateLimiter.SimpleRateLimiter(maxWriteMBPerSec);
     }
 
+    // Throw exception on directory traversal attempts 
+    protected String validateFilenameOrError(String filename) {
+      if (filename != null) {
+        Path filePath = Paths.get(filename);
+        for (Path subpath : filePath) {
+          if ("..".equals(subpath.toString())) {
+            throw new SolrException(ErrorCode.FORBIDDEN, "File name cannot contain ..");
+          }
+        }
+        if (filePath.isAbsolute()) {
+          throw new SolrException(ErrorCode.FORBIDDEN, "File name must be relative");
+        }
+        return filename;
+      } else return null;
+    }
+
     protected void initWrite() throws IOException {
       if (sOffset != null) offset = Long.parseLong(sOffset);
       if (sLen != null) len = Integer.parseInt(sLen);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ae789c25/solr/core/src/test/org/apache/solr/handler/TestReplicationHandler.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/handler/TestReplicationHandler.java b/solr/core/src/test/org/apache/solr/handler/TestReplicationHandler.java
index b997ad4..2a07582 100644
--- a/solr/core/src/test/org/apache/solr/handler/TestReplicationHandler.java
+++ b/solr/core/src/test/org/apache/solr/handler/TestReplicationHandler.java
@@ -34,6 +34,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Date;
+import java.util.List;
 import java.util.Properties;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
@@ -1401,6 +1402,21 @@ public class TestReplicationHandler extends SolrTestCaseJ4 {
     assertTrue(timeTakenInSeconds - approximateTimeInSeconds > 0);
   }
 
+  @Test
+  public void doTestIllegalFilePaths() throws Exception {
+    // Loop through the file=, cf=, tlogFile= params and prove that it throws exception for path traversal attempts
+    List<String> illegalFilenames = Arrays.asList("/foo/bar", "../dir/traversal", "illegal\rfile\nname\t");
+    List<String> params = Arrays.asList(ReplicationHandler.FILE, ReplicationHandler.CONF_FILE_SHORT);
+    for (String param : params) {
+      for (String filename : illegalFilenames) {
+        try {
+          invokeReplicationCommand(masterJetty.getLocalPort(), "filecontent&" + param + "=" + filename);
+          fail("Should have thrown exception on illegal path for param " + param + " and file name " + filename);
+        } catch (Exception e) {}
+      }
+    }
+  }
+  
   private class AddExtraDocs implements Runnable {
 
     SolrClient masterClient;