From 7d22c6fbd79d817bc137da7b9d712cb2802a7df8 Mon Sep 17 00:00:00 2001 From: Benoit TELLIER Date: Wed, 9 Feb 2022 08:24:12 +0700 Subject: [PATCH] CVE-2022-22931 JAMES-3646 Rely on strong typing for file paths operations (#877) --- .../james/sieverepository/file/SieveFileRepository.java | 8 ++------ .../sieverepository/file/SieveFileRepositoryTest.java | 9 +++++++++ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/server/data/data-file/src/main/java/org/apache/james/sieverepository/file/SieveFileRepository.java b/server/data/data-file/src/main/java/org/apache/james/sieverepository/file/SieveFileRepository.java index 26baf986093..b70496b6b30 100644 --- a/server/data/data-file/src/main/java/org/apache/james/sieverepository/file/SieveFileRepository.java +++ b/server/data/data-file/src/main/java/org/apache/james/sieverepository/file/SieveFileRepository.java @@ -316,12 +316,8 @@ protected File getUserDirectory(Username username) throws StorageException { } private void enforceRoot(File file) throws StorageException { - try { - if (!file.getCanonicalPath().startsWith(root.getCanonicalPath())) { - throw new StorageException(new IllegalStateException("Path traversal attempted")); - } - } catch (IOException e) { - throw new StorageException(e); + if (!file.toPath().normalize().startsWith(root.toPath().normalize())) { + throw new StorageException(new IllegalStateException("Path traversal attempted")); } } diff --git a/server/data/data-file/src/test/java/org/apache/james/sieverepository/file/SieveFileRepositoryTest.java b/server/data/data-file/src/test/java/org/apache/james/sieverepository/file/SieveFileRepositoryTest.java index e6b4f17a3c3..1077ec8e3ef 100644 --- a/server/data/data-file/src/test/java/org/apache/james/sieverepository/file/SieveFileRepositoryTest.java +++ b/server/data/data-file/src/test/java/org/apache/james/sieverepository/file/SieveFileRepositoryTest.java @@ -84,4 +84,13 @@ void getScriptShouldNotAllowToReadScriptsOfOtherUsers() throws Exception { new ScriptName("../other/script"))) .isInstanceOf(StorageException.class); } + + @Test + void getScriptShouldNotAllowToReadScriptsOfOtherUsersWhenPrefix() throws Exception { + sieveRepository().putScript(Username.of("testa"), new ScriptName("script"), new ScriptContent("PWND!!!")); + + assertThatThrownBy(() -> sieveRepository().getScript(Username.of("test"), + new ScriptName("../other/script"))) + .isInstanceOf(StorageException.class); + } }