PHOENIX-4188 Disable inline-DTDs in Pherf XML records
Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/4004ed17 Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/4004ed17 Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/4004ed17 Branch: refs/heads/4.x-HBase-0.98 Commit: 4004ed17fd67c93e7d67f8c365740e01632597be Parents: 3aec050 Author: Josh Elser <els...@apache.org> Authored: Fri Sep 8 22:50:25 2017 -0400 Committer: Josh Elser <els...@apache.org> Committed: Tue Sep 12 13:50:53 2017 -0400 ---------------------------------------------------------------------- .../config/scenario/user_defined_scenario.xml | 4 +- phoenix-pherf/pom.xml | 4 + .../pherf/configuration/XMLConfigParser.java | 15 +- .../pherf/result/impl/XMLResultHandler.java | 17 +- .../phoenix/pherf/ConfigurationParserTest.java | 5 +- .../phoenix/pherf/XMLConfigParserTest.java | 53 ++ .../pherf/result/impl/XMLResultHandlerTest.java | 53 ++ .../resources/malicious_results_with_dtd.xml | 676 +++++++++++++++++++ .../scenario/malicious_scenario_with_dtd.xml | 48 ++ 9 files changed, 863 insertions(+), 12 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/4004ed17/phoenix-pherf/config/scenario/user_defined_scenario.xml ---------------------------------------------------------------------- diff --git a/phoenix-pherf/config/scenario/user_defined_scenario.xml b/phoenix-pherf/config/scenario/user_defined_scenario.xml index e54d76a..6435e29 100644 --- a/phoenix-pherf/config/scenario/user_defined_scenario.xml +++ b/phoenix-pherf/config/scenario/user_defined_scenario.xml @@ -82,7 +82,7 @@ <maxValue>2019-09-15 11:00:00.000</maxValue> </datavalue> <datavalue distribution="10"> - <value>2019-09-19 00:01:00</value> + <value>2019-09-19 00:01:00.000</value> </datavalue> <datavalue distribution="10"> <minValue>2019-09-22 00:01:00.000</minValue> @@ -131,4 +131,4 @@ </querySet> </scenario> </scenarios> -</datamodel> \ No newline at end of file +</datamodel> http://git-wip-us.apache.org/repos/asf/phoenix/blob/4004ed17/phoenix-pherf/pom.xml ---------------------------------------------------------------------- diff --git a/phoenix-pherf/pom.xml b/phoenix-pherf/pom.xml index 2b4641d..cd31fbd 100644 --- a/phoenix-pherf/pom.xml +++ b/phoenix-pherf/pom.xml @@ -219,6 +219,10 @@ <include>com.googlecode.java-diff-utils:diffutils</include> <include>org.apache.commons:commons-lang3</include> <include>org.apache.commons:commons-math3</include> + <include>commons-cli:commons-cli</include> + <include>joda-time:joda-time</include> + <include>org.apache.commons:commons-csv</include> + <include>commons-lang:commons-lang</include> </includes> </artifactSet> <filters> http://git-wip-us.apache.org/repos/asf/phoenix/blob/4004ed17/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/configuration/XMLConfigParser.java ---------------------------------------------------------------------- diff --git a/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/configuration/XMLConfigParser.java b/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/configuration/XMLConfigParser.java index 93dc94c..f3ec12f 100644 --- a/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/configuration/XMLConfigParser.java +++ b/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/configuration/XMLConfigParser.java @@ -29,6 +29,10 @@ import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.transform.stream.StreamSource; import org.apache.phoenix.pherf.PherfConstants; import org.apache.phoenix.pherf.exception.FileLoaderException; @@ -108,16 +112,19 @@ public class XMLConfigParser { * @param file Name of File * @return {@link org.apache.phoenix.pherf.configuration.DataModel} Returns DataModel from * XML configuration - * @throws JAXBException */ // TODO Remove static calls - public static DataModel readDataModel(Path file) throws JAXBException { + public static DataModel readDataModel(Path file) throws JAXBException, XMLStreamException { + XMLInputFactory xif = XMLInputFactory.newFactory(); + xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false); + xif.setProperty(XMLInputFactory.SUPPORT_DTD, false); JAXBContext jaxbContext = JAXBContext.newInstance(DataModel.class); Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); String fName = PherfConstants.RESOURCE_SCENARIO + "/" + file.getFileName().toString(); logger.info("Open config file: " + fName); - return (DataModel) jaxbUnmarshaller - .unmarshal(XMLConfigParser.class.getResourceAsStream(fName)); + XMLStreamReader xmlReader = xif.createXMLStreamReader( + new StreamSource(XMLConfigParser.class.getResourceAsStream(fName))); + return (DataModel) jaxbUnmarshaller.unmarshal(xmlReader); } // TODO Remove static calls http://git-wip-us.apache.org/repos/asf/phoenix/blob/4004ed17/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/result/impl/XMLResultHandler.java ---------------------------------------------------------------------- diff --git a/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/result/impl/XMLResultHandler.java b/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/result/impl/XMLResultHandler.java index 990c9be..05b5a2b 100644 --- a/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/result/impl/XMLResultHandler.java +++ b/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/result/impl/XMLResultHandler.java @@ -24,6 +24,10 @@ import org.apache.phoenix.pherf.result.file.ResultFileDetails; import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamReader; +import javax.xml.transform.stream.StreamSource; + import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -66,12 +70,19 @@ public class XMLResultHandler extends DefaultResultHandler{ @Override public synchronized List<Result> read() throws Exception { + return readFromResultFile(new File(resultFileName)); + } + List<Result> readFromResultFile(File resultsFile) throws Exception { + XMLInputFactory xif = XMLInputFactory.newFactory(); + xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false); + xif.setProperty(XMLInputFactory.SUPPORT_DTD, false); JAXBContext jaxbContext = JAXBContext.newInstance(DataModelResult.class); Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); - File XMLfile = new File(resultFileName); - List<ResultValue> resultValue = new ArrayList(); - resultValue.add(new ResultValue<>((DataModelResult) jaxbUnmarshaller.unmarshal(XMLfile))); + @SuppressWarnings("rawtypes") + List<ResultValue> resultValue = new ArrayList<>(); + XMLStreamReader xmlReader = xif.createXMLStreamReader(new StreamSource(resultsFile)); + resultValue.add(new ResultValue<>(jaxbUnmarshaller.unmarshal(xmlReader))); List<Result> results = new ArrayList<>(); results.add(new Result(ResultFileDetails.XML, null, resultValue)); return results; http://git-wip-us.apache.org/repos/asf/phoenix/blob/4004ed17/phoenix-pherf/src/test/java/org/apache/phoenix/pherf/ConfigurationParserTest.java ---------------------------------------------------------------------- diff --git a/phoenix-pherf/src/test/java/org/apache/phoenix/pherf/ConfigurationParserTest.java b/phoenix-pherf/src/test/java/org/apache/phoenix/pherf/ConfigurationParserTest.java index a5c908e..1f1006d 100644 --- a/phoenix-pherf/src/test/java/org/apache/phoenix/pherf/ConfigurationParserTest.java +++ b/phoenix-pherf/src/test/java/org/apache/phoenix/pherf/ConfigurationParserTest.java @@ -18,7 +18,6 @@ package org.apache.phoenix.pherf; -import java.net.URISyntaxException; import java.net.URL; import java.nio.file.Path; import java.nio.file.Paths; @@ -129,7 +128,7 @@ public class ConfigurationParserTest extends ResultBaseTest { return resourceUrl; } - private List<Scenario> getScenarios() throws URISyntaxException, JAXBException{ + private List<Scenario> getScenarios() throws Exception { DataModel data = getDataModel(); List<Scenario> scenarioList = data.getScenarios(); assertTrue("Could not load the scenarios from xml.", @@ -137,7 +136,7 @@ public class ConfigurationParserTest extends ResultBaseTest { return scenarioList; } - private DataModel getDataModel() throws URISyntaxException, JAXBException { + private DataModel getDataModel() throws Exception { Path resourcePath = Paths.get(getResourceUrl().toURI()); return XMLConfigParser.readDataModel(resourcePath); } http://git-wip-us.apache.org/repos/asf/phoenix/blob/4004ed17/phoenix-pherf/src/test/java/org/apache/phoenix/pherf/XMLConfigParserTest.java ---------------------------------------------------------------------- diff --git a/phoenix-pherf/src/test/java/org/apache/phoenix/pherf/XMLConfigParserTest.java b/phoenix-pherf/src/test/java/org/apache/phoenix/pherf/XMLConfigParserTest.java new file mode 100644 index 0000000..c5746f9 --- /dev/null +++ b/phoenix-pherf/src/test/java/org/apache/phoenix/pherf/XMLConfigParserTest.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you 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. + */ +package org.apache.phoenix.pherf; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.net.URL; +import java.nio.file.Path; +import java.nio.file.Paths; + +import javax.xml.bind.UnmarshalException; +import javax.xml.stream.XMLStreamException; + +import org.apache.phoenix.pherf.configuration.XMLConfigParser; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class XMLConfigParserTest { + private static final Logger LOG = LoggerFactory.getLogger(XMLConfigParserTest.class); + + @Test + public void testDTDInScenario() throws Exception { + URL scenarioUrl = XMLConfigParserTest.class.getResource("/scenario/malicious_scenario_with_dtd.xml"); + assertNotNull(scenarioUrl); + Path p = Paths.get(scenarioUrl.toURI()); + try { + XMLConfigParser.readDataModel(p); + fail("The scenario should have failed to parse because it contains a DTD"); + } catch (UnmarshalException e) { + // If we don't parse the DTD, the variable 'name' won't be defined in the XML + LOG.warn("Caught expected exception", e); + Throwable cause = e.getLinkedException(); + assertTrue("Cause was a " + cause.getClass(), cause instanceof XMLStreamException); + } + } +} http://git-wip-us.apache.org/repos/asf/phoenix/blob/4004ed17/phoenix-pherf/src/test/java/org/apache/phoenix/pherf/result/impl/XMLResultHandlerTest.java ---------------------------------------------------------------------- diff --git a/phoenix-pherf/src/test/java/org/apache/phoenix/pherf/result/impl/XMLResultHandlerTest.java b/phoenix-pherf/src/test/java/org/apache/phoenix/pherf/result/impl/XMLResultHandlerTest.java new file mode 100644 index 0000000..98c492f --- /dev/null +++ b/phoenix-pherf/src/test/java/org/apache/phoenix/pherf/result/impl/XMLResultHandlerTest.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you 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. + */ +package org.apache.phoenix.pherf.result.impl; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.File; +import java.net.URL; + +import javax.xml.bind.UnmarshalException; +import javax.xml.stream.XMLStreamException; + +import org.apache.phoenix.pherf.XMLConfigParserTest; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class XMLResultHandlerTest { + private static final Logger LOG = LoggerFactory.getLogger(XMLResultHandlerTest.class); + + @Test + public void testDTDInResults() throws Exception { + URL resultsUrl = XMLConfigParserTest.class.getResource("/malicious_results_with_dtd.xml"); + assertNotNull(resultsUrl); + File resultsFile = new File(resultsUrl.getFile()); + XMLResultHandler handler = new XMLResultHandler(); + try { + handler.readFromResultFile(resultsFile); + fail("Expected to see an exception parsing the results with a DTD"); + } catch (UnmarshalException e) { + // If we don't parse the DTD, the variable 'name' won't be defined in the XML + LOG.debug("Caught expected exception", e); + Throwable cause = e.getLinkedException(); + assertTrue("Cause was a " + cause.getClass(), cause instanceof XMLStreamException); + } + } +}