mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-07 01:54:22 +00:00
Merge pull request #11037 from DSpace/backport-11031-to-dspace-8_x
[Port dspace-8_x] Improve SAF manifest path handling
This commit is contained in:
@@ -1010,6 +1010,34 @@ public class ItemImportServiceImpl implements ItemImportService, InitializingBea
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures a file path does not attempt to access files outside the designated parent directory.
|
||||
*
|
||||
* @param parentDir The absolute path to the parent directory that should contain the file
|
||||
* @param fileName The name or path of the file to validate
|
||||
* @throws IOException If an error occurs while resolving canonical paths, or the file path attempts
|
||||
* to access a location outside the parent directory
|
||||
*/
|
||||
private void validateFilePath(String parentDir, String fileName) throws IOException {
|
||||
File parent = new File(parentDir);
|
||||
File file = new File(fileName);
|
||||
|
||||
// If the fileName is not an absolute path, we resolve it against the parentDir
|
||||
if (!file.isAbsolute()) {
|
||||
file = new File(parent, fileName);
|
||||
}
|
||||
|
||||
String parentCanonicalPath = parent.getCanonicalPath();
|
||||
String fileCanonicalPath = file.getCanonicalPath();
|
||||
|
||||
if (!fileCanonicalPath.startsWith(parentCanonicalPath)) {
|
||||
log.error("File path outside of canonical root requested: fileCanonicalPath={} does not begin " +
|
||||
"with parentCanonicalPath={}", fileCanonicalPath, parentCanonicalPath);
|
||||
throw new IOException("Illegal file path '" + fileName + "' encountered. This references a path " +
|
||||
"outside of the import package. Please see the system logs for more details.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the collections file inside the item directory. If there
|
||||
* is one and it is not empty return a list of collections in
|
||||
@@ -1210,6 +1238,7 @@ public class ItemImportServiceImpl implements ItemImportService, InitializingBea
|
||||
sDescription = sDescription.replaceFirst("description:", "");
|
||||
}
|
||||
|
||||
validateFilePath(path, sFilePath);
|
||||
registerBitstream(c, i, iAssetstore, sFilePath, sBundle, sDescription);
|
||||
logInfo("\tRegistering Bitstream: " + sFilePath
|
||||
+ "\tAssetstore: " + iAssetstore
|
||||
@@ -1423,6 +1452,7 @@ public class ItemImportServiceImpl implements ItemImportService, InitializingBea
|
||||
return;
|
||||
}
|
||||
|
||||
validateFilePath(path, fileName);
|
||||
String fullpath = path + File.separatorChar + fileName;
|
||||
|
||||
// get an input stream
|
||||
|
@@ -12,6 +12,7 @@ import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Path;
|
||||
import java.security.DigestInputStream;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
@@ -249,7 +250,15 @@ public class DSBitStoreService extends BaseBitStoreService {
|
||||
log.debug("Local filename for " + sInternalId + " is "
|
||||
+ bufFilename.toString());
|
||||
}
|
||||
return new File(bufFilename.toString());
|
||||
File bitstreamFile = new File(bufFilename.toString());
|
||||
Path normalizedPath = bitstreamFile.toPath().normalize();
|
||||
if (!normalizedPath.startsWith(baseDir.getAbsolutePath())) {
|
||||
log.error("Bitstream path outside of assetstore root requested:" +
|
||||
"bitstream={}, path={}, assetstore={}",
|
||||
bitstream.getID(), normalizedPath, baseDir.getAbsolutePath());
|
||||
throw new IOException("Illegal bitstream path constructed");
|
||||
}
|
||||
return bitstreamFile;
|
||||
}
|
||||
|
||||
public boolean isRegisteredBitstream(String internalId) {
|
||||
|
Reference in New Issue
Block a user