This is an automated email from the ASF dual-hosted git repository. jiangtian pushed a commit to branch fix_path_attack_1.3 in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit f601a6535d400e8026af916212478ed46bf683e7 Author: Tian Jiang <[email protected]> AuthorDate: Tue Aug 5 09:58:09 2025 +0800 Fix path attack when loading snapshot of IoTConsensus (cherry picked from commit f907bd3eb07523ec40eb0079c8601d961b07b184) --- .../consensus/iot/IoTConsensusServerImpl.java | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/iot/IoTConsensusServerImpl.java b/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/iot/IoTConsensusServerImpl.java index dab767bc9da..3002b018e3e 100644 --- a/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/iot/IoTConsensusServerImpl.java +++ b/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/iot/IoTConsensusServerImpl.java @@ -358,7 +358,7 @@ public class IoTConsensusServerImpl { throws ConsensusGroupModifyPeerException { try { String targetFilePath = calculateSnapshotPath(snapshotId, originalFilePath); - File targetFile = new File(storageDir, targetFilePath); + File targetFile = getSnapshotPath(targetFilePath); Path parentDir = Paths.get(targetFile.getParent()); if (!Files.exists(parentDir)) { Files.createDirectories(parentDir); @@ -405,7 +405,23 @@ public class IoTConsensusServerImpl { public void loadSnapshot(String snapshotId) { // TODO: (xingtanzjr) throw exception if the snapshot load failed - stateMachine.loadSnapshot(new File(storageDir, snapshotId)); + stateMachine.loadSnapshot(getSnapshotPath(snapshotId)); + } + + private File getSnapshotPath(String snapshotRelativePath) { + File storageDirFile = new File(storageDir); + File snapshotDir = new File(storageDir, snapshotRelativePath); + try { + if (!snapshotDir + .getCanonicalFile() + .toPath() + .startsWith(storageDirFile.getCanonicalFile().toPath())) { + throw new IllegalArgumentException("Invalid snapshotRelativePath: " + snapshotRelativePath); + } + } catch (IOException e) { + throw new IllegalArgumentException(e); + } + return snapshotDir; } @FunctionalInterface @@ -816,7 +832,7 @@ public class IoTConsensusServerImpl { } public void cleanupSnapshot(String snapshotId) throws ConsensusGroupModifyPeerException { - File snapshotDir = new File(storageDir, snapshotId); + File snapshotDir = getSnapshotPath(snapshotId); if (snapshotDir.exists()) { try { FileUtils.deleteDirectory(snapshotDir);
