From 41b7c75ad66ea73969ce1d4e25c36fbb4668267e Mon Sep 17 00:00:00 2001 From: Stefano Maffei Date: Thu, 14 Aug 2025 12:02:08 +0200 Subject: [PATCH 1/2] [CST-21947] fix security fix (cherry picked from commit 6c3274630ce081b8395168149756569689153ce0) --- .../org/dspace/storage/bitstore/DSBitStoreService.java | 7 ++++++- dspace/config/modules/assetstore.cfg | 6 ++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/storage/bitstore/DSBitStoreService.java b/dspace-api/src/main/java/org/dspace/storage/bitstore/DSBitStoreService.java index 7743b93ca4..fd4e23b825 100644 --- a/dspace-api/src/main/java/org/dspace/storage/bitstore/DSBitStoreService.java +++ b/dspace-api/src/main/java/org/dspace/storage/bitstore/DSBitStoreService.java @@ -19,9 +19,11 @@ import java.security.NoSuchAlgorithmException; import java.util.List; import java.util.Map; +import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.Logger; import org.dspace.content.Bitstream; import org.dspace.core.Utils; +import org.dspace.services.factory.DSpaceServicesFactory; /** * Native DSpace (or "Directory Scatter" if you prefer) asset store. @@ -252,7 +254,10 @@ public class DSBitStoreService extends BaseBitStoreService { } File bitstreamFile = new File(bufFilename.toString()); Path normalizedPath = bitstreamFile.toPath().normalize(); - if (!normalizedPath.startsWith(baseDir.getAbsolutePath())) { + String[] allowedAssetstoreRoots = DSpaceServicesFactory.getInstance().getConfigurationService() + .getArrayProperty("assetstore.allowed.roots", new String[]{}); + if (!normalizedPath.startsWith(baseDir.getAbsolutePath()) + && !StringUtils.startsWithAny(normalizedPath.toString(), allowedAssetstoreRoots)) { log.error("Bitstream path outside of assetstore root requested:" + "bitstream={}, path={}, assetstore={}", bitstream.getID(), normalizedPath, baseDir.getAbsolutePath()); diff --git a/dspace/config/modules/assetstore.cfg b/dspace/config/modules/assetstore.cfg index 0f66b08e69..cf951c2952 100644 --- a/dspace/config/modules/assetstore.cfg +++ b/dspace/config/modules/assetstore.cfg @@ -12,10 +12,10 @@ assetstore.dir = ${dspace.dir}/assetstore # This value will be used as `incoming` default store inside the `bitstore.xml` # Possible values are: # - 0: to use the `localStore`; -# - 1: to use the `s3Store`. +# - 1: to use the `s3Store`. # If you want to add additional assetstores, they must be added to that bitstore.xml # and new values should be provided as key-value pairs in the `stores` map of the -# `bitstore.xml` configuration. +# `bitstore.xml` configuration. assetstore.index.primary = 0 #---------------------------------------------------------------# @@ -102,3 +102,5 @@ assetstore.s3.awsRegionName = # The maximum counter value for S3 operations. # Default: -1 (unlimited) connection is never manualy closed in BitstoreService # assetstore.jcloud.maxCounter = -1 + +#assetstore.allowed.roots = /data/assetstore \ No newline at end of file From c6d42456f7bbca7fc98287fcc75a195f0d55aefe Mon Sep 17 00:00:00 2001 From: Piaget Bouaka Donfack Date: Thu, 4 Sep 2025 09:41:32 +0200 Subject: [PATCH 2/2] [DURACOM-392] Error in file upload after security fixes (cherry picked from commit 6234103d2c55a1375d7c96db4562a3620e5fd290) --- dspace/config/modules/assetstore.cfg | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/dspace/config/modules/assetstore.cfg b/dspace/config/modules/assetstore.cfg index cf951c2952..478e9522cd 100644 --- a/dspace/config/modules/assetstore.cfg +++ b/dspace/config/modules/assetstore.cfg @@ -18,6 +18,9 @@ assetstore.dir = ${dspace.dir}/assetstore # `bitstore.xml` configuration. assetstore.index.primary = 0 +#if the assetstore path is symbolic link, use this configuration to allow that path. +#assetstore.allowed.roots = /data/assetstore + #---------------------------------------------------------------# #-------------- Amazon S3 Specific Configurations --------------# #---------------------------------------------------------------# @@ -101,6 +104,4 @@ assetstore.s3.awsRegionName = # The maximum counter value for S3 operations. # Default: -1 (unlimited) connection is never manualy closed in BitstoreService -# assetstore.jcloud.maxCounter = -1 - -#assetstore.allowed.roots = /data/assetstore \ No newline at end of file +# assetstore.jcloud.maxCounter = -1 \ No newline at end of file