aboutsummaryrefslogtreecommitdiffstats
path: root/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/main
diff options
context:
space:
mode:
authorandre.schmid <andre.schmid@est.tech>2019-09-27 13:27:11 +0100
committerOfir Sonsino <ofir.sonsino@intl.att.com>2019-10-30 09:47:54 +0000
commitbf5eeb23a769a2e2b75f432b74f10fdbcfd2f161 (patch)
treefa27998ee6efef6f7651315cbf71271130fca025 /openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/main
parent19773b769c6762a12876064c70a34cc31d2b12da (diff)
Fix zip slip security flaw
Apply zip slip checking in zip operations throughout the system. Centralizes most of the zip logic in one class. Create tests to zip functionalities and zip slip problem. Change-Id: I721f3d44b34fe6d242c9537f5a515ce1bb534c9a Issue-ID: SDC-1401 Signed-off-by: andre.schmid <andre.schmid@est.tech>
Diffstat (limited to 'openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/main')
-rw-r--r--openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/main/java/org/openecomp/core/externaltesting/impl/ExternalTestingManagerImpl.java61
1 files changed, 30 insertions, 31 deletions
diff --git a/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/main/java/org/openecomp/core/externaltesting/impl/ExternalTestingManagerImpl.java b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/main/java/org/openecomp/core/externaltesting/impl/ExternalTestingManagerImpl.java
index e112ef432c..22ac1e8ed8 100644
--- a/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/main/java/org/openecomp/core/externaltesting/impl/ExternalTestingManagerImpl.java
+++ b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/main/java/org/openecomp/core/externaltesting/impl/ExternalTestingManagerImpl.java
@@ -18,17 +18,21 @@ package org.openecomp.core.externaltesting.impl;
import com.amdocs.zusammen.utils.fileutils.json.JsonUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.collect.ImmutableSet;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
+import java.util.Map.Entry;
import lombok.EqualsAndHashCode;
-import org.apache.commons.io.IOUtils;
+import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.onap.sdc.tosca.services.YamlUtil;
import org.openecomp.core.externaltesting.api.*;
import org.openecomp.core.externaltesting.errors.ExternalTestingException;
+import org.openecomp.sdc.common.zip.ZipUtils;
+import org.openecomp.sdc.common.zip.exception.ZipException;
import org.openecomp.sdc.heat.datatypes.manifest.FileData;
import org.openecomp.sdc.heat.datatypes.manifest.ManifestContent;
import org.openecomp.sdc.vendorsoftwareproduct.OrchestrationTemplateCandidateManager;
@@ -58,7 +62,6 @@ import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
public class ExternalTestingManagerImpl implements ExternalTestingManager {
@@ -97,6 +100,8 @@ public class ExternalTestingManagerImpl implements ExternalTestingManager {
private static final String SDC_CSAR = "sdc-csar";
private static final String SDC_HEAT = "sdc-heat";
+ private final ImmutableSet<String> relevantArchiveFileExtensionSet =
+ ImmutableSet.of("yaml", "meta", "yml", "json", "env");
private VersioningManager versioningManager;
@@ -721,10 +726,8 @@ public class ExternalTestingManagerImpl implements ExternalTestingManager {
private void processArchive(final VtpTestExecutionRequest test, final MultiValueMap<String, Object> body, final byte[] zip) {
// We need to make one pass through the zip input stream. Pull out files that match our expectations into a temporary
- // map that we can process over. These are not huge files so we shouldn't need to worry about memory.
-
- List<String> extensions = Arrays.asList(".yaml", ".meta", ".yml", ".json", ".env");
- final Map<String, byte[]> contentWeCareAbout = extractRelevantContent(zip, extensions);
+ // map that we can process over. These are not huge files so we shouldn't need to worry about memory.
+ final Map<String, byte[]> contentWeCareAbout = extractRelevantContent(zip);
// VTP does not support concurrent executions of the same test with the same associated file name.
// It writes files to /tmp and if we were to send two requests with the same file, the results are unpredictable.
@@ -891,34 +894,30 @@ public class ExternalTestingManagerImpl implements ExternalTestingManager {
* @param zip csar/heat zip to iterate over
* @return relevant content from the archive file as a map.
*/
- private Map<String, byte[]> extractRelevantContent(final byte[] zip, final List<String> extensions) {
- final Map<String, byte[]> rv = new HashMap<>(); // FYI, rv = return value.
- try (ByteArrayInputStream is = new ByteArrayInputStream(zip)) {
- try (ZipInputStream zipStream = new ZipInputStream(is)) {
- ZipEntry entry;
- while ((entry = zipStream.getNextEntry()) != null) {
- final String entryName = entry.getName();
-
- // NOTE: leaving this debugging in for dublin...
- logger.debug("archive contains entry {}", entryName);
-
- extractIfMatching(extensions, rv, zipStream, entryName);
- }
- }
- }
- catch (IOException ex) {
- logger.error("error encountered processing archive", ex);
- throw new ExternalTestingException(SDC_RESOLVER_ERR, 500, ex.getMessage());
+ private Map<String, byte[]> extractRelevantContent(final byte[] zip) {
+ final Map<String, byte[]> zipFileAndByteMap;
+ try {
+ zipFileAndByteMap = ZipUtils.readZip(zip, false);
+ } catch (final ZipException ex) {
+ logger.error("An error occurred while processing archive", ex);
+ throw new ExternalTestingException(SDC_RESOLVER_ERR, 500, ex.getMessage(), ex);
}
- return rv;
+
+ return zipFileAndByteMap.entrySet().stream()
+ .filter(stringEntry -> hasRelevantExtension(stringEntry.getKey()))
+ .collect(Collectors.toMap(Entry::getKey, Entry::getValue));
}
- private void extractIfMatching(List<String> extensions, Map<String, byte[]> rv, ZipInputStream zipStream, String entryName) throws IOException {
- int idx = entryName.lastIndexOf('.');
- if ((idx >= 0) && (extensions.contains(entryName.substring(idx)))) {
- byte[] content = IOUtils.toByteArray(zipStream);
- rv.put(entryName, content);
- }
+ /**
+ * Checks if the file matches with a expected extension.
+ *
+ * @param filePath the file path
+ * @return {@code true} if the file extension matches with {@link #relevantArchiveFileExtensionSet}, {@code false}
+ * otherwise
+ */
+ private boolean hasRelevantExtension(final String filePath) {
+ final String entryExtension = FilenameUtils.getExtension(filePath);
+ return StringUtils.isNotEmpty(entryExtension) && (relevantArchiveFileExtensionSet.contains(entryExtension));
}
/**