GP-6354: Check to make sure we aren't unzipping extension files to

outside the extension directory
This commit is contained in:
Ryan Kurtz
2026-01-20 18:32:40 -05:00
parent 75df24a131
commit 5f3bb4af3b

View File

@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -22,8 +22,8 @@ import java.util.*;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.apache.commons.compress.utils.IOUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -265,7 +265,7 @@ public class ExtensionUtils {
return null;
}
try (ZipFile zipFile = new ZipFile(file)) {
try (ZipFile zipFile = new ZipFile.Builder().setFile(file).get()) {
Properties props = getProperties(zipFile);
if (props != null) {
ExtensionDetails extension = createExtensionDetails(props);
@@ -359,7 +359,7 @@ public class ExtensionUtils {
// eg: DatabaseTools/extension.properties is valid
// DatabaseTools/foo/extension.properties is not.
if (isZip(file)) {
try (ZipFile zipFile = new ZipFile(file)) {
try (ZipFile zipFile = new ZipFile.Builder().setFile(file).get()) {
Properties props = getProperties(zipFile);
if (props != null) {
return createExtensionDetails(props);
@@ -569,7 +569,7 @@ public class ExtensionUtils {
return false;
}
try (ZipFile zipFile = new ZipFile(file)) {
try (ZipFile zipFile = new ZipFile.Builder().setFile(file).get()) {
Enumeration<ZipArchiveEntry> entries = zipFile.getEntries();
while (entries.hasMoreElements()) {
@@ -578,6 +578,9 @@ public class ExtensionUtils {
ZipArchiveEntry entry = entries.nextElement();
String filePath = installDir + File.separator + entry.getName();
File destination = new File(filePath);
if (!FileUtilities.isPathContainedWithin(installDirRoot, destination)) {
throw new IOException("Zip entry escapes target directory: " + entry.getName());
}
if (entry.isDirectory()) {
destination.mkdirs();
}
@@ -586,6 +589,15 @@ public class ExtensionUtils {
}
}
}
catch (IOException e) {
if (!FileUtilities.deleteDir(destinationFolder)) {
throw new IOException(
"Failed to clean up partially installed extension directory: " +
destinationFolder,
e);
}
throw e;
}
extension.setInstallDir(destinationFolder);
return true;