This is an automated email from the ASF dual-hosted git repository.

ptupitsyn pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/master by this push:
     new 5c42c7a3039 IGNITE-25524 Fix GridLogCommandHandler path validation 
(#12136)
5c42c7a3039 is described below

commit 5c42c7a303937844179ad470edb35c1ad1cee6ab
Author: Pavel Tupitsyn <ptupit...@apache.org>
AuthorDate: Fri Jun 13 12:56:22 2025 +0300

    IGNITE-25524 Fix GridLogCommandHandler path validation (#12136)
---
 .../rest/handlers/log/GridLogCommandHandler.java   | 17 ++++---
 .../handlers/log/GridLogCommandHandlerTest.java    | 52 ++++++++++++++++++++--
 2 files changed, 60 insertions(+), 9 deletions(-)

diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/log/GridLogCommandHandler.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/log/GridLogCommandHandler.java
index aac1fa7e188..ecb733ea995 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/log/GridLogCommandHandler.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/log/GridLogCommandHandler.java
@@ -20,7 +20,7 @@ import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileReader;
 import java.io.IOException;
-import java.nio.file.InvalidPathException;
+import java.net.URI;
 import java.util.Collection;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.internal.GridKernalContext;
@@ -36,7 +36,7 @@ import org.apache.ignite.internal.util.typedef.internal.U;
 import static org.apache.ignite.internal.processors.rest.GridRestCommand.LOG;
 
 /**
- * Handler for {@link 
org.apache.ignite.internal.processors.rest.GridRestCommand#LOG} command.
+ * Handler for {@link GridRestCommand#LOG} command.
  */
 public class GridLogCommandHandler extends GridRestCommandHandlerAdapter {
     /**
@@ -120,7 +120,7 @@ public class GridLogCommandHandler extends 
GridRestCommandHandlerAdapter {
                         else
                             logFile = new File(req0.path());
                     }
-                    else if 
(req0.path().startsWith(ctx.config().getIgniteHome()))
+                    else if 
(resolveFilePath(req0.path()).startsWith(ctx.config().getIgniteHome()))
                         logFile = new File(req0.path());
                     else {
                         return new GridFinishedFuture<>(new 
GridRestResponse(GridRestResponse.STATUS_FAILED,
@@ -132,7 +132,7 @@ public class GridLogCommandHandler extends 
GridRestCommandHandlerAdapter {
                 else
                     logFile = new File(log.fileName());
             }
-            catch (InvalidPathException e) {
+            catch (Exception e) {
                 return new GridFinishedFuture<>(new 
GridRestResponse(GridRestResponse.STATUS_FAILED,
                     "Incorrect path to a log file [msg=" + e.getMessage() + 
']'));
             }
@@ -159,7 +159,7 @@ public class GridLogCommandHandler extends 
GridRestCommandHandlerAdapter {
      * @return Content that is read.
      * @throws IgniteCheckedException If failed.
      */
-    private String readLog(int from, int to, File logFile) throws 
IgniteCheckedException {
+    private static String readLog(int from, int to, File logFile) throws 
IgniteCheckedException {
         StringBuilder content = new StringBuilder();
 
         try (BufferedReader reader = new BufferedReader(new 
FileReader(logFile))) {
@@ -184,4 +184,11 @@ public class GridLogCommandHandler extends 
GridRestCommandHandlerAdapter {
 
         return content.toString();
     }
+
+    /** */
+    private static String resolveFilePath(String p) throws Exception {
+        p = new URI(p).normalize().getPath();
+
+        return new File(p).getCanonicalPath();
+    }
 }
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/rest/handlers/log/GridLogCommandHandlerTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/rest/handlers/log/GridLogCommandHandlerTest.java
index 4739051425a..5e9fc3d2cf5 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/rest/handlers/log/GridLogCommandHandlerTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/rest/handlers/log/GridLogCommandHandlerTest.java
@@ -16,7 +16,7 @@
  */
 package org.apache.ignite.internal.processors.rest.handlers.log;
 
-import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
@@ -38,7 +38,7 @@ import org.junit.Test;
  */
 public class GridLogCommandHandlerTest extends GridCommonAbstractTest {
     /** */
-    private String igniteHome = System.getProperty("user.dir");
+    private final String igniteHome = System.getProperty("user.dir");
 
     /** {@inheritDoc} */
     @Override protected void beforeTestsStarted() throws Exception {
@@ -53,11 +53,13 @@ public class GridLogCommandHandlerTest extends 
GridCommonAbstractTest {
         Files.createDirectories(dir);
 
         Path file = Paths.get(igniteHome + "/work/log/" + "ignite.log");
-        Files.write(file, lines, Charset.forName("UTF-8"));
+        Files.write(file, lines, StandardCharsets.UTF_8);
 
         file = Paths.get(igniteHome + "/work/log/" + "test.log");
-        Files.write(file, lines, Charset.forName("UTF-8"));
+        Files.write(file, lines, StandardCharsets.UTF_8);
 
+        file = Paths.get(igniteHome + "/../parent.txt");
+        Files.write(file, "Should not be 
read.".getBytes(StandardCharsets.UTF_8));
     }
 
     /** {@inheritDoc} */
@@ -65,6 +67,7 @@ public class GridLogCommandHandlerTest extends 
GridCommonAbstractTest {
         Files.delete(Paths.get(igniteHome + "/work/log/" + "test.log"));
         Files.delete(Paths.get(igniteHome + "/work/log/" + "ignite.log"));
         Files.delete(Paths.get(igniteHome + "/work/log/"));
+        Files.delete(Paths.get(igniteHome + "/../parent.txt"));
     }
 
     /**
@@ -198,6 +201,47 @@ public class GridLogCommandHandlerTest extends 
GridCommonAbstractTest {
         assertNull(resp.result().getResponse());
     }
 
+    /**
+     * @throws Exception If failed.
+     */
+    @Test
+    public void testHandleAsyncPathWithIgniteHomeAndContainsParentDirectory() 
throws Exception {
+        testHandleAsyncPathWithIgniteHomeAndContainsParentDirectory(igniteHome 
+ "/../parent.txt");
+
+        testHandleAsyncPathWithIgniteHomeAndContainsParentDirectory(igniteHome 
+ "/.%2e/parent.txt");
+        testHandleAsyncPathWithIgniteHomeAndContainsParentDirectory(igniteHome 
+ "/%2e./parent.txt");
+        testHandleAsyncPathWithIgniteHomeAndContainsParentDirectory(igniteHome 
+ "/%2e%2e/parent.txt");
+
+        testHandleAsyncPathWithIgniteHomeAndContainsParentDirectory(igniteHome 
+ "/.%252e/parent.txt");
+        testHandleAsyncPathWithIgniteHomeAndContainsParentDirectory(igniteHome 
+ "/%252e./parent.txt");
+        testHandleAsyncPathWithIgniteHomeAndContainsParentDirectory(igniteHome 
+ "/%252e%252e/parent.txt");
+
+        testHandleAsyncPathWithIgniteHomeAndContainsParentDirectory(igniteHome 
+ "/%2e%252e/parent.txt");
+
+        testHandleAsyncPathWithIgniteHomeAndContainsParentDirectory(igniteHome 
+ "/%00../parent.txt");
+        testHandleAsyncPathWithIgniteHomeAndContainsParentDirectory(igniteHome 
+ "/.%00./parent.txt");
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    private void 
testHandleAsyncPathWithIgniteHomeAndContainsParentDirectory(String p) throws 
Exception {
+        IgniteConfiguration cfg = new IgniteConfiguration();
+        cfg.setIgniteHome(igniteHome);
+        GridTestKernalContext ctx = newContext(cfg);
+        GridLogCommandHandler cmdHnd = new GridLogCommandHandler(ctx);
+        GridRestLogRequest req = new GridRestLogRequest();
+
+        req.to(1);
+        req.from(0);
+        req.path(p);
+
+        IgniteInternalFuture<GridRestResponse> resp = cmdHnd.handleAsync(req);
+
+        assertEquals(GridRestResponse.STATUS_FAILED, 
resp.result().getSuccessStatus());
+        assertNull(resp.result().getResponse());
+    }
+
     /**
      * @throws Exception If failed.
      */

Reply via email to