From 8ba7795cd5612764ba00d7c2ba853fdb269191f1 Mon Sep 17 00:00:00 2001 From: Alan Davis Date: Fri, 5 Sep 2014 17:17:58 +0000 Subject: [PATCH] Merged HEAD-BUG-FIX (5.0/Cloud) to HEAD (5.0/Cloud) 83478: Merged V4.2-BUG-FIX (4.2.4) to HEAD-BUG-FIX (5.0/Cloud) 83322: Merged DEV to V4.2-BUG-FIX (4.2.4) 83320 : MNT-12301 - Util method was added for FileContentStore - Unit test added. 83473: Merged V4.1-BUG-FIX (4.1.10) to V4.2-BUG-FIX (4.2.4) (RECORD ONLY) 83474: Merged V4.1-BUG-FIX (4.1.10) to V4.2-BUG-FIX (4.2.4) (RECORD ONLY) git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@83484 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../content/filestore/FileContentStore.java | 32 ++++++++++++ .../filestore/FileContentStoreTest.java | 49 +++++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/source/java/org/alfresco/repo/content/filestore/FileContentStore.java b/source/java/org/alfresco/repo/content/filestore/FileContentStore.java index 67a8d26979..2930376666 100644 --- a/source/java/org/alfresco/repo/content/filestore/FileContentStore.java +++ b/source/java/org/alfresco/repo/content/filestore/FileContentStore.java @@ -72,6 +72,7 @@ public class FileContentStore private File rootDirectory; private String rootAbsolutePath; + private String rootCanonicalPath; private boolean allowRandomAccess; private boolean readOnly; private ApplicationContext applicationContext; @@ -108,6 +109,15 @@ public class FileContentStore rootAbsolutePath = rootDirectory.getAbsolutePath(); allowRandomAccess = true; readOnly = false; + + try + { + rootCanonicalPath = rootDirectory.getCanonicalPath(); + } + catch (IOException e) + { + throw new ContentIOException("Failed to get store root canonical path: " + rootDirectory, e); + } } /** @@ -349,6 +359,9 @@ public class FileContentStore } // get the file File file = new File(rootDirectory, relativePath); + + ensureFileInContentStore(file); + // done return file; } @@ -677,4 +690,23 @@ public class FileContentStore { this.deleteEmptyDirs = deleteEmptyDirs; } + + /* + * Added as fix for MNT-12301, we should ensure that content store accesses content only inside of store root + */ + private void ensureFileInContentStore(File file) + { + try + { + String fileCanonicalPath = file.getCanonicalPath(); + if (!fileCanonicalPath.startsWith(rootCanonicalPath)) + { + throw new ContentIOException("Access to files outside of content store root is not allowed: " + file); + } + } + catch (IOException e) + { + throw new ContentIOException("Failed to get file canonical path: " + file, e); + } + } } diff --git a/source/test-java/org/alfresco/repo/content/filestore/FileContentStoreTest.java b/source/test-java/org/alfresco/repo/content/filestore/FileContentStoreTest.java index 76b9abaab5..d95d3ceaa2 100644 --- a/source/test-java/org/alfresco/repo/content/filestore/FileContentStoreTest.java +++ b/source/test-java/org/alfresco/repo/content/filestore/FileContentStoreTest.java @@ -28,6 +28,7 @@ import org.alfresco.repo.content.ContentLimitProvider; import org.alfresco.repo.content.ContentLimitProvider.SimpleFixedLimitProvider; import org.alfresco.repo.content.ContentLimitViolationException; import org.alfresco.repo.content.ContentStore; +import org.alfresco.service.cmr.repository.ContentIOException; import org.alfresco.service.cmr.repository.ContentWriter; import org.alfresco.test_category.OwnJVMTestsCategory; import org.alfresco.util.TempFileProvider; @@ -241,6 +242,54 @@ public class FileContentStoreTest extends AbstractWritableContentStoreTest assertTrue("Stream close not detected", writer.isClosed()); } + /* + * Test for MNT-12301 case. + */ + public void testFileAccessOutsideStoreRoot() + { + String url = FileContentStore.STORE_PROTOCOL + ContentStore.PROTOCOL_DELIMITER + "../somefile.bin"; + + try + { + store.getReader(url); + fail("Access to content outside of content store root should not be allowed."); + } + catch (ContentIOException e) + { + //expected + } + + try + { + store.exists(url); + fail("Access to content outside of content store root should not be allowed."); + } + catch (ContentIOException e) + { + //expected + } + + try + { + store.delete(url); + fail("Access to content outside of content store root should not be allowed."); + } + catch (ContentIOException e) + { + //expected + } + + try + { + store.getWriterInternal(null, url); + fail("Access to content outside of content store root should not be allowed."); + } + catch (ContentIOException e) + { + //expected + } + } + private void assertDirExists(File root, String dir) {