From bf5eeb23a769a2e2b75f432b74f10fdbcfd2f161 Mon Sep 17 00:00:00 2001 From: "andre.schmid" Date: Fri, 27 Sep 2019 13:27:11 +0100 Subject: 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 --- .../src/test/java/org/openecomp/sdc/ZipUtil.java | 143 --------------------- .../be/components/csar/CsarBusinessLogicTest.java | 13 +- .../sdc/be/components/csar/CsarInfoTest.java | 14 +- .../impl/utils/YamlTemplateParsingHandlerTest.java | 30 +++-- 4 files changed, 31 insertions(+), 169 deletions(-) delete mode 100644 catalog-be/src/test/java/org/openecomp/sdc/ZipUtil.java (limited to 'catalog-be/src/test/java') diff --git a/catalog-be/src/test/java/org/openecomp/sdc/ZipUtil.java b/catalog-be/src/test/java/org/openecomp/sdc/ZipUtil.java deleted file mode 100644 index 87e351be8a..0000000000 --- a/catalog-be/src/test/java/org/openecomp/sdc/ZipUtil.java +++ /dev/null @@ -1,143 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Modifications Copyright (c) 2019 Samsung - * ================================================================================ - * 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. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.openecomp.sdc; - -import org.apache.commons.codec.binary.Base64; -import org.apache.commons.io.output.ByteArrayOutputStream; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.net.URISyntaxException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.HashMap; -import java.util.Map; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; - -public class ZipUtil { - - public static void main(String[] args) { - - String zipFileName = "/src/test/resources/config/config.zip"; - - zipFileName = "C:\\Git_work\\D2-SDnC\\catalog-be\\src\\test\\resources\\config\\config.zip"; - zipFileName = "src/test/resources/config/config.zip"; - - Path path = Paths.get(zipFileName); - - try { - byte[] zipAsBytes = Files.readAllBytes(path); - // encode to base - - byte[] decodedMd5 = Base64.encodeBase64(zipAsBytes); - String decodedStr = new String(decodedMd5); - - zipAsBytes = Base64.decodeBase64(decodedStr.getBytes()); - - // String str = new String(zipAsBytes); - - // readZip(str.getBytes()); - readZip(zipAsBytes); - - } catch (IOException e) { - e.printStackTrace(); - } - - } - - private static Map readZip(byte[] zipAsBytes) { - - Map fileNameToByteArray = new HashMap<>(); - - byte[] buffer = new byte[1024]; - ZipInputStream zis = null; - try { - - zis = new ZipInputStream(new ByteArrayInputStream(zipAsBytes)); - // get the zipped file list entry - ZipEntry ze = zis.getNextEntry(); - - while (ze != null) { - - String fileName = ze.getName(); - - if (!ze.isDirectory()) { - - ByteArrayOutputStream os = new ByteArrayOutputStream(); - try { - int len; - while ((len = zis.read(buffer)) > 0) { - os.write(buffer, 0, len); - } - - // aClass.outputStreamMethod(os); - String aString = new String(os.toByteArray(), "UTF-8"); - - fileNameToByteArray.put(fileName, os.toByteArray()); - - } finally { - if (os != null) { - os.close(); - } - } - } - ze = zis.getNextEntry(); - - } - - zis.closeEntry(); - zis.close(); - - } catch (IOException ex) { - ex.printStackTrace(); - return null; - } finally { - if (zis != null) { - try { - zis.closeEntry(); - zis.close(); - } catch (IOException e) { - // TODO: add log - } - - } - } - - return fileNameToByteArray; - - } - - private static byte[] loadResource(String resourceDir) throws IOException, URISyntaxException { - - Path path = Paths.get(ZipUtil.class.getResource(resourceDir).toURI()); - return Files.readAllBytes(path); - } - - public static Map readData(String resourceDir) throws IOException, URISyntaxException { - - byte[] data = loadResource(resourceDir); - return readZip(data); - } -} diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/CsarBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/CsarBusinessLogicTest.java index 2f7f5aab17..9bad9f4fa8 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/CsarBusinessLogicTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/CsarBusinessLogicTest.java @@ -50,11 +50,7 @@ import java.util.Map; import org.junit.Before; import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; import org.mockito.Mockito; -import org.mockito.junit.MockitoJUnitRunner; import org.openecomp.sdc.be.components.impl.BaseBusinessLogicMock; import org.openecomp.sdc.be.components.impl.exceptions.ComponentException; @@ -66,7 +62,8 @@ import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; import org.openecomp.sdc.be.model.operations.impl.CsarOperation; import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; -import org.openecomp.sdc.common.util.ZipUtil; +import org.openecomp.sdc.common.zip.ZipUtils; +import org.openecomp.sdc.common.zip.exception.ZipException; import org.openecomp.sdc.exception.ResponseFormat; public class CsarBusinessLogicTest extends BaseBusinessLogicMock { @@ -125,7 +122,7 @@ public class CsarBusinessLogicTest extends BaseBusinessLogicMock { } @Test() - public void testGetCsarInfoWithPayload() throws IOException, URISyntaxException { + public void testGetCsarInfoWithPayload() throws IOException, URISyntaxException, ZipException { // given Resource resource = new Resource(); resource.setName(RESOURCE_NAME); @@ -185,11 +182,11 @@ public class CsarBusinessLogicTest extends BaseBusinessLogicMock { test.validateCsarBeforeCreate(resource, AuditingActionEnum.ARTIFACT_DOWNLOAD, user, "csarUUID"); } - public Map loadPayload(String payloadName) throws IOException, URISyntaxException { + public Map loadPayload(String payloadName) throws IOException, URISyntaxException, ZipException { Path path = Paths.get(getClass().getResource("/" + payloadName).toURI()); byte[] data = Files.readAllBytes(path); - return ZipUtil.readZip(data); + return ZipUtils.readZip(data, false); } } diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/CsarInfoTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/CsarInfoTest.java index 3ae65c818a..69f9f5704d 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/CsarInfoTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/CsarInfoTest.java @@ -25,7 +25,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import java.io.IOException; +import java.io.File; import java.net.URISyntaxException; import java.util.Arrays; import java.util.List; @@ -41,7 +41,8 @@ import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentEx import org.openecomp.sdc.be.dao.api.ActionStatus; import org.openecomp.sdc.be.model.NodeTypeInfo; import org.openecomp.sdc.be.model.User; -import org.openecomp.sdc.ZipUtil; +import org.openecomp.sdc.common.zip.ZipUtils; +import org.openecomp.sdc.common.zip.exception.ZipException; @RunWith(MockitoJUnitRunner.class) public class CsarInfoTest { @@ -52,19 +53,18 @@ public class CsarInfoTest { private User user; private static final String CSAR_UUID = "csarUUID"; - private static final String PAYLOAD_NAME = "/mock_service.csar"; + private static final String PAYLOAD_NAME = "mock_service.csar"; private static final String RESOURCE_NAME = "resourceName"; private static final String MAIN_TEMPLATE_NAME = "Definitions/tosca_mock_vf.yaml"; - private static final String NEW_NODE_NAME = "new_db"; private static final String NODE_TYPE = "tosca.nodes.Compute"; private static final String DELIVER_FOR = "tosca.nodes.Root"; @Before - public void setup() throws IOException, URISyntaxException { - + public void setup() throws ZipException, URISyntaxException { // given - Map payload = ZipUtil.readData(PAYLOAD_NAME); + final File csarFile = new File(CsarInfoTest.class.getClassLoader().getResource(PAYLOAD_NAME).toURI()); + final Map payload = ZipUtils.readZip(csarFile, false); String mainTemplateContent = new String(payload.get(MAIN_TEMPLATE_NAME)); csarInfo = new CsarInfo(user, CSAR_UUID, payload, RESOURCE_NAME, diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/utils/YamlTemplateParsingHandlerTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/utils/YamlTemplateParsingHandlerTest.java index 19d1a17e84..8ae02c4f1b 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/utils/YamlTemplateParsingHandlerTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/utils/YamlTemplateParsingHandlerTest.java @@ -27,11 +27,14 @@ import static org.junit.Assert.assertNotNull; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; -import java.io.IOException; +import java.io.File; import java.net.URISyntaxException; -import java.util.*; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; import java.util.stream.Collectors; - import org.assertj.core.util.Lists; import org.junit.Assert; import org.junit.Before; @@ -41,8 +44,6 @@ import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; - -import org.openecomp.sdc.ZipUtil; import org.openecomp.sdc.be.components.csar.CsarInfo; import org.openecomp.sdc.be.components.csar.YamlTemplateParsingHandler; import org.openecomp.sdc.be.components.impl.AnnotationBusinessLogic; @@ -50,8 +51,15 @@ import org.openecomp.sdc.be.components.impl.GroupTypeBusinessLogic; import org.openecomp.sdc.be.components.validation.AnnotationValidator; import org.openecomp.sdc.be.dao.jsongraph.JanusGraphDao; import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; -import org.openecomp.sdc.be.model.*; +import org.openecomp.sdc.be.model.CapabilityDefinition; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.GroupProperty; +import org.openecomp.sdc.be.model.GroupTypeDefinition; +import org.openecomp.sdc.be.model.ParsedToscaYamlInfo; +import org.openecomp.sdc.be.model.User; import org.openecomp.sdc.be.model.operations.impl.AnnotationTypeOperations; +import org.openecomp.sdc.common.zip.ZipUtils; +import org.openecomp.sdc.common.zip.exception.ZipException; import java.io.File; import java.io.IOException; @@ -88,10 +96,8 @@ public class YamlTemplateParsingHandlerTest { private final static GroupTypeDefinition rootGroupType = buildRootGroupType(); private final static String CAPABILITY_TYPE = "org.openecomp.capabilities.VLANAssignment"; private final static String CAPABILITY_NAME = "vlan_assignment"; - private static final String CSAR_FILE_PATH = "/csars/with_groups.csar"; - + private static final String CSAR_FILE_PATH = "csars/with_groups.csar"; private static final String FILE_NAME = "MainServiceTemplate.yaml"; - private static final String CSAR_UUID = "csarUUID"; private static final String RESOURCE_NAME = "resourceName"; private static final String MAIN_TEMPLATE_NAME = "Definitions/MainServiceTemplate.yaml"; @@ -103,8 +109,10 @@ public class YamlTemplateParsingHandlerTest { YamlTemplateParsingHandler testSubject; @BeforeClass() - public static void prepareData() throws IOException, URISyntaxException { - csar = ZipUtil.readData(CSAR_FILE_PATH); + public static void prepareData() throws URISyntaxException, ZipException { + final File csarFile = new File( + YamlTemplateParsingHandlerTest.class.getClassLoader().getResource(CSAR_FILE_PATH).toURI()); + csar = ZipUtils.readZip(csarFile, false); Optional keyOp = csar.keySet().stream().filter(k -> k.endsWith(FILE_NAME)).findAny(); byte[] mainTemplateService = keyOp.map(csar::get).orElse(null); -- cgit 1.2.3-korg