Headline
CVE-2022-31195: [DS-4131] Better path handling in ItemImport zips · DSpace/DSpace@56e7604
DSpace open source software is a repository application which provides durable access to digital resources. In affected versions the ItemImportServiceImpl is vulnerable to a path traversal vulnerability. This means a malicious SAF (simple archive format) package could cause a file/directory to be created anywhere the Tomcat/DSpace user can write to on the server. However, this path traversal vulnerability is only possible by a user with special privileges (either Administrators or someone with command-line access to the server). This vulnerability impacts the XMLUI, JSPUI and command-line. Users are advised to upgrade. As a basic workaround, users may block all access to the following URL paths: If you are using the XMLUI, block all access to /admin/batchimport path (this is the URL of the Admin Batch Import tool). Keep in mind, if your site uses the path "/xmlui", then you’d need to block access to /xmlui/admin/batchimport. If you are using the JSPUI, block all access to /dspace-admin/batchimport path (this is the URL of the Admin Batch Import tool). Keep in mind, if your site uses the path "/jspui", then you’d need to block access to /jspui/dspace-admin/batchimport. Keep in mind, only an Administrative user or a user with command-line access to the server is able to import/upload SAF packages. Therefore, assuming those users do not blindly upload untrusted SAF packages, then it is unlikely your site could be impacted by this vulnerability.
@@ -2003,22 +2003,30 @@ public static String unzip(File zipfile, String destDir) throws IOException { if (destinationDir == null){ destinationDir = tempWorkDir; } log.debug("Using directory " + destinationDir + " for zip extraction. (destDir arg is " + destDir + ", tempWorkDir is " + tempWorkDir + ")");
File tempdir = new File(destinationDir); if (!tempdir.isDirectory()) { log.error(“’” + ConfigurationManager.getProperty(“org.dspace.app.itemexport.work.dir”) + "’ as defined by the key ‘org.dspace.app.itemexport.work.dir’ in dspace.cfg " + log.error(“’” + ConfigurationManager.getProperty(“org.dspace.app.batchitemimport.work.dir”) + "’ as defined by the key ‘org.dspace.app.batchitemimport.work.dir’ in dspace.cfg " + “is not a valid directory”); }
if (!tempdir.exists() && !tempdir.mkdirs()) { log.error("Unable to create temporary directory: " + tempdir.getAbsolutePath()); } String sourcedir = destinationDir + System.getProperty(“file.separator”) + zipfile.getName(); String zipDir = destinationDir + System.getProperty(“file.separator”) + zipfile.getName() + System.getProperty(“file.separator”);
if(!destinationDir.endsWith(System.getProperty(“file.separator”))) { destinationDir += System.getProperty(“file.separator”); }
String sourcedir = destinationDir + zipfile.getName(); String zipDir = destinationDir + zipfile.getName() + System.getProperty(“file.separator”);
log.debug("zip directory to use is " + zipDir);
// 3 String sourceDirForZip = sourcedir; @@ -2028,11 +2036,26 @@ public static String unzip(File zipfile, String destDir) throws IOException { while (entries.hasMoreElements()) { entry = entries.nextElement(); // Check that the true path to extract files is never outside allowed temp directories // without creating any actual files on disk log.debug(“Inspecting entry name: " + entry.getName() + " for path traversal security”); File potentialExtract = new File(zipDir + entry.getName()); String canonicalPath = potentialExtract.getCanonicalPath(); log.debug("Canonical path to potential File is " + canonicalPath); if(!canonicalPath.startsWith(zipDir)) { log.error("Rejecting zip file: " + zipfile.getName() + " as it contains an entry that would be extracted " + "outside the temporary unzip directory: " + canonicalPath); throw new IOException("Error extracting " + zipfile + ": Canonical path of zip entry: " + entry.getName() + " (" + canonicalPath + ") does not start with permissible temp " + "unzip directory (" + destinationDir + ")"); } if (entry.isDirectory()) { if (!new File(zipDir + entry.getName()).mkdir()) { // Log error and throw IOException if a directory entry could not be created File newDir = new File(zipDir + entry.getName()); if (!newDir.mkdirs()) { log.error("Unable to create contents directory: " + zipDir + entry.getName()); throw new IOException("Unable to create contents directory: " + zipDir + entry.getName()); } } else @@ -2074,6 +2097,7 @@ public static String unzip(File zipfile, String destDir) throws IOException { byte[] buffer = new byte[1024]; int len; InputStream in = zf.getInputStream(entry); log.debug(“Reading " + zipDir + entry.getName() + " into InputStream”); BufferedOutputStream out = new BufferedOutputStream( new FileOutputStream(zipDir + entry.getName())); while((len = in.read(buffer)) >= 0)
Related news
### Impact ItemImportServiceImpl is vulnerable to a path traversal vulnerability. This means a malicious SAF (simple archive format) package could cause a file/directory to be created anywhere the Tomcat/DSpace user can write to on the server. However, this path traversal vulnerability is only possible by a user with special privileges (either Administrators or someone with command-line access to the server). This vulnerability impacts the XMLUI, JSPUI and command-line. _This vulnerability does NOT impact 7.x._ ### Patches _DSpace 6.x:_ * Fixed in 6.4 via commit: https://github.com/DSpace/DSpace/commit/7af52a0883a9dbc475cf3001f04ed11b24c8a4c0 * 6.x patch file: https://github.com/DSpace/DSpace/commit/7af52a0883a9dbc475cf3001f04ed11b24c8a4c0.patch (may be applied manually if an immediate upgrade to 6.4 or 7.x is not possible) _DSpace 5.x:_ * Fixed in 5.11 via commit: https://github.com/DSpace/DSpace/commit/56e76049185bbd87c994128a9d77735ad7af0199 * 5.x patch file: https://github.c...