From ebb52995a5dcec5489e67bb6588e7ca71375bdf2 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Mon, 4 Jul 2016 07:10:07 -0400 Subject: [PATCH] converted hint analyzer to use an externalized configuration file to simplify the resolution of issue #522 --- .../dependencycheck/xml/hints/HintRule.java | 160 ++++++++++++++++++ .../dependencycheck/xml/hints/Hints.java | 75 ++++++++ .../xml/hints/VendorDuplicatingHintRule.java | 85 ++++++++++ .../resources/dependencycheck-base-hint.xml | 75 ++++++++ .../resources/schema/dependency-hint.1.0.xsd | 68 ++++++++ .../xml/hints/HintHandlerTest.java | 77 +++++++++ .../xml/hints/HintParserTest.java | 69 ++++++++ .../src/test/resources/hints.xml | 25 +++ 8 files changed, 634 insertions(+) create mode 100644 dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/hints/HintRule.java create mode 100644 dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/hints/Hints.java create mode 100644 dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/hints/VendorDuplicatingHintRule.java create mode 100644 dependency-check-core/src/main/resources/dependencycheck-base-hint.xml create mode 100644 dependency-check-core/src/main/resources/schema/dependency-hint.1.0.xsd create mode 100644 dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/hints/HintHandlerTest.java create mode 100644 dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/hints/HintParserTest.java create mode 100644 dependency-check-core/src/test/resources/hints.xml diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/hints/HintRule.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/hints/HintRule.java new file mode 100644 index 000000000..0ab10091d --- /dev/null +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/hints/HintRule.java @@ -0,0 +1,160 @@ +/* + * This file is part of dependency-check-core. + * + * 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. + * + * Copyright (c) 2016 Jeremy Long. All Rights Reserved. + */ +package org.owasp.dependencycheck.xml.hints; + +import java.util.ArrayList; +import java.util.List; +import org.owasp.dependencycheck.dependency.Confidence; +import org.owasp.dependencycheck.dependency.Evidence; +import org.owasp.dependencycheck.suppression.PropertyType; + +/** + * A collection of product and vendor evidence to match; if any evidence is + * matched the addVendor and addProduct evidence should be added to the + * dependency. + * + * @author Jeremy Long + */ +public class HintRule { + + /** + * The list of file names to match. + */ + private final List filenames = new ArrayList(); + + /** + * Adds the filename evidence to the collection. + * + * @param filename the filename to add + */ + public void addFilename(PropertyType filename) { + this.filenames.add(filename); + } + + /** + * Returns the list of filename evidence to match against. + * + * @return the list of filename evidence to match against + */ + public List getFilenames() { + return filenames; + } + /** + * The list of product evidence that is being matched. + */ + private final List givenProduct = new ArrayList(); + + /** + * Adds a given product to the list of evidence to matched. + * + * @param source the source of the evidence + * @param name the name of the evidence + * @param value the value of the evidence + * @param confidence the confidence of the evidence + */ + public void addGivenProduct(String source, String name, String value, Confidence confidence) { + givenProduct.add(new Evidence(source, name, value, confidence)); + } + + /** + * Get the value of givenProduct + * + * @return the value of givenProduct. + */ + public List getGivenProduct() { + return givenProduct; + } + + /** + * The list of vendor evidence that is being matched. + */ + private final List givenVendor = new ArrayList(); + + /** + * Adds a given vendors to the list of evidence to matched. + * + * @param source the source of the evidence + * @param name the name of the evidence + * @param value the value of the evidence + * @param confidence the confidence of the evidence + */ + public void addGivenVendor(String source, String name, String value, Confidence confidence) { + givenVendor.add(new Evidence(source, name, value, confidence)); + } + + /** + * Get the value of givenVendor. + * + * @return the value of givenVendor + */ + public List getGivenVendor() { + return givenVendor; + } + + /** + * The list of product evidence to add. + */ + private final List addProduct = new ArrayList(); + + /** + * Adds a given product to the list of evidence to add when matched. + * + * @param source the source of the evidence + * @param name the name of the evidence + * @param value the value of the evidence + * @param confidence the confidence of the evidence + */ + public void addAddProduct(String source, String name, String value, Confidence confidence) { + addProduct.add(new Evidence(source, name, value, confidence)); + } + + /** + * Get the value of addProduct. + * + * @return the value of addProduct + */ + public List getAddProduct() { + return addProduct; + } + + /** + * The list of vendor hints to add. + */ + private final List addVendor = new ArrayList(); + + /** + * Adds a given vendor to the list of evidence to add when matched. + * + * @param source the source of the evidence + * @param name the name of the evidence + * @param value the value of the evidence + * @param confidence the confidence of the evidence + */ + public void addAddVendor(String source, String name, String value, Confidence confidence) { + addVendor.add(new Evidence(source, name, value, confidence)); + } + + /** + * Get the value of addVendor. + * + * @return the value of addVendor + */ + public List getAddVendor() { + return addVendor; + } +} diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/hints/Hints.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/hints/Hints.java new file mode 100644 index 000000000..0240d2fc1 --- /dev/null +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/hints/Hints.java @@ -0,0 +1,75 @@ +/* + * This file is part of dependency-check-core. + * + * 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. + * + * Copyright (c) 2016 Jeremy Long. All Rights Reserved. + */ +package org.owasp.dependencycheck.xml.hints; + +import java.util.List; + +/** + * A collection of hint rules. + * + * @author Jeremy Long + */ +public class Hints { + + /** + * The list of hint rules. + */ + private List hintRules; + + /** + * Get the value of hintRules + * + * @return the value of hintRules + */ + public List getHintRules() { + return hintRules; + } + + /** + * Set the value of hintRules + * + * @param hintRules new value of hintRules + */ + public void setHintRules(List hintRules) { + this.hintRules = hintRules; + } + + /** + * The duplicating hint rules. + */ + private List vendorDuplicatingHintRules; + + /** + * Get the value of vendorDuplicatingHintRules + * + * @return the value of vendorDuplicatingHintRules + */ + public List getVendorDuplicatingHintRules() { + return vendorDuplicatingHintRules; + } + + /** + * Set the value of vendorDuplicatingHintRules + * + * @param vendorDuplicatingHintRules new value of vendorDuplicatingHintRules + */ + public void setVendorDuplicatingHintRules(List vendorDuplicatingHintRules) { + this.vendorDuplicatingHintRules = vendorDuplicatingHintRules; + } + +} diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/hints/VendorDuplicatingHintRule.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/hints/VendorDuplicatingHintRule.java new file mode 100644 index 000000000..51450fac3 --- /dev/null +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/hints/VendorDuplicatingHintRule.java @@ -0,0 +1,85 @@ +/* + * This file is part of dependency-check-core. + * + * 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. + * + * Copyright (c) 2016 Jeremy Long. All Rights Reserved. + */ +package org.owasp.dependencycheck.xml.hints; + +/** + * Used to duplicate vendor evidence within a collection. The intent is if any evidence + * is found in a collection that matches the value given the evidence will be + * duplicated and the value replaced with the value indicated. + * + * @author Jeremy Long + */ +public class VendorDuplicatingHintRule { + + /** + * Constructs a new duplicating rule. + * + * @param value the value to duplicate the evidence if found + * @param duplicate the value to replace within the duplicated evidence + */ + public VendorDuplicatingHintRule(String value, String duplicate) { + this.value = value; + this.duplicate = duplicate; + } + + /** + * The evidence value to duplicate if found. + */ + private String value; + + /** + * Get the value of value. + * + * @return the value of value + */ + public String getValue() { + return value; + } + + /** + * Set the value of value. + * + * @param value new value of value + */ + public void setValue(String value) { + this.value = value; + } + + /** + * The value to replace when duplicating the evidence. + */ + private String duplicate; + + /** + * Get the value of duplicate. + * + * @return the value of duplicate + */ + public String getDuplicate() { + return duplicate; + } + + /** + * Set the value of duplicate. + * + * @param duplicate new value of duplicate + */ + public void setDuplicate(String duplicate) { + this.duplicate = duplicate; + } +} diff --git a/dependency-check-core/src/main/resources/dependencycheck-base-hint.xml b/dependency-check-core/src/main/resources/dependencycheck-base-hint.xml new file mode 100644 index 000000000..4e1d870a6 --- /dev/null +++ b/dependency-check-core/src/main/resources/dependencycheck-base-hint.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dependency-check-core/src/main/resources/schema/dependency-hint.1.0.xsd b/dependency-check-core/src/main/resources/schema/dependency-hint.1.0.xsd new file mode 100644 index 000000000..9fa7afb27 --- /dev/null +++ b/dependency-check-core/src/main/resources/schema/dependency-hint.1.0.xsd @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/hints/HintHandlerTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/hints/HintHandlerTest.java new file mode 100644 index 000000000..dd71ebf4b --- /dev/null +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/hints/HintHandlerTest.java @@ -0,0 +1,77 @@ +/* + * This file is part of dependency-check-core. + * + * 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. + * + * Copyright (c) 2016 Jeremy Long. All Rights Reserved. + */ +package org.owasp.dependencycheck.xml.hints; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.UnsupportedEncodingException; +import java.util.List; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import org.junit.Test; +import static org.junit.Assert.*; +import org.owasp.dependencycheck.BaseTest; +import org.owasp.dependencycheck.suppression.SuppressionErrorHandler; +import org.owasp.dependencycheck.suppression.SuppressionHandler; +import org.owasp.dependencycheck.suppression.SuppressionParser; +import org.owasp.dependencycheck.suppression.SuppressionRule; +import org.xml.sax.Attributes; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.SAXNotRecognizedException; +import org.xml.sax.SAXNotSupportedException; +import org.xml.sax.XMLReader; + +/** + * + * @author Jeremy Long + */ +public class HintHandlerTest extends BaseTest { + + @Test + public void testHandler() throws ParserConfigurationException, SAXNotRecognizedException, SAXNotSupportedException, SAXException, FileNotFoundException, UnsupportedEncodingException, IOException { + File file = BaseTest.getResourceAsFile(this, "hints.xml"); + File schema = BaseTest.getResourceAsFile(this, "schema/dependency-hint.1.0.xsd"); + HintHandler handler = new HintHandler(); + + SAXParserFactory factory = SAXParserFactory.newInstance(); + factory.setNamespaceAware(true); + factory.setValidating(true); + SAXParser saxParser = factory.newSAXParser(); + saxParser.setProperty(HintParser.JAXP_SCHEMA_LANGUAGE, HintParser.W3C_XML_SCHEMA); + saxParser.setProperty(HintParser.JAXP_SCHEMA_SOURCE, schema); + XMLReader xmlReader = saxParser.getXMLReader(); + xmlReader.setErrorHandler(new HintErrorHandler()); + xmlReader.setContentHandler(handler); + + InputStream inputStream = new FileInputStream(file); + Reader reader = new InputStreamReader(inputStream, "UTF-8"); + InputSource in = new InputSource(reader); + xmlReader.parse(in); + + List result = handler.getHintRules(); + assertEquals("two hint rules should have been loaded",2,result.size()); + } + +} diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/hints/HintParserTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/hints/HintParserTest.java new file mode 100644 index 000000000..36e55e473 --- /dev/null +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/hints/HintParserTest.java @@ -0,0 +1,69 @@ +/* + * This file is part of dependency-check-core. + * + * 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. + * + * Copyright (c) 2016 Jeremy Long. All Rights Reserved. + */ +package org.owasp.dependencycheck.xml.hints; + +import java.io.File; +import java.io.InputStream; +import org.junit.Test; +import static org.junit.Assert.assertEquals; +import org.owasp.dependencycheck.BaseTest; + +/** + * + * @author Jeremy Long + */ +public class HintParserTest extends BaseTest { + + /** + * Test of parseHints method, of class HintParser. + */ + @Test + public void testParseHints_File() throws Exception { + File file = BaseTest.getResourceAsFile(this, "hints.xml"); + HintParser instance = new HintParser(); + Hints results = instance.parseHints(file); + assertEquals("Two duplicating hints should have been read", 2, results.getVendorDuplicatingHintRules().size()); + assertEquals("Two hint rules should have been read", 2, results.getHintRules().size()); + } + + /** + * Test of parseHints method, of class HintParser. + */ + @Test + public void testParseHints_InputStream() throws Exception { + InputStream ins = BaseTest.getResourceAsStream(this, "hints.xml"); + HintParser instance = new HintParser(); + Hints results = instance.parseHints(ins); + assertEquals("Two duplicating hints should have been read", 2, results.getVendorDuplicatingHintRules().size()); + assertEquals("Two hint rules should have been read", 2, results.getHintRules().size()); + assertEquals("One add product should have been read", 1, results.getHintRules().get(0).getAddProduct().size()); + assertEquals("One add vendor should have been read", 1, results.getHintRules().get(0).getAddVendor().size()); + assertEquals("Two file name should have been read", 2, results.getHintRules().get(1).getFilenames().size()); + + assertEquals("add product name not found", "add product name", results.getHintRules().get(0).getAddProduct().get(0).getName()); + assertEquals("add vendor name not found", "add vendor name", results.getHintRules().get(0).getAddVendor().get(0).getName()); + assertEquals("given product name not found", "given product name", results.getHintRules().get(0).getGivenProduct().get(0).getName()); + assertEquals("given vendor name not found", "given vendor name", results.getHintRules().get(0).getGivenVendor().get(0).getName()); + + assertEquals("spring file name not found", "spring", results.getHintRules().get(1).getFilenames().get(0).getValue()); + assertEquals("file name 1 should not be case sensitive", false, results.getHintRules().get(1).getFilenames().get(0).isCaseSensitive()); + assertEquals("file name 1 should not be a regex", false, results.getHintRules().get(1).getFilenames().get(0).isRegex()); + assertEquals("file name 2 should be case sensitive", true, results.getHintRules().get(1).getFilenames().get(1).isCaseSensitive()); + assertEquals("file name 2 should be a regex", true, results.getHintRules().get(1).getFilenames().get(1).isRegex()); + } +} diff --git a/dependency-check-core/src/test/resources/hints.xml b/dependency-check-core/src/test/resources/hints.xml new file mode 100644 index 000000000..000028414 --- /dev/null +++ b/dependency-check-core/src/test/resources/hints.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file