From 8f2b611dcb3554717478017597c97746b8aba7f9 Mon Sep 17 00:00:00 2001 From: vasraz Date: Wed, 16 Jun 2021 13:53:58 +0100 Subject: Fix CRITICAL xxe (XML External Entity) issues Signed-off-by: Vasyl Razinkov Change-Id: Ic33527d54a5245430e41b5a4261810922f7b4fb1 Issue-ID: SDC-3608 --- .../sdc/asdctool/impl/GraphMLDataAnalyzer.java | 228 ++++++++++----------- .../sdc/asdctool/impl/GraphMLDataAnalyzerTest.java | 32 +-- 2 files changed, 128 insertions(+), 132 deletions(-) diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/GraphMLDataAnalyzer.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/GraphMLDataAnalyzer.java index bbfcbd36dd..88e20e9b21 100644 --- a/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/GraphMLDataAnalyzer.java +++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/GraphMLDataAnalyzer.java @@ -24,21 +24,21 @@ import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Set; -import javax.xml.XMLConstants; +import org.apache.commons.lang3.StringUtils; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; -import org.jdom2.Document; -import org.jdom2.Element; -import org.jdom2.JDOMException; -import org.jdom2.filter.ElementFilter; -import org.jdom2.input.SAXBuilder; -import org.jdom2.util.IteratorIterable; +import org.dom4j.Document; +import org.dom4j.DocumentException; +import org.dom4j.Element; +import org.dom4j.io.SAXReader; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.xml.sax.SAXException; public class GraphMLDataAnalyzer { @@ -47,12 +47,12 @@ public class GraphMLDataAnalyzer { private static final String[] COMPONENT_SHEET_HEADER = {"uniqueId", "type", "name", "toscaResourceName", "resourceType", "version", "deleted", "hasNonCalculatedReqCap"}; private static final String[] COMPONENT_INSTANCES_SHEET_HEADER = {"uniqueId", "name", "originUid", "originType", "containerUid"}; - private static Logger log = LoggerFactory.getLogger(GraphMLDataAnalyzer.class); + private static final Logger log = LoggerFactory.getLogger(GraphMLDataAnalyzer.class); - public String analyzeGraphMLData(String[] args) { + public String analyzeGraphMLData(final String[] args) { String result; try { - String mlFileLocation = args[0]; + final String mlFileLocation = args[0]; result = analyzeGraphMLData(mlFileLocation); log.info("Analyzed ML file={}, XLS result={}", mlFileLocation, result); } catch (Exception e) { @@ -62,34 +62,32 @@ public class GraphMLDataAnalyzer { return result; } - private String analyzeGraphMLData(String mlFileLocation) throws JDOMException, IOException { + private String analyzeGraphMLData(final String mlFileLocation) throws SAXException, DocumentException, IOException { // Parse ML file - SAXBuilder builder = new SAXBuilder(); - builder.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, ""); - builder.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); - File xmlFile = new File(mlFileLocation); - Document document = builder.build(xmlFile); + final SAXReader xmlReader = new SAXReader(); + xmlReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + final Document document = xmlReader.read(new File(mlFileLocation)); + // XLS data file name - String outputFile = mlFileLocation.replace(GRAPH_ML_EXTENSION, EXCEL_EXTENSION); - try (Workbook wb = new HSSFWorkbook(); FileOutputStream fileOut = new FileOutputStream(outputFile)) { + final String outputFile = mlFileLocation.replace(GRAPH_ML_EXTENSION, EXCEL_EXTENSION); + try (final var wb = new HSSFWorkbook(); final var fileOut = new FileOutputStream(outputFile)) { writeComponents(wb, document); writeComponentInstances(wb, document); wb.write(fileOut); - } catch (Exception e) { + } catch (final Exception e) { log.error("Analyze GraphML Data failed!", e); } return outputFile; } - private void writeComponents(Workbook wb, Document document) { - Sheet componentsSheet = wb.createSheet("Components"); + private void writeComponents(final Workbook wb, final Document document) { + final Sheet componentsSheet = wb.createSheet("Components"); Row currentRow = componentsSheet.createRow(0); for (int i = 0; i < COMPONENT_SHEET_HEADER.length; i++) { currentRow.createCell(i).setCellValue(COMPONENT_SHEET_HEADER[i]); } - List components = getComponents(document); int rowNum = 1; - for (ComponentRow row : components) { + for (final ComponentRow row : getComponents(document)) { currentRow = componentsSheet.createRow(rowNum++); currentRow.createCell(0).setCellValue(row.getUniqueId()); currentRow.createCell(1).setCellValue(row.getType()); @@ -102,15 +100,14 @@ public class GraphMLDataAnalyzer { } } - private void writeComponentInstances(Workbook wb, Document document) { - Sheet componentsSheet = wb.createSheet("ComponentInstances"); + private void writeComponentInstances(final Workbook wb, final Document document) { + final Sheet componentsSheet = wb.createSheet("ComponentInstances"); Row currentRow = componentsSheet.createRow(0); for (int i = 0; i < COMPONENT_INSTANCES_SHEET_HEADER.length; i++) { currentRow.createCell(i).setCellValue(COMPONENT_INSTANCES_SHEET_HEADER[i]); } - List components = getComponentInstances(document); int rowNum = 1; - for (ComponentInstanceRow row : components) { + for (final ComponentInstanceRow row : getComponentInstances(document)) { currentRow = componentsSheet.createRow(rowNum++); currentRow.createCell(0).setCellValue(row.getUniqueId()); currentRow.createCell(1).setCellValue(row.getName()); @@ -120,66 +117,67 @@ public class GraphMLDataAnalyzer { } } - private List getComponents(Document document) { - List res = new ArrayList<>(); - Element root = document.getRootElement(); - ElementFilter filter = new ElementFilter("graph"); - Element graph = root.getDescendants(filter).next(); - filter = new ElementFilter("edge"); - IteratorIterable edges = graph.getDescendants(filter); - Set componentsHavingReqOrCap = new HashSet<>(); - filter = new ElementFilter("data"); - for (Element edge : edges) { - IteratorIterable dataNodes = edge.getDescendants(filter); - for (Element data : dataNodes) { - String attributeValue = data.getAttributeValue("key"); + private List getComponents(final Document document) { + final List res = new ArrayList<>(); + final Element root = document.getRootElement(); + final Element graph = (Element) root.elementIterator("graph").next(); + final Iterator edges = graph.elementIterator("edge"); + final Set componentsHavingReqOrCap = new HashSet<>(); + while (edges.hasNext()) { + final Element edge = edges.next(); + final Iterator dataNodes = edge.elementIterator("data"); + while (dataNodes.hasNext()) { + final Element data = dataNodes.next(); + final String attributeValue = data.attributeValue("key"); if ("labelE".equals(attributeValue)) { - String edgeLabel = data.getText(); + final String edgeLabel = data.getText(); if ("REQUIREMENT".equals(edgeLabel) || "CAPABILITY".equals(edgeLabel)) { - componentsHavingReqOrCap.add(edge.getAttributeValue("source")); + componentsHavingReqOrCap.add(edge.attributeValue("source")); } } } } - filter = new ElementFilter("node"); - IteratorIterable nodes = graph.getDescendants(filter); - filter = new ElementFilter("data"); - for (Element element : nodes) { - IteratorIterable dataNodes = element.getDescendants(filter); - ComponentRow componentRow = new ComponentRow(); + final Iterator nodes = graph.elementIterator("node"); + while (nodes.hasNext()) { + final Element element = nodes.next(); + final Iterator dataNodes = element.elementIterator("data"); + final ComponentRow componentRow = new ComponentRow(); boolean isComponent = false; - for (Element data : dataNodes) { - String attributeValue = data.getAttributeValue("key"); - switch (attributeValue) { - case "nodeLabel": - String nodeLabel = data.getText(); - if ("resource".equals(nodeLabel) || "service".equals(nodeLabel)) { - isComponent = true; - componentRow.setType(nodeLabel); - String componentId = element.getAttributeValue("id"); - componentRow.setHasNonCalculatedReqCap(componentsHavingReqOrCap.contains(componentId)); - } - break; - case "uid": - componentRow.setUniqueId(data.getText()); - break; - case "name": - componentRow.setName(data.getText()); - break; - case "toscaResourceName": - componentRow.setToscaResourceName(data.getText()); - break; - case "resourceType": - componentRow.setResourceType(data.getText()); - break; - case "version": - componentRow.setVersion(data.getText()); - break; - case "deleted": - componentRow.setIsDeleted(Boolean.parseBoolean(data.getText())); - break; - default: - break; + while (dataNodes.hasNext()) { + final Element data = dataNodes.next(); + final String attributeValue = data.attributeValue("key"); + if (StringUtils.isNotEmpty(attributeValue)) { + switch (attributeValue) { + case "nodeLabel": + final String nodeLabel = data.getText(); + if ("resource".equals(nodeLabel) || "service".equals(nodeLabel)) { + isComponent = true; + componentRow.setType(nodeLabel); + final String componentId = element.attributeValue("id"); + componentRow.setHasNonCalculatedReqCap(componentsHavingReqOrCap.contains(componentId)); + } + break; + case "uid": + componentRow.setUniqueId(data.getText()); + break; + case "name": + componentRow.setName(data.getText()); + break; + case "toscaResourceName": + componentRow.setToscaResourceName(data.getText()); + break; + case "resourceType": + componentRow.setResourceType(data.getText()); + break; + case "version": + componentRow.setVersion(data.getText()); + break; + case "deleted": + componentRow.setIsDeleted(Boolean.parseBoolean(data.getText())); + break; + default: + break; + } } } if (isComponent) { @@ -189,47 +187,45 @@ public class GraphMLDataAnalyzer { return res; } - private List getComponentInstances(Document document) { - List res = new ArrayList<>(); - Element root = document.getRootElement(); - ElementFilter filter = new ElementFilter("graph"); - Element graph = root.getDescendants(filter).next(); - filter = new ElementFilter("node"); - IteratorIterable nodes = graph.getDescendants(filter); - filter = new ElementFilter("data"); - for (Element element : nodes) { - IteratorIterable dataNodes = element.getDescendants(filter); - ComponentInstanceRow componentInstRow = new ComponentInstanceRow(); + private List getComponentInstances(final Document document) { + final List res = new ArrayList<>(); + final Element root = document.getRootElement(); + final Element graph = (Element) root.elementIterator("graph").next(); + final Iterator nodes = graph.elementIterator("node"); + while (nodes.hasNext()) { + final Iterator dataNodes = nodes.next().elementIterator("data"); + final ComponentInstanceRow componentInstRow = new ComponentInstanceRow(); boolean isComponentInst = false; - for (Element data : dataNodes) { - String attributeValue = data.getAttributeValue("key"); - switch (attributeValue) { - case "nodeLabel": - String nodeLabel = data.getText(); - if ("resourceInstance".equals(nodeLabel)) { - isComponentInst = true; - } - break; - case "uid": - componentInstRow.setUniqueId(data.getText()); - break; - case "name": - componentInstRow.setName(data.getText()); - break; - case "originType": - componentInstRow.setOriginType(data.getText()); - break; - default: - break; + while (dataNodes.hasNext()) { + final Element data = dataNodes.next(); + final String attributeValue = data.attributeValue("key"); + if (StringUtils.isNotEmpty(attributeValue)) { + switch (attributeValue) { + case "nodeLabel": + final String nodeLabel = data.getText(); + if ("resourceInstance".equals(nodeLabel)) { + isComponentInst = true; + } + break; + case "uid": + componentInstRow.setUniqueId(data.getText()); + break; + case "name": + componentInstRow.setName(data.getText()); + break; + case "originType": + componentInstRow.setOriginType(data.getText()); + break; + default: + break; + } } } if (isComponentInst) { - // Assuming the uid is in standard form of - - // .. - String uniqueId = componentInstRow.getUniqueId(); + // Assuming the uid is in standard form of .. + final String uniqueId = componentInstRow.getUniqueId(); if (uniqueId != null) { - String[] split = uniqueId.split("\\."); + final String[] split = uniqueId.split("\\."); if (split.length == 3) { componentInstRow.setContainerUid(split[0]); componentInstRow.setOriginUid(split[1]); diff --git a/asdctool/src/test/java/org/openecomp/sdc/asdctool/impl/GraphMLDataAnalyzerTest.java b/asdctool/src/test/java/org/openecomp/sdc/asdctool/impl/GraphMLDataAnalyzerTest.java index c2a8a561d8..a3cb9ddfad 100644 --- a/asdctool/src/test/java/org/openecomp/sdc/asdctool/impl/GraphMLDataAnalyzerTest.java +++ b/asdctool/src/test/java/org/openecomp/sdc/asdctool/impl/GraphMLDataAnalyzerTest.java @@ -20,37 +20,37 @@ package org.openecomp.sdc.asdctool.impl; -import org.junit.Test; - -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.openecomp.sdc.asdctool.impl.GraphMLDataAnalyzer.EXCEL_EXTENSION; import static org.openecomp.sdc.asdctool.impl.GraphMLDataAnalyzer.GRAPH_ML_EXTENSION; -public class GraphMLDataAnalyzerTest { +import org.junit.jupiter.api.Test; + +class GraphMLDataAnalyzerTest { - public static final String FILE_NAME = "export"; + private static final String FILE_NAME = "export"; @Test - public void testAnalyzeGraphMLDataNoFile() { - String[] args = new String[]{"noExistFile"}; + void testAnalyzeGraphMLDataNoFile() { + final String[] args = new String[]{"noExistFile"}; // default test - GraphMLDataAnalyzer graph = new GraphMLDataAnalyzer(); - String result = graph.analyzeGraphMLData(args); + final GraphMLDataAnalyzer graph = new GraphMLDataAnalyzer(); + final String result = graph.analyzeGraphMLData(args); assertNull(result); } @Test - public void testAnalyzeGraphMLData() { - String path = getClass().getClassLoader().getResource(FILE_NAME + GRAPH_ML_EXTENSION).getPath(); - String[] args = new String[]{path}; + void testAnalyzeGraphMLData() { + final String path = getClass().getClassLoader().getResource(FILE_NAME + GRAPH_ML_EXTENSION).getPath(); + final String[] args = new String[]{path}; // default test - GraphMLDataAnalyzer graph = new GraphMLDataAnalyzer(); - String result = graph.analyzeGraphMLData(args); + final GraphMLDataAnalyzer graph = new GraphMLDataAnalyzer(); + final String result = graph.analyzeGraphMLData(args); assertNotNull(result); assertTrue(result.endsWith(EXCEL_EXTENSION)); -- cgit 1.2.3-korg