diff --git a/.gitignore b/.gitignore index b67401f2..ed3247b2 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ .project .java-version .keystore +.idea/ # Package Files # *.jar diff --git a/plugin/pom.xml b/plugin/pom.xml index 24592ada..5b43879c 100755 --- a/plugin/pom.xml +++ b/plugin/pom.xml @@ -143,6 +143,13 @@ 1.4.01 + + org.junit.jupiter + junit-jupiter + 5.8.0 + test + + diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/BenchmarkScore.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/BenchmarkScore.java index 2a5b0e3f..ea087336 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/BenchmarkScore.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/BenchmarkScore.java @@ -29,13 +29,9 @@ import java.io.SequenceInputStream; import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; -import java.nio.file.FileSystem; -import java.nio.file.FileSystems; import java.nio.file.Files; -import java.nio.file.NoSuchFileException; import java.nio.file.Path; import java.nio.file.Paths; -import java.nio.file.StandardCopyOption; import java.security.SecureRandom; import java.text.DecimalFormat; import java.util.ArrayList; @@ -44,11 +40,10 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; @@ -58,71 +53,13 @@ import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; -import org.json.JSONException; -import org.json.JSONObject; import org.owasp.benchmarkutils.helpers.Categories; import org.owasp.benchmarkutils.helpers.Category; import org.owasp.benchmarkutils.helpers.Utils; -import org.owasp.benchmarkutils.score.parsers.AcunetixReader; -import org.owasp.benchmarkutils.score.parsers.AppScanDynamicReader; -import org.owasp.benchmarkutils.score.parsers.AppScanDynamicReader2; -import org.owasp.benchmarkutils.score.parsers.AppScanSourceReader; -import org.owasp.benchmarkutils.score.parsers.AppScanSourceReader2; -import org.owasp.benchmarkutils.score.parsers.ArachniReader; -import org.owasp.benchmarkutils.score.parsers.BurpJsonReader; -import org.owasp.benchmarkutils.score.parsers.BurpReader; -import org.owasp.benchmarkutils.score.parsers.CASTAIPReader; -import org.owasp.benchmarkutils.score.parsers.CheckmarxESReader; -import org.owasp.benchmarkutils.score.parsers.CheckmarxIASTReader; -import org.owasp.benchmarkutils.score.parsers.CheckmarxReader; -import org.owasp.benchmarkutils.score.parsers.CodeQLReader; -import org.owasp.benchmarkutils.score.parsers.ContrastReader; -import org.owasp.benchmarkutils.score.parsers.CoverityReader; -import org.owasp.benchmarkutils.score.parsers.CrashtestReader; -import org.owasp.benchmarkutils.score.parsers.FaastReader; -import org.owasp.benchmarkutils.score.parsers.FindbugsReader; -import org.owasp.benchmarkutils.score.parsers.FortifyReader; -import org.owasp.benchmarkutils.score.parsers.FusionLiteInsightReader; -import org.owasp.benchmarkutils.score.parsers.HCLReader; -import org.owasp.benchmarkutils.score.parsers.HdivReader; -import org.owasp.benchmarkutils.score.parsers.HorusecReader; -import org.owasp.benchmarkutils.score.parsers.InsiderReader; -import org.owasp.benchmarkutils.score.parsers.JuliaReader; -import org.owasp.benchmarkutils.score.parsers.KiuwanReader; -import org.owasp.benchmarkutils.score.parsers.LGTMReader; -import org.owasp.benchmarkutils.score.parsers.NJSScanReader; -import org.owasp.benchmarkutils.score.parsers.NetsparkerReader; -import org.owasp.benchmarkutils.score.parsers.NoisyCricketReader; -import org.owasp.benchmarkutils.score.parsers.PMDReader; -import org.owasp.benchmarkutils.score.parsers.ParasoftReader; -import org.owasp.benchmarkutils.score.parsers.QualysWASReader; -import org.owasp.benchmarkutils.score.parsers.Rapid7Reader; import org.owasp.benchmarkutils.score.parsers.Reader; -import org.owasp.benchmarkutils.score.parsers.ReshiftReader; -import org.owasp.benchmarkutils.score.parsers.SeekerReader; -import org.owasp.benchmarkutils.score.parsers.SemgrepReader; -import org.owasp.benchmarkutils.score.parsers.ShiftLeftReader; -import org.owasp.benchmarkutils.score.parsers.ShiftLeftScanReader; -import org.owasp.benchmarkutils.score.parsers.SnappyTickReader; -import org.owasp.benchmarkutils.score.parsers.SonarQubeJsonReader; -import org.owasp.benchmarkutils.score.parsers.SonarQubeReader; -import org.owasp.benchmarkutils.score.parsers.SourceMeterReader; -import org.owasp.benchmarkutils.score.parsers.ThunderScanReader; -import org.owasp.benchmarkutils.score.parsers.VeracodeReader; -import org.owasp.benchmarkutils.score.parsers.VisualCodeGrepperReader; -import org.owasp.benchmarkutils.score.parsers.W3AFReader; -import org.owasp.benchmarkutils.score.parsers.WapitiJsonReader; -import org.owasp.benchmarkutils.score.parsers.WapitiReader; -import org.owasp.benchmarkutils.score.parsers.WebInspectReader; -import org.owasp.benchmarkutils.score.parsers.XanitizerReader; -import org.owasp.benchmarkutils.score.parsers.ZapJsonReader; -import org.owasp.benchmarkutils.score.parsers.ZapReader; import org.owasp.benchmarkutils.score.report.ScatterHome; import org.owasp.benchmarkutils.score.report.ScatterInterpretation; import org.owasp.benchmarkutils.score.report.ScatterVulns; -import org.w3c.dom.Document; -import org.w3c.dom.Node; -import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.yaml.snakeyaml.Yaml; @@ -378,7 +315,6 @@ public void execute() throws MojoExecutionException, MojoFailureException { * @param args - The command line arguments. */ public static void main(String[] args) { - if (!processCommandLineArgs(args)) { System.out.println("Error processing configuration for Scoring. Aborting."); System.exit(-1); @@ -914,274 +850,15 @@ private static Map calculateScores(TestSuiteResults } private static TestSuiteResults readActualResults(File fileToParse) throws Exception { - String filename = fileToParse.getName(); + ResultFile resultFile = new ResultFile(fileToParse); TestSuiteResults tr = null; - if (filename.endsWith(".csv")) { - String line1 = getLine(fileToParse, 0); - if (line1.contains("CheckerKey") && line1.contains("LastDetectionURL")) { - tr = new SeekerReader().parse(fileToParse); - } else if (line1.contains("CWE") && line1.contains("URL")) { - tr = new CheckmarxIASTReader().parse(fileToParse); - } else if (line1.contains("Reshift Report")) { - tr = new ReshiftReader().parse(fileToParse); - } else System.out.println("Error: No matching parser found for CSV file: " + filename); - } else if (filename.endsWith(".ozasmt")) { - tr = new AppScanSourceReader().parse(fileToParse); - } else if (filename.endsWith(".faast")) { - tr = new FaastReader().parse(fileToParse); - } else if (filename.endsWith(".json")) { - - String line2 = getLine(fileToParse, 1); - if (line2 != null && (line2.contains("Coverity") || line2.contains("formatVersion"))) { - tr = new CoverityReader().parse(fileToParse); - } else if (line2 != null && line2.contains("Vendor") && line2.contains("Checkmarx")) { - tr = new CheckmarxESReader().parse(fileToParse); - } else { // Handle JSON where we have to look for a specific node to identify the tool - // type - - String content = new String(Files.readAllBytes(Paths.get(fileToParse.getPath()))); - JSONObject jsonObj = new JSONObject(content); - - if (HorusecReader.isHorusecReport(jsonObj)) { - tr = new HorusecReader().parse(jsonObj); - } else if (InsiderReader.isInsiderReport(jsonObj)) { - tr = new InsiderReader().parse(jsonObj); - - // ShiftLeft Scan puts two JSON files into one, so we need to pass the raw file - // content - } else if (ShiftLeftScanReader.isShiftLeftScanReport(content)) { - tr = new ShiftLeftScanReader().parse(content); - } else if (WapitiJsonReader.isWapitiReport(jsonObj)) { - tr = WapitiJsonReader.parse(jsonObj); - } else if (ZapJsonReader.isZapReport(jsonObj)) { - tr = new ZapJsonReader().parse(jsonObj); - } else if (NJSScanReader.isNJSScanReport(jsonObj)) { - tr = NJSScanReader.parse(jsonObj); - - } else { - try { - jsonObj.getJSONArray( - "results"); // Throws JSONException if this Node not found. - tr = new SemgrepReader().parse(jsonObj); - } catch (JSONException e) { - - // Note: Each of the remaining try blocks is nested under the one above, but - // we shown them inline as they would get too deep otherwise - try { - // SonarQube has two different JSON formats, one for standard issues and - // another for 'hotspots' which are security issues. Both are handled by - // the same parser for SonarQube. - jsonObj.getJSONArray("issues"); - tr = new SonarQubeJsonReader().parse(fileToParse); - } catch (JSONException e2) { - - try { - jsonObj.getJSONArray("hotspots"); - tr = new SonarQubeJsonReader().parse(fileToParse); - } catch (JSONException e3) { - - try { - jsonObj.getJSONArray("issue_events"); - tr = new BurpJsonReader().parse(fileToParse); - - // This is the final catch that says we couldn't find a matching - // parser - } catch (JSONException e4) { - System.out.println( - "Error: No matching parser found for JSON file: " - + filename); - } - } // end catch SonarQubeJsonReader - hotspots - } // end catch SonarQubeJsonReader - issues - } // end catch SemgrepReader - } // end else - } - } else if (filename.endsWith(".sarif")) { - // CodeQL results and LGTM results both have the same extension .sarif - // But only the LGTM results have "semmle.sourceLanguage" as a key in ["run.properties"] + Optional reader = + Reader.allReaders().stream().filter(r -> r.canRead(resultFile)).findAny(); - try { - // So we simply try the LGTMReader first, and if that fails, we try CodeQL. - tr = - new LGTMReader() - .parse(fileToParse); // If "semmle.sourceLanguage" is available set - // the LGTMReader - } catch (JSONException e) { - tr = - new CodeQLReader() - .parse(fileToParse); // If "semmle.sourceLanguage" is not available - // set the CodeQLReader - } - } else if (filename.endsWith(".threadfix")) { - tr = new KiuwanReader().parse(fileToParse); - } else if (filename.endsWith(".txt")) { - String line1 = getLine(fileToParse, 0); - if (line1.startsWith("Possible ")) { - tr = new SourceMeterReader().parse(fileToParse); - } - } else if (filename.endsWith(".xml")) { - - // Handle XML results files where the 1st or 2nd line indicates the tool type - - String line1 = - getLine(fileToParse, 0); // line1 is frequently like: - String line2 = getLine(fileToParse, 1); - String line4; - - if (line2 != null && line2.startsWith(" ")) { - tr = new ThunderScanReader().parse(fileToParse); - } else if (line2 != null && line2.startsWith("")) { - tr = new SonarQubeReader().parse(fileToParse); - } else if (line1.contains(" -1) { - tr.setTool(tr.getToolName() + "-OnDemand"); - } - } finally { - br.close(); - } - } catch (NoSuchFileException e) { - // Do nothing if the filtertemplate.xml file doesn't exist in the .fpr archive - } finally { - outputFile.delete(); - } - } else if (filename.endsWith(".log")) { - - String line1 = getLine(fileToParse, 0); - // line1 contains: Starting Contrast (for Java) or contrast:contrastAgent (for Node) - if (line1 != null && line1.toLowerCase().contains(" contrast")) { - tr = new ContrastReader().parse(fileToParse); - } else System.out.println("Error: No matching parser found for .log file: " + filename); - } else if (filename.endsWith(".hcl")) { - tr = new HCLReader().parse(fileToParse); - } else if (filename.endsWith(".hlg")) { - tr = new HdivReader().parse(fileToParse); - } else if (filename.endsWith(".sl")) { - tr = new ShiftLeftReader().parse(fileToParse); - } else System.out.println("Error: No matching parser found for file: " + filename); + if (reader.isPresent()) { + tr = reader.get().parse(resultFile); + } // If we have results, see if the version # is in the results file name. if (tr != null) { @@ -1190,9 +867,9 @@ else if (filename.endsWith(".fpr")) { // 1.3.2661 in this example). // This code should also handle: Benchmark-1.1-Coverity-results-v1.3.2661.xml (where the // compute time '-6720' isn't specified) - int indexOfVersionMarker = filename.lastIndexOf("-v"); + int indexOfVersionMarker = resultFile.filename().lastIndexOf("-v"); if (indexOfVersionMarker != -1) { - String restOfFileName = filename.substring(indexOfVersionMarker + 2); + String restOfFileName = resultFile.filename().substring(indexOfVersionMarker + 2); int endIndex = restOfFileName.lastIndexOf('-'); if (endIndex == -1) endIndex = restOfFileName.lastIndexOf('.'); String version = restOfFileName.substring(0, endIndex); @@ -1203,53 +880,6 @@ else if (filename.endsWith(".fpr")) { return tr; } - /** - * Read the specified line of the provided file. If its blank, skip all blank lines until a - * non-blank line is found and return that. Return "" if no non-blank line is found from the - * specified line on. - * - * @return The first non-blank line in the file starting with the specified line. null if there - * aren't that many lines in the file. - */ - private static String getLine(File actual, int lineNum) { - - try (BufferedReader br = new BufferedReader(new FileReader(actual))) { - // Skip all the lines before the line # requested - String line = null; - for (int i = 0; i <= lineNum; i++) { - line = br.readLine(); - } - while (line != null && line.length() == 0) { // Skip empty lines - line = br.readLine(); - } - return line; - } catch (IOException e) { - return ""; - } - } - - /** - * Read through the provided file and return true if it contains the specified string. - * - * @return True if string found. False otherwise - */ - /* UNUSED - so commented out. - private static boolean fileContains(File actual, String value) { - - try (BufferedReader br = new BufferedReader(new FileReader(actual))) { - String line; - do { - line = br.readLine(); - if (line == null) return false; - if (line.contains(value)) return true; - } while (line != null); - } catch (IOException e) { - // Do nothing - } - return false; - } - */ - /** * Go through each expected result, and figure out if this tool actually passed or not. This * updates the expected results to reflect what passed/failed. @@ -1937,19 +1567,4 @@ private static void updateMenuTemplates(String toolmenu, String vulnmenu, File s public static String fullTestSuiteName(String suite) { return ("Benchmark".equals(suite) ? "OWASP Benchmark" : suite); } - - private static Document getXMLDocument(File f) throws Exception { - DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); - // Prevent XXE = Note, disabling DTDs entirely breaks the parsing of some XML files, like a - // Burp results file, so have to use the alternate defense. - // dbFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); - docBuilderFactory.setFeature( - "http://xml.org/sax/features/external-general-entities", false); - docBuilderFactory.setFeature( - "http://xml.org/sax/features/external-parameter-entities", false); - DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder(); - InputSource is = new InputSource(new FileInputStream(f)); - Document doc = docBuilder.parse(is); - return doc; - } } diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/CweNumber.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/CweNumber.java new file mode 100644 index 00000000..5d8d1fd8 --- /dev/null +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/CweNumber.java @@ -0,0 +1,162 @@ +/** + * OWASP Benchmark Project + * + *

This file is part of the Open Web Application Security Project (OWASP) Benchmark Project For + * details, please see https://owasp.org/www-project-benchmark/. + * + *

The OWASP Benchmark is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Foundation, version 2. + * + *

The OWASP Benchmark is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + *

This reader reads JSON reports from the Horusec open source tool at: + * https://github.com/ZupIT/horusec + * + * @author Sascha Knoop + * @created 2021 + */ +package org.owasp.benchmarkutils.score; + +public class CweNumber { + + /** CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal') */ + public static int PATH_TRAVERSAL = 22; + + /** + * CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command + * Injection') + */ + public static int COMMAND_INJECTION = 78; + + /** + * CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') + */ + public static int XSS = 79; + + /** + * CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection') + */ + public static int SQL_INJECTION = 89; + + /** + * CWE-90: Improper Neutralization of Special Elements used in an LDAP Query ('LDAP Injection') + */ + public static int LDAP_INJECTION = 90; + + /** + * CWE-113: Improper Neutralization of CRLF Sequences in HTTP Headers ('HTTP Response + * Splitting') + */ + public static int HTTP_RESPONSE_SPLITTING = 113; + + /** CWE-134: Use of Externally-Controlled Format String */ + public static int EXTERNALLY_CONTROLLED_STRING = 134; + + /** CWE-284: Improper Access Control */ + public static int IMPROPER_ACCESS_CONTROL = 284; + + /** CWE-327: Use of a Broken or Risky Cryptographic Algorithm */ + public static int BROKEN_CRYPTO = 327; + + /** CWE-328: Reversible One-Way Hash */ + public static int REVERSIBLE_HASH = 328; + + /** CWE-329: Generation of Predictable IV with CBC Mode */ + public static int STATIC_CRYPTO_INIT = 329; + + /** CWE-330: Use of Insufficiently Random Values */ + public static int WEAK_RANDOM = 330; + + /** CWE-352: Cross-Site Request Forgery (CSRF) */ + public static int CSRF = 352; + + /** CWE-382: J2EE Bad Practices: Use of System.exit() */ + public static int SYSTEM_EXIT = 382; + + /** CWE-395: Use of NullPointerException Catch to Detect NULL Pointer Dereference */ + public static int CATCHING_NULL_POINTER_EXCEPTION = 395; + + /** CWE-396: Declaration of Catch for Generic Exception */ + public static int CATCH_GENERIC_EXCEPTION = 396; + + /** CWE-397: Declaration of Throws for Generic Exception */ + public static int THROW_GENERIC_EXCEPTION = 397; + + /** CWE-478: Missing Default Case in Switch Statement */ + public static int MISSING_DEFAULT_CASE = 478; + + /** CWE-483: Incorrect Block Delimitation */ + public static int INCORRECT_BLOCK_DELIMITATION = 483; + + /** CWE-484: Omitted Break Statement in Switch */ + public static int OMITTED_BREAK = 484; + + /** CWE-493: Critical Public Variable Without Final Modifier */ + public static int PUBLIC_VAR_WITHOUT_FINAL = 493; + + /** CWE-500: Public Static Field Not Marked Final */ + public static int PUBLIC_STATIC_NOT_FINAL = 500; + + /** CWE-501: Trust Boundary Violation */ + public static int TRUST_BOUNDARY_VIOLATION = 501; + + /** CWE-502: Deserialization of Untrusted Data */ + public static int INSECURE_DESERIALIZATION = 502; + + /** CWE-523: Unprotected Transport of Credentials */ + public static int UNPROTECTED_CREDENTIALS_TRANSPORT = 523; + + /** CWE-532: Insertion of Sensitive Information into Log File */ + public static int SENSITIVE_LOGFILE = 532; + + /** CWE-572: Call to Thread run() instead of start() */ + public static int THREAD_WRONG_CALL = 572; + + /** CWE-580: clone() Method Without super.clone() */ + public static int CLONE_WITHOUT_SUPER_CLONE = 580; + + /** CWE-563: Assignment to Variable without Use */ + public static int UNUSED_VAR_ASSIGNMENT = 563; + + /** CWE-581: Object Model Violation: Just One of Equals and Hashcode Defined */ + public static int OBJECT_MODEL_VIOLATION = 581; + + /** CWE-583: finalize() Method Declared Public */ + public static int FINALIZE_DECLARED_PUBLIC = 583; + + /** CWE-584: Return Inside Finally Block */ + public static int RETURN_INSIDE_FINALLY = 584; + + /** CWE-595: Comparison of Object References Instead of Object Contents */ + public static int OBJECT_REFERENCE_COMPARISON = 595; + + /** CWE-611: Improper Restriction of XML External Entity Reference */ + public static int XML_ENTITIES = 611; + + /** CWE-614: Sensitive Cookie in HTTPS Session Without 'Secure' Attribute */ + public static int INSECURE_COOKIE = 614; + + /** CWE-643: Improper Neutralization of Data within XPath Expressions ('XPath Injection') */ + public static int XPATH_INJECTION = 643; + + /** + * CWE-649: Reliance on Obfuscation or Encryption of Security-Relevant Inputs without Integrity + * Checking + */ + public static int OBFUSCATION = 649; + + /** CWE-754: Improper Check for Unusual or Exceptional Conditions */ + public static int IMPROPER_CHECK_FOR_CONDITIONS = 754; + + /** CWE-783: Operator Precedence Logic Error */ + public static int OPERATOR_PRECEDENCE_LOGIC = 783; + + /** CWE-835: Loop with Unreachable Exit Condition ('Infinite Loop') */ + public static int LOOP_WITH_UNREACHABLE_EXIT = 835; + + /** CWE-1004: Sensitive Cookie Without 'HttpOnly' Flag */ + public static int COOKIE_WITHOUT_HTTPONLY = 1004; +} diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/ResultFile.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/ResultFile.java new file mode 100644 index 00000000..ad99740b --- /dev/null +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/ResultFile.java @@ -0,0 +1,178 @@ +package org.owasp.benchmarkutils.score; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.StringReader; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import org.json.JSONObject; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.xml.sax.InputSource; +import org.xml.sax.helpers.DefaultHandler; + +public class ResultFile { + private final byte[] rawContent; + private final String filename; + private final File originalFile; + private JSONObject contentAsJson; + private Document contentAsXml; + + public ResultFile(File fileToParse) throws IOException { + this(fileToParse, readFileContent(fileToParse)); + } + + public ResultFile(String filename, String content) throws IOException { + this(filename, content.getBytes()); + } + + public ResultFile(String filename, byte[] rawContent) throws IOException { + this(new File(filename), rawContent); + } + + public ResultFile(File fileToParse, byte[] rawContent) throws IOException { + this.rawContent = rawContent; + originalFile = fileToParse; + filename = originalFile.getName(); + parseJson(); + parseXml(); + } + + private String removeBom(byte[] rawContent) { + String s = new String(rawContent, StandardCharsets.UTF_8); + + if (s.startsWith("\uFEFF")) { + return s.substring(1); + } + + return s; + } + + private static byte[] readFileContent(File fileToParse) throws IOException { + return Files.readAllBytes(Paths.get(fileToParse.getPath())); + } + + private void parseJson() { + try { + contentAsJson = new JSONObject(removeBom(rawContent)); + } catch (Exception ignored) { + // No JSON + } + } + + private void parseXml() { + try { + DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); + // Prevent XXE = Note, disabling DTDs entirely breaks the parsing of some XML files, + // like a Burp results file, so have to use the alternate defense. + // dbFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + docBuilderFactory.setFeature( + "http://xml.org/sax/features/external-general-entities", false); + docBuilderFactory.setFeature( + "http://xml.org/sax/features/external-parameter-entities", false); + DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder(); + docBuilder.setErrorHandler(new DefaultHandler()); + InputSource is = new InputSource(new StringReader(this.content())); + this.contentAsXml = docBuilder.parse(is); + } catch (Exception ignored) { + // No XML + } + } + + public String filename() { + return filename; + } + + public boolean isJson() { + return contentAsJson != null; + } + + public boolean isXml() { + return contentAsXml != null; + } + + public JSONObject json() { + return contentAsJson; + } + + public String content() { + return removeBom(rawContent); + } + + public File file() { + return originalFile; + } + + /** + * Read the specified line of the provided file. Returns empty string if the given file does not + * have as many lines. + */ + public String line(int lineNum) { + List lines = Arrays.asList(removeBom(rawContent).split("\n")); + + if (lineNum >= lines.size()) { + return ""; + } + + return lines.get(lineNum); + } + + public List lines() { + return new ArrayList<>(); + } + + public Document xml() { + return contentAsXml; + } + + public Element xmlRootNode() { + return xml().getDocumentElement(); + } + + public String xmlRootNodeName() { + return isXml() ? xmlRootNode().getNodeName() : ""; + } + + /** + * Extracts a file from a packed ResultFile. + * + * @return + */ + public ResultFile extract(String zipPath) { + try (ZipInputStream zipIn = new ZipInputStream(new ByteArrayInputStream(rawContent))) { + ZipEntry entry = zipIn.getNextEntry(); + while (entry != null) { + if (entry.getName().equals(zipPath)) { + return readFileFromZip(zipPath, zipIn); + } + zipIn.closeEntry(); + entry = zipIn.getNextEntry(); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + + throw new RuntimeException("ZipFile does not contain " + zipPath); + } + + private ResultFile readFileFromZip(String zipPath, ZipInputStream zipIn) throws IOException { + try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) { + final byte[] buf = new byte[1024]; + int length; + while ((length = zipIn.read(buf, 0, buf.length)) >= 0) { + bos.write(buf, 0, length); + } + return new ResultFile(zipPath, bos.toByteArray()); + } + } +} diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/TestSuiteResults.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/TestSuiteResults.java index 36bd5121..64b7a5e0 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/TestSuiteResults.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/TestSuiteResults.java @@ -247,23 +247,6 @@ public void setTime(File f) { } } - // We had to create a custom method for Fortify since we extract the contents of the .fpr - // file out into a temp file whose name looks like this: - // Benchmark_1.1-Fortify-13121.fpr8111236727473243675.fvdl - - public void setFortifyTime(File f) { - String filename = f.getName(); - // to make the same as normal filenames, strip off the '.fvdl' at the end of the filename - filename = filename.substring(0, filename.lastIndexOf('.') - 1); - String time = filename.substring(filename.lastIndexOf('-') + 1, filename.lastIndexOf('.')); - try { - int seconds = Integer.parseInt(time); - this.setTime(formatTime(seconds * 1000)); - } catch (Exception e) { - this.setTime("Time not specified"); - } - } - /** * Get the total number of results for these TestResults. * diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/AcunetixReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/AcunetixReader.java index 34176ae7..90f3c247 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/AcunetixReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/AcunetixReader.java @@ -19,15 +19,24 @@ import java.util.List; import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.CweNumber; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; import org.w3c.dom.Node; public class AcunetixReader extends Reader { - public TestSuiteResults parse(Node root) throws Exception { + @Override + public boolean canRead(ResultFile resultFile) { + return resultFile.filename().endsWith(".xml") + && (resultFile.xmlRootNodeName().equals("ScanGroup") + || resultFile.xmlRootNodeName().equals("acunetix-360")); + } - if (root.getNodeName().equalsIgnoreCase("acunetix-360")) { + @Override + public TestSuiteResults parse(ResultFile resultFile) throws Exception { + if (resultFile.xmlRootNodeName().equalsIgnoreCase("acunetix-360")) { /* This is for the 2020 format that looks like: @@ -45,12 +54,12 @@ public TestSuiteResults parse(Node root) throws Exception { TestSuiteResults tr = new TestSuiteResults("Acunetix 360", true, TestSuiteResults.ToolType.DAST); - Node target = getNamedChild("target", root); + Node target = getNamedChild("target", resultFile.xmlRootNode()); String duration = getNamedChild("duration", target).getTextContent(); // duration format is: 01:57:21.2094646 tr.setTime(duration.substring(0, duration.lastIndexOf('.'))); - Node issues = getNamedChild("vulnerabilities", root); + Node issues = getNamedChild("vulnerabilities", resultFile.xmlRootNode()); List issueList = getNamedChildren("vulnerability", issues); for (Node issue : issueList) { @@ -65,7 +74,7 @@ public TestSuiteResults parse(Node root) throws Exception { } return tr; - } else if (root.getNodeName().equalsIgnoreCase("ScanGroup")) { + } else if (resultFile.xmlRootNodeName().equalsIgnoreCase("ScanGroup")) { // The following is for the legacy format that looks like so: @@ -87,7 +96,7 @@ public TestSuiteResults parse(Node root) throws Exception { */ TestSuiteResults tr = new TestSuiteResults("Acunetix WVS", true, TestSuiteResults.ToolType.DAST); - Node scan = getNamedChild("Scan", root); + Node scan = getNamedChild("Scan", resultFile.xmlRootNode()); String duration = getNamedChild("ScanTime", scan).getTextContent(); tr.setTime(duration); @@ -220,22 +229,22 @@ private TestCaseResult parseAcunetixReportItem(Node flaw) throws Exception { return null; } - private static int cweLookup(String cweNum) { + private int cweLookup(String cweNum) { if (cweNum == null || cweNum.isEmpty()) { System.out.println("ERROR: No CWE number supplied"); return 0000; } switch (cweNum) { case "22": - return 22; // path traversal + return CweNumber.PATH_TRAVERSAL; case "78": - return 78; // command injection + return CweNumber.COMMAND_INJECTION; case "79": - return 79; // xss + return CweNumber.XSS; case "89": - return 89; // sql injection + return CweNumber.SQL_INJECTION; case "614": - return 614; // insecure cookie use + return CweNumber.INSECURE_COOKIE; // switch left in case we ever need to map a reported cwe to the one expected by // Benchmark diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/AppScanDynamicReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/AppScanDynamicReader.java index 3d309080..12ac1d07 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/AppScanDynamicReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/AppScanDynamicReader.java @@ -21,14 +21,21 @@ import java.util.List; import java.util.Map; import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; import org.w3c.dom.Node; public class AppScanDynamicReader extends Reader { - public TestSuiteResults parse(Node root) throws Exception { + @Override + public boolean canRead(ResultFile resultFile) { + return resultFile.filename().endsWith(".xml") + && resultFile.xmlRootNodeName().equals("XmlReport"); + } + @Override + public TestSuiteResults parse(ResultFile resultFile) throws Exception { TestSuiteResults tr = new TestSuiteResults("HCL AppScan", true, TestSuiteResults.ToolType.DAST); @@ -37,14 +44,14 @@ public TestSuiteResults parse(Node root) throws Exception { // // - Node info = getNamedChild("AppScanInfo", root); + Node info = getNamedChild("AppScanInfo", resultFile.xmlRootNode()); Node version = getNamedChild("Version", info); tr.setToolVersion(version.getTextContent()); //

// 14:48:40.9394530 - Node summary = getNamedChild("Summary", root); + Node summary = getNamedChild("Summary", resultFile.xmlRootNode()); Node elapsed = getNamedChild("TotalScanDuration", summary); tr.setTime(calculateTime(elapsed.getTextContent())); @@ -88,7 +95,7 @@ public TestSuiteResults parse(Node root) throws Exception { // parse issue types list into cweMap Map cweMap = new HashMap(); - Node results = getNamedChild("Results", root); + Node results = getNamedChild("Results", resultFile.xmlRootNode()); Node issueTypes = getNamedChild("IssueTypes", results); List issueTypeList = getNamedChildren("IssueType", issueTypes); for (Node issueType : issueTypeList) { @@ -119,7 +126,7 @@ public TestSuiteResults parse(Node root) throws Exception { } // 14:48:40.9394530 - private static String calculateTime(String elapsed) { + private String calculateTime(String elapsed) { try { String[] splits = elapsed.split("[\\.:]"); int hours = Integer.parseInt(splits[0]); diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/AppScanDynamicReader2.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/AppScanDynamicReader2.java index 253ece14..9e7f0a54 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/AppScanDynamicReader2.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/AppScanDynamicReader2.java @@ -17,13 +17,14 @@ */ package org.owasp.benchmarkutils.score.parsers; -import java.io.File; -import java.io.FileInputStream; +import java.io.StringReader; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.CweNumber; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; import org.w3c.dom.Document; @@ -31,17 +32,24 @@ import org.w3c.dom.Node; import org.xml.sax.InputSource; +// This is the new AppScan Dynamic reader, where they generate ".xml" files. public class AppScanDynamicReader2 extends Reader { - // This is the new AppScan Dynamic reader, where they generate ".xml" files. - - public TestSuiteResults parse(File f) throws Exception { + @Override + public boolean canRead(ResultFile resultFile) { + return resultFile.filename().endsWith(".xml") + && resultFile.xmlRootNodeName().equals("xml-report") + && "AppScan Report".equals(getAttributeValue("name", resultFile.xmlRootNode())) + && "DAST".equals(getAttributeValue("technology", resultFile.xmlRootNode())); + } + @Override + public TestSuiteResults parse(ResultFile resultFile) throws Exception { DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); // Prevent XXE docBuilderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder(); - InputSource is = new InputSource(new FileInputStream(f)); + InputSource is = new InputSource(new StringReader(resultFile.content())); Document doc = docBuilder.parse(is); Node root = doc.getDocumentElement(); @@ -101,9 +109,9 @@ public TestSuiteResults parse(File f) throws Exception { } /// Issues which are not variants - private static TestCaseResult TestCaseLookup(String issueType, String url) { + private TestCaseResult TestCaseLookup(String issueType, String url) { TestCaseResult tcr = new TestCaseResult(); - String urlElements[] = url.split("/"); + String[] urlElements = url.split("/"); String testArea = urlElements[urlElements.length - 2].split("-")[0]; // .split strips off the -## @@ -139,9 +147,9 @@ private static TestCaseResult TestCaseLookup(String issueType, String url) { } // Fetch Issues listed as variants, to cater to post 10.x release xml format - private static List variantLookup( + private List variantLookup( String issueType, String itemID, String startingUrl, List variants) { - List testCaseElementsFromVariants = new ArrayList(); + List testCaseElementsFromVariants = new ArrayList<>(); // System.out.println("Variant Lookup Item ID: " + itemID); @@ -162,7 +170,7 @@ private static List variantLookup( String benchMarkTestCase = variantUrl[1].trim(); if (benchMarkTestCase.contains("BenchmarkTest")) { - String urlElements[] = benchMarkTestCase.split("/"); + String[] urlElements = benchMarkTestCase.split("/"); String testAreaUrl = startingUrl @@ -181,7 +189,7 @@ private static List variantLookup( return testCaseElementsFromVariants; } - private static int cweLookup(String vtype, String testArea) { + private int cweLookup(String vtype, String testArea) { int cwe = cweLookup(vtype); // Do the standard CWE lookup // Then map some to other CWEs based on the test area being processed. @@ -191,45 +199,45 @@ private static int cweLookup(String vtype, String testArea) { return cwe; } - private static int cweLookup(String vtype) { + private int cweLookup(String vtype) { switch (vtype) { case "attDirectoryFound": case "attDirOptions": case "attFileUnix": - return 22; + return CweNumber.PATH_TRAVERSAL; case "attApplicationRemoteCodeExecutionAdns": case "attCodeInjectionInSystemCall": case "attCommandInjectionAdns": case "attCommandInjectionUnixTws": case "attFileParamPipe": - return 78; + return CweNumber.COMMAND_INJECTION; case "attCrossSiteScripting": - return 79; + return CweNumber.XSS; case "attBlindSqlInjectionStrings": case "attSqlInjectionChecks": - return 89; + return CweNumber.SQL_INJECTION; case "attLDAPInjection": case "attLDAPInjection2": case "attBlindLDAPInjection": - return 90; + return CweNumber.LDAP_INJECTION; case "SHA1CipherSuites": - return 327; // Better if set to 327? + return CweNumber.REVERSIBLE_HASH; // Better if set to 327? case "passParamGET": - return 523; + return CweNumber.UNPROTECTED_CREDENTIALS_TRANSPORT; case "attRespCookieNotSecureSSL": - return 614; + return CweNumber.INSECURE_COOKIE; case "attXPathInjection": case "attBlindXpathInjectionSingleQuote": case "attBlindXPathInjection": - return 643; + return CweNumber.XPATH_INJECTION; // These don't map to anything we care about case "attContentSecurityPolicyObjectSrc": diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/AppScanSourceReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/AppScanSourceReader.java index 27a4fdab..c6875c41 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/AppScanSourceReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/AppScanSourceReader.java @@ -17,7 +17,6 @@ */ package org.owasp.benchmarkutils.score.parsers; -import java.io.File; import java.io.FileInputStream; import java.util.HashSet; import java.util.List; @@ -27,6 +26,8 @@ import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.CweNumber; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; import org.w3c.dom.Document; @@ -36,14 +37,20 @@ public class AppScanSourceReader extends Reader { - // This is the original AppScan Source reader, when they generated ".ozasmt" files. + @Override + public boolean canRead(ResultFile resultFile) { + return resultFile.filename().endsWith(".ozasmt"); + } - public TestSuiteResults parse(File f) throws Exception { + // This is the original AppScan Source reader, when they generated ".ozasmt" files. + @Override + public TestSuiteResults parse(ResultFile resultFile) throws Exception { DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); + // Prevent XXE docBuilderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder(); - InputSource is = new InputSource(new FileInputStream(f)); + InputSource is = new InputSource(new FileInputStream(resultFile.file())); Document doc = docBuilder.parse(is); Node root = doc.getDocumentElement(); @@ -136,40 +143,40 @@ private String parseTime(String message) { } } */ - private static int cweLookup(String vtype) { + private int cweLookup(String vtype) { switch (vtype) { // case "Vulnerability.AppDOS" : return 00; // case "Vulnerability.Authentication.Entity" : return 00; case "Vulnerability.Cryptography.InsecureAlgorithm": - return 327; + return CweNumber.STATIC_CRYPTO_INIT; case "Vulnerability.Cryptography.PoorEntropy": - return 330; + return CweNumber.WEAK_RANDOM; case "Vulnerability.Cryptography.????WeakHash": - return 328; // They don't have a weak hashing rule + return CweNumber.REVERSIBLE_HASH; // They don't have a weak hashing rule // case "Vulnerability.ErrorHandling.RevealDetails.Message" : return 00; // case "Vulnerability.ErrorHandling.RevealDetails.StackTrace" : return 00; case "Vulnerability.Injection.HttpResponseSplitting": - return 113; + return CweNumber.HTTP_RESPONSE_SPLITTING; case "Vulnerability.Injection.LDAP": - return 90; + return CweNumber.LDAP_INJECTION; case "Vulnerability.Injection.OS": - return 78; + return CweNumber.COMMAND_INJECTION; case "Vulnerability.Injection.SQL": - return 89; + return CweNumber.SQL_INJECTION; case "Vulnerability.Injection.XPath": - return 643; + return CweNumber.XPATH_INJECTION; // case "Vulnerability.Malicious.DynamicCode" : return 00; // case "Vulnerability.Malicious.DynamicCode.Execution" : return 00; case "Vulnerability.PathTraversal": - return 22; + return CweNumber.PATH_TRAVERSAL; // case "Vulnerability.Quality.TestCode" : return 00; // case "Vulnerability.Quality.Unsupported" : return 00; case "Vulnerability.SessionManagement.Cookies": - return 614; + return CweNumber.INSECURE_COOKIE; case "Vulnerability.Validation.EncodingRequired": - return 79; + return CweNumber.XSS; case "Vulnerability.Validation.Required": - return 501; + return CweNumber.TRUST_BOUNDARY_VIOLATION; } return 0; } diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/AppScanSourceReader2.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/AppScanSourceReader2.java index ae279f09..52a1edb5 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/AppScanSourceReader2.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/AppScanSourceReader2.java @@ -17,29 +17,39 @@ */ package org.owasp.benchmarkutils.score.parsers; -import java.io.File; +import static org.owasp.benchmarkutils.score.parsers.Reader.getAttributeValue; + import java.io.FileInputStream; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.CweNumber; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.xml.sax.InputSource; +// This is the new AppScan Source reader, where they generate ".xml" files. public class AppScanSourceReader2 extends Reader { - // This is the new AppScan Source reader, where they generate ".xml" files. - - public TestSuiteResults parse(File f) throws Exception { + @Override + public boolean canRead(ResultFile resultFile) { + return resultFile.filename().endsWith(".xml") + && resultFile.xmlRootNodeName().equals("xml-report") + && "AppScan Report".equals(getAttributeValue("name", resultFile.xmlRootNode())) + && "SAST".equals(getAttributeValue("technology", resultFile.xmlRootNode())); + } + @Override + public TestSuiteResults parse(ResultFile resultFile) throws Exception { DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); // Prevent XXE docBuilderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder(); - InputSource is = new InputSource(new FileInputStream(f)); + InputSource is = new InputSource(new FileInputStream(resultFile.file())); Document doc = docBuilder.parse(is); Node root = doc.getDocumentElement(); @@ -53,7 +63,7 @@ public TestSuiteResults parse(File f) throws Exception { // If the fliename includes an elapsed time in seconds (e.g., TOOLNAME-seconds.xml) set the // compute time on the scorecard. - tr.setTime(f); + tr.setTime(resultFile.file()); Node allIssues = getNamedChild("issue-group", root); List vulnerabilities = getNamedChildren("item", allIssues); @@ -144,49 +154,46 @@ else if (methodSig == null) return hours + ":" + mins + ":" + secs; } */ - private static int cweLookup(String vtype) { + private int cweLookup(String vtype) { switch (vtype) { // case "AppDOS" : return 00; // case "Authentication.Entity" : return 00; case "CrossSiteScripting": - return 79; + case "Validation.EncodingRequired": + return CweNumber.XSS; case "Cryptography.InsecureAlgorithm": - return 327; + return CweNumber.BROKEN_CRYPTO; case "Cryptography.PoorEntropy": - return 330; + return CweNumber.WEAK_RANDOM; // case "Cryptography.????WeakHash" : return 328; // They don't have a weak // hashing rule // case "ErrorHandling.RevealDetails.Message" : return 00; // case "ErrorHandling.RevealDetails.StackTrace" : return 00; case "Injection.HttpResponseSplitting": - return 113; + return CweNumber.HTTP_RESPONSE_SPLITTING; case "Injection.LDAP": - return 90; + return CweNumber.LDAP_INJECTION; case "Injection.OS": - return 78; + return CweNumber.COMMAND_INJECTION; case "Injection.SQL": - return 89; + return CweNumber.SQL_INJECTION; case "Injection.XPath": - return 643; + return CweNumber.XPATH_INJECTION; // case "Malicious.DynamicCode" : return 00; // case "Malicious.DynamicCode.Execution" : return 00; case "OpenSource": return 00; // Known vuln in open source lib. case "PathTraversal": - return 22; + return CweNumber.PATH_TRAVERSAL; // case "Quality.TestCode" : return 00; // case "Quality.Unsupported" : return 00; case "SessionManagement.Cookies": - return 614; - - case "Validation.EncodingRequired": - return 79; // XSS + return CweNumber.INSECURE_COOKIE; case "Validation.Required": - return 502; case "Validation.Required.WriteToStream": - return 502; + return CweNumber.INSECURE_DESERIALIZATION; default: System.out.println("Identified unknown type of: " + vtype); diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ArachniReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ArachniReader.java index 876c63c8..f7c9674f 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ArachniReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ArachniReader.java @@ -17,8 +17,7 @@ */ package org.owasp.benchmarkutils.score.parsers; -import java.io.File; -import java.io.FileInputStream; +import java.io.StringReader; import java.net.URI; import java.net.URISyntaxException; import java.text.SimpleDateFormat; @@ -26,6 +25,7 @@ import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; import org.w3c.dom.Document; @@ -34,6 +34,18 @@ public class ArachniReader extends Reader { + // 2015-08-17T14:21:14+03:00 + private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX"); + + @Override + public boolean canRead(ResultFile resultFile) { + return resultFile.filename().endsWith(".xml") + && resultFile.line(1).contains("Arachni") + && !resultFile + .xmlRootNodeName() + .equals("BugCollection"); // Ignore Find(Sec)Bugs files + } + // // 2.0dev @@ -41,12 +53,13 @@ public class ArachniReader extends Reader { // 2015-08-17T14:44:14+03:00 // - public TestSuiteResults parse(File f) throws Exception { + @Override + public TestSuiteResults parse(ResultFile resultFile) throws Exception { DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); // Prevent XXE docBuilderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder(); - InputSource is = new InputSource(new FileInputStream(f)); + InputSource is = new InputSource(new StringReader(resultFile.content())); Document doc = docBuilder.parse(is); TestSuiteResults tr = @@ -116,9 +129,6 @@ public TestSuiteResults parse(File f) throws Exception { // // - // 2015-08-17T14:21:14+03:00 - private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX"); - private String calculateTime(String submitted, String published) { try { long start = sdf.parse(submitted).getTime(); diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/BurpJsonReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/BurpJsonReader.java index 2b100482..71bfd564 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/BurpJsonReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/BurpJsonReader.java @@ -17,38 +17,31 @@ */ package org.owasp.benchmarkutils.score.parsers; -import java.io.File; -import java.nio.file.Files; -import java.nio.file.Paths; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; public class BurpJsonReader extends Reader { - public TestSuiteResults parse(File f) throws Exception { - String content = new String(Files.readAllBytes(Paths.get(f.getPath()))); + @Override + public boolean canRead(ResultFile resultFile) { + return resultFile.isJson() && resultFile.json().has("issue_events"); + } - JSONObject obj = new JSONObject(content); - JSONArray arr; - try { - arr = obj.getJSONArray("issue_events"); - } catch (JSONException e) { - System.out.println( - "ERROR: Couldn't find 'issue_events' element in Burp JSON results." - + " Maybe not a Burp JSON results file?"); - return null; - } + @Override + public TestSuiteResults parse(ResultFile resultFile) throws Exception { + JSONArray arr = resultFile.json().getJSONArray("issue_events"); TestSuiteResults tr = new TestSuiteResults("Burp Suite Enterprise", true, TestSuiteResults.ToolType.DAST); // If the filename includes an elapsed time in seconds (e.g., TOOLNAME-seconds.xml), // set the compute time on the score card. - tr.setTime(f); + tr.setTime(resultFile.file()); int numIssues = arr.length(); for (int i = 0; i < numIssues; i++) { @@ -87,7 +80,7 @@ public TestSuiteResults parse(File f) throws Exception { * Issued to:  OWASP BenchmarkIssued by:  OWASP BenchmarkValid from:  Mon Sep 28 19:39:43 CEST 2015Valid to:  Sun Dec 27 18:39:43 CET 2015 * * - * ", "caption": "/", "evidence": [], "internal_data": + *

", "caption": "/", "evidence": [], "internal_data": * "eyJmbGFncyI6MTQsInZhcmlhbnQiOjAsImlzc3VlX2RldGFpbHNfbWFwIjp7IjM0Ijoip09XQVNQIEJlbmNobWFya6dPV0FTUCBCZW5jaG1hcmunTW9uIFNlcCAyOCAxOTozOTo0MyBDRVNUIDIwMTWnU3VuIERlYyAyNyAxODozOTo0MyBDRVQgMjAxNacxNKcifX0=" * } }, ... */ diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/BurpReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/BurpReader.java index b54ecb05..65745f82 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/BurpReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/BurpReader.java @@ -17,33 +17,40 @@ */ package org.owasp.benchmarkutils.score.parsers; -import java.io.File; import java.util.List; import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.CweNumber; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; import org.w3c.dom.Node; public class BurpReader extends Reader { + @Override + public boolean canRead(ResultFile resultFile) { + return resultFile.filename().endsWith(".xml") + && resultFile.xmlRootNodeName().equals("issues"); + } + // filename passed in so we can extract the scan time if it is included in the filename // root of XML doc passed in so we can parse the results - public TestSuiteResults parse(File f, Node root) throws Exception { - + @Override + public TestSuiteResults parse(ResultFile resultFile) throws Exception { TestSuiteResults tr = new TestSuiteResults("Burp Suite Pro", true, TestSuiteResults.ToolType.DAST); // - String version = getAttributeValue("burpVersion", root); + String version = getAttributeValue("burpVersion", resultFile.xmlRootNode()); tr.setToolVersion(version); // If the filename includes an elapsed time in seconds (e.g., TOOLNAME-seconds.xml) set the // compute time on the scorecard. - tr.setTime(f); + tr.setTime(resultFile.file()); - List issueList = getNamedChildren("issue", root); + List issueList = getNamedChildren("issue", resultFile.xmlRootNode()); for (Node issue : issueList) { TestCaseResult tcr = parseBurpVulnerability(issue); @@ -97,6 +104,7 @@ private TestCaseResult parseBurpVulnerability(Node issue) { return null; } + // https://portswigger.net/kb/issues - This page lists all the issue types Burp looks for, and // their // customer ID #'s. There are more on this page. The following primarily lists those @@ -104,29 +112,25 @@ private TestCaseResult parseBurpVulnerability(Node issue) { static int cweLookup(String id) { switch (id) { case "1048832": - return 78; // Command Injection + return CweNumber.COMMAND_INJECTION; case "1049088": - return 89; // SQL Injection + return CweNumber.SQL_INJECTION; case "1049344": - return 22; // File Path Traversal + case "1051392": // File Path Manipulation - Not sure exact difference with 1049344 above + return CweNumber.PATH_TRAVERSAL; case "1049600": - return 611; // XXE + return CweNumber.XML_ENTITIES; case "1049856": - return 90; // LDAP Injection + return CweNumber.LDAP_INJECTION; case "1050112": - return 643; // XPATH Injection - case "1050368": - return 643; // XML Injection - Meaning what? - case "1051392": - return 22; // File Path Manipulation - Not sure exact difference with 1049344 above - case "2097408": - return 79; // Stored XSS - case "2097920": - return 79; // Reflected XSS - case "2097936": - return 79; // DOM-Based XSS (Probably want separate ID for this in the future) + case "1050368": // XML Injection - Meaning what? + return CweNumber.XPATH_INJECTION; + case "2097408": // Stored XSS + case "2097920": // Reflected XSS + case "2097936": // DOM-Based XSS (Probably want separate ID for this in the future) + return CweNumber.XSS; case "2098944": - return 352; // CSRF Vulnerability + return CweNumber.CSRF; case "3146240": return 918; // External service interaction (DNS) case "4194560": @@ -138,7 +142,7 @@ static int cweLookup(String id) { case "4197632": return 20; // Suspicious input transformation (reflected) case "5243392": - return 614; // SSL cookie without secure flag set + return CweNumber.INSECURE_COOKIE; case "5244416": return 9998; // Cookie without HttpOnly flag set - There is no CWE defined for this // weakness diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/CASTAIPReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/CASTAIPReader.java index 7c2fd5f4..ed38873d 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/CASTAIPReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/CASTAIPReader.java @@ -17,12 +17,13 @@ */ package org.owasp.benchmarkutils.score.parsers; -import java.io.File; -import java.io.FileInputStream; +import java.io.StringReader; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.CweNumber; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; import org.w3c.dom.Document; @@ -31,30 +32,25 @@ public class CASTAIPReader extends Reader { - public TestSuiteResults parse(File f) throws Exception { + @Override + public boolean canRead(ResultFile resultFile) { + return resultFile.filename().endsWith(".xml") + && resultFile.line(1).toLowerCase().startsWith(" - // - - // Only start time available in XML, per above. No stop time - // String duration = getNamedChild("timestamp", root ).getTextContent(); - // try { - // long millis = Long.parseLong(duration); - // tr.setTime( TestResults.formatTime( millis ) ); - // } catch( Exception e ) { - // tr.setTime( duration ); - // } - String version = getAttributeValue("version", root); if (version != null) { tr.setToolVersion(version); @@ -75,15 +71,6 @@ public TestSuiteResults parse(File f) throws Exception { return tr; } - // Issues look like this (all on one line) - // - // - // Avoid OS command injection vulnerabilities ( CWE-78 ) - private TestCaseResult parseCASTAIPIssue(Node flaw) throws Exception { TestCaseResult tcr = new TestCaseResult(); @@ -116,44 +103,43 @@ private TestCaseResult parseCASTAIPIssue(Node flaw) throws Exception { return null; } - private static int cweLookup(String name) { + private int cweLookup(String name) { if (name == null || name.isEmpty()) { return 0000; } switch (name.trim()) { case "614": - return 614; // insecure cookie use + return CweNumber.INSECURE_COOKIE; case "78": - return 78; // command injection + return CweNumber.COMMAND_INJECTION; case "79": - return 79; // xss + return CweNumber.XSS; case "89": - return 89; // sql injection + return CweNumber.SQL_INJECTION; case "90": - return 90; // ldap injection + return CweNumber.LDAP_INJECTION; // case "header-injection" : return 113; // header injection // case "hql-injection" : return 0000; // hql injection // case "unsafe-readline" : return 0000; // unsafe readline // case "reflection-injection" : return 0000; // reflection injection // case "reflected-xss" : return 79; // xss case "91": - return 643; // xpath injection - case "73": - return 22; // path traversal - This tool calls this CWE-73 "External Control of File + case "643": + return CweNumber.XPATH_INJECTION; + case "73": // This tool calls this CWE-73 "External Control of File" + case "22": + return CweNumber.PATH_TRAVERSAL; // Name or Path" // case "crypto-bad-mac" : return 328; // weak hash // case "crypto-weak-randomness" : return 330; // weak random // case "crypto-bad-ciphers" : return 327; // weak encryption case "501": - return 501; // trust boundary + return CweNumber.TRUST_BOUNDARY_VIOLATION; // case "xxe" : return 611; // xml entity case "134": - return 134; // Use of Externally-Controlled Format String - Which really isn't a - // Java vuln - case "22": - return 22; - case "643": - return 643; + return CweNumber + .EXTERNALLY_CONTROLLED_STRING; // Use of Externally-Controlled Format String + // - Which really isn't a default: System.out.println( "No matching CWE # found in CAST AIP Reader for: 'CWE-" + name + "'"); diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/CheckmarxESReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/CheckmarxESReader.java index 91db7cf0..8d75a0d4 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/CheckmarxESReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/CheckmarxESReader.java @@ -17,22 +17,29 @@ */ package org.owasp.benchmarkutils.score.parsers; -import java.io.File; -import java.nio.file.Files; -import java.nio.file.Paths; import org.json.JSONArray; import org.json.JSONObject; import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.CweNumber; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; public class CheckmarxESReader extends Reader { - public TestSuiteResults parse(File f) throws Exception { + + @Override + public boolean canRead(ResultFile resultFile) { + return resultFile.filename().endsWith(".json") + && resultFile.line(1).contains("Vendor") + && resultFile.line(1).contains("Checkmarx"); + } + + @Override + public TestSuiteResults parse(ResultFile resultFile) throws Exception { TestSuiteResults tr = new TestSuiteResults("Checkmarx SAST", true, TestSuiteResults.ToolType.SAST); - String content = new String(Files.readAllBytes(Paths.get(f.getPath()))); - JSONObject obj = new JSONObject(content); + JSONObject obj = resultFile.json(); // engine version String version = obj.getString("EngineVersion"); @@ -112,12 +119,12 @@ private boolean isIrrelevant(String name) { private int translate(int cwe) { switch (cwe) { case 77: - return 78; // command injection + return CweNumber.COMMAND_INJECTION; case 36: case 23: - return 22; // path traversal + return CweNumber.PATH_TRAVERSAL; case 338: - return 330; // weak random + return CweNumber.WEAK_RANDOM; } return cwe; } diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/CheckmarxIASTReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/CheckmarxIASTReader.java index 08c4135c..d80db1b3 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/CheckmarxIASTReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/CheckmarxIASTReader.java @@ -17,18 +17,66 @@ */ package org.owasp.benchmarkutils.score.parsers; -import java.io.File; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVRecord; import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; public class CheckmarxIASTReader extends Reader { - private static int cweLookup(String checkerKey) { + @Override + public boolean canRead(ResultFile resultFile) { + return resultFile.filename().endsWith(".csv") + && resultFile.line(0).contains("CWE") + && resultFile.line(0).contains("URL"); + } + + @Override + public TestSuiteResults parse(ResultFile resultFile) throws Exception { + TestSuiteResults tr = new TestSuiteResults("CxIAST", true, TestSuiteResults.ToolType.IAST); + + java.io.Reader inReader = new java.io.StringReader(resultFile.content()); + Iterable records = CSVFormat.RFC4180.withFirstRecordAsHeader().parse(inReader); + for (CSVRecord record : records) { + String checkerKey = record.get("Vulnerability Type"); + String url = record.get("URL"); + // System.out.println("URL = "+url); //For debugging YE + + TestCaseResult tcr = new TestCaseResult(); + tcr.setCategory(checkerKey); + tcr.setCWE(cweLookup(checkerKey)); + Pattern testCasePattern = + Pattern.compile( + BenchmarkScore.TESTCASENAME + + "[0-9]{" + + BenchmarkScore.TESTIDLENGTH + + "}"); + Matcher testCaseMatcher = testCasePattern.matcher(url); + if (testCaseMatcher.find()) { + String testCase = testCaseMatcher.group(0); + // System.out.println("testCase = "+testCase+" Test Num = + // "+testCase.substring(testCase.length()-Utils.TESTCASE_DIGITS, + // testCase.length())); // For debugging YE + tcr.setTestCaseName(testCase); + // BenchmarkTest00000 - BenchmarkTest99999 + tcr.setNumber( + Integer.parseInt( + testCase.substring( + testCase.length() - BenchmarkScore.TESTIDLENGTH))); + if (tcr.getCWE() != 0) { + tr.put(tcr); + } + } + } + tr.setTime("100"); + return tr; + } + + private int cweLookup(String checkerKey) { // checkerKey = checkerKey.replace("-SECOND-ORDER", ""); switch (checkerKey) { @@ -123,44 +171,4 @@ private static int cweLookup(String checkerKey) { } return 0; } - - public TestSuiteResults parse(File f) throws Exception { - TestSuiteResults tr = new TestSuiteResults("CxIAST", true, TestSuiteResults.ToolType.IAST); - - java.io.Reader inReader = new java.io.FileReader(f); - Iterable records = CSVFormat.RFC4180.withFirstRecordAsHeader().parse(inReader); - for (CSVRecord record : records) { - String checkerKey = record.get("Vulnerability Type"); - String url = record.get("URL"); - // System.out.println("URL = "+url); //For debugging YE - - TestCaseResult tcr = new TestCaseResult(); - tcr.setCategory(checkerKey); - tcr.setCWE(cweLookup(checkerKey)); - Pattern testCasePattern = - Pattern.compile( - BenchmarkScore.TESTCASENAME - + "[0-9]{" - + BenchmarkScore.TESTIDLENGTH - + "}"); - Matcher testCaseMatcher = testCasePattern.matcher(url); - if (testCaseMatcher.find()) { - String testCase = testCaseMatcher.group(0); - // System.out.println("testCase = "+testCase+" Test Num = - // "+testCase.substring(testCase.length()-Utils.TESTCASE_DIGITS, - // testCase.length())); // For debugging YE - tcr.setTestCaseName(testCase); - // BenchmarkTest00000 - BenchmarkTest99999 - tcr.setNumber( - Integer.parseInt( - testCase.substring( - testCase.length() - BenchmarkScore.TESTIDLENGTH))); - if (tcr.getCWE() != 0) { - tr.put(tcr); - } - } - } - tr.setTime("100"); - return tr; - } } diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/CheckmarxReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/CheckmarxReader.java index 6d3ef571..93f9c62c 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/CheckmarxReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/CheckmarxReader.java @@ -17,12 +17,12 @@ */ package org.owasp.benchmarkutils.score.parsers; -import java.io.File; -import java.io.FileInputStream; +import java.io.StringReader; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; import org.w3c.dom.Document; @@ -31,12 +31,19 @@ public class CheckmarxReader extends Reader { - public TestSuiteResults parse(File f) throws Exception { + @Override + public boolean canRead(ResultFile resultFile) { + return resultFile.filename().endsWith(".xml") + && resultFile.line(1).startsWith(" parseLGTMRules(JSONArray rulesJSON) { - HashMap rulesUsed = new HashMap(); for (int j = 0; j < rulesJSON.length(); j++) { diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ContrastReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ContrastReader.java index 5e697069..706d539d 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ContrastReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ContrastReader.java @@ -24,25 +24,35 @@ import java.util.Date; import org.json.JSONObject; import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; public class ContrastReader extends Reader { - private static final String NODEFINDINGLINEINDICATOR = "contrast:rules:sinks - "; - private static final String NODEAGENTVERSIONLINEINDICATOR = "contrast:contrast-init - agent v"; + private final String NODEFINDINGLINEINDICATOR = "contrast:rules:sinks - "; + private final String NODEAGENTVERSIONLINEINDICATOR = "contrast:contrast-init - agent v"; public static void main(String[] args) throws Exception { File f = new File("results/Benchmark_1.2-Contrast.log"); + ResultFile resultFile = new ResultFile(f); ContrastReader cr = new ContrastReader(); - cr.parse(f); + cr.parse(resultFile); } - public TestSuiteResults parse(File f) throws Exception { + @Override + public boolean canRead(ResultFile resultFile) { + // first line contains: Starting Contrast (for Java) or contrast:contrastAgent (for Node) + return resultFile.filename().endsWith(".log") + && resultFile.line(0).toLowerCase().contains(" contrast"); + } + + @Override + public TestSuiteResults parse(ResultFile resultFile) throws Exception { TestSuiteResults tr = new TestSuiteResults("Contrast", true, TestSuiteResults.ToolType.IAST); - BufferedReader reader = new BufferedReader(new FileReader(f)); + BufferedReader reader = new BufferedReader(new FileReader(resultFile.file())); String FIRSTLINEINDICATOR = BenchmarkScore.TESTCASENAME; String firstLine = null; String lastLine = ""; @@ -192,7 +202,7 @@ private void parseContrastJavaFinding(TestSuiteResults tr, String json) throws E } } - private static int cweLookup(String rule) { + private int cweLookup(String rule) { switch (rule) { case "cache-controls-missing": return 525; // Web Browser Cache Containing Sensitive Info diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/CoverityReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/CoverityReader.java index 2bbb4769..ba228fed 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/CoverityReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/CoverityReader.java @@ -17,21 +17,25 @@ */ package org.owasp.benchmarkutils.score.parsers; -import java.io.File; -import java.nio.file.Files; -import java.nio.file.Paths; import org.json.JSONArray; import org.json.JSONObject; import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; public class CoverityReader extends Reader { - public TestSuiteResults parse(File f) throws Exception { - String content = new String(Files.readAllBytes(Paths.get(f.getPath()))); + @Override + public boolean canRead(ResultFile resultFile) { + return resultFile.filename().endsWith(".json") + && (resultFile.line(1).contains("Coverity") + || resultFile.line(1).contains("formatVersion")); + } - JSONObject obj = new JSONObject(content); + @Override + public TestSuiteResults parse(ResultFile resultFile) throws Exception { + JSONObject obj = resultFile.json(); int version = obj.getInt("formatVersion"); String key = version > 1 ? "issues" : "mergedIssues"; @@ -43,9 +47,10 @@ public TestSuiteResults parse(File f) throws Exception { true, TestSuiteResults.ToolType .SAST); // Coverity's tool is called Code Advisor or Code Advisor On + // Demand // Fixme: See if we can figure this out from some of the files they provide - tr.setTime(f); + tr.setTime(resultFile.file()); for (int i = 0; i < arr.length(); i++) { TestCaseResult tcr = parseCoverityFinding(arr.getJSONObject(i), version); @@ -129,8 +134,8 @@ private TestCaseResult parseCoverityFinding(JSONObject finding, int version) { * * @param finding Coverity finding in JSON format that needs parsing * @return either a TestCaseResult object containing the finding details or - * null if the finding is not relevant (not in a test case) or of an unknown type - * (that is: not part of the test case definition) + * null if the finding is not relevant (not in a test case) or of an unknown type (that + * is: not part of the test case definition) */ private TestCaseResult parseCoverityFindingV2(JSONObject finding) { try { diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/CrashtestReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/CrashtestReader.java index 31d75f6f..1728f6aa 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/CrashtestReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/CrashtestReader.java @@ -17,7 +17,6 @@ */ package org.owasp.benchmarkutils.score.parsers; -import java.io.File; import java.io.FileInputStream; import java.net.URI; import java.net.URISyntaxException; @@ -25,6 +24,7 @@ import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; import org.w3c.dom.Document; @@ -33,6 +33,12 @@ public class CrashtestReader extends Reader { + @Override + public boolean canRead(ResultFile resultFile) { + return resultFile.filename().endsWith(".xml") + && resultFile.line(0).startsWith(" // @@ -40,12 +46,13 @@ public class CrashtestReader extends Reader { // - public TestSuiteResults parse(File f) throws Exception { + @Override + public TestSuiteResults parse(ResultFile resultFile) throws Exception { DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); // Prevent XXE docBuilderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder(); - InputSource is = new InputSource(new FileInputStream(f)); + InputSource is = new InputSource(new FileInputStream(resultFile.file())); Document doc = docBuilder.parse(is); TestSuiteResults tr = diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/FaastReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/FaastReader.java index 7f34cfa3..60aa100b 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/FaastReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/FaastReader.java @@ -17,24 +17,30 @@ */ package org.owasp.benchmarkutils.score.parsers; -import java.io.File; import java.nio.file.Files; import java.nio.file.Paths; import org.json.JSONArray; import org.json.JSONObject; import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; public class FaastReader extends Reader { - public TestSuiteResults parse(File f) throws Exception { - String content = new String(Files.readAllBytes(Paths.get(f.getPath()))); + @Override + public boolean canRead(ResultFile resultFile) { + return resultFile.filename().endsWith(".faast"); + } + + @Override + public TestSuiteResults parse(ResultFile resultFile) throws Exception { + String content = new String(Files.readAllBytes(Paths.get(resultFile.file().getPath()))); JSONArray obj = new JSONArray(content); TestSuiteResults tr = new TestSuiteResults( "Faast - Telefonica Cyber Security", true, TestSuiteResults.ToolType.DAST); - tr.setTime(f); + tr.setTime(resultFile.file()); for (int i = 0; i < obj.length(); i++) { TestCaseResult tcr = parseFaastFinding(obj.getJSONObject(i)); tr.put(tcr); diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/FindbugsReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/FindbugsReader.java index ef9f5675..ec7daeae 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/FindbugsReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/FindbugsReader.java @@ -17,11 +17,11 @@ */ package org.owasp.benchmarkutils.score.parsers; -import java.io.File; -import java.io.FileInputStream; +import java.io.StringReader; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; import org.w3c.dom.Document; @@ -30,17 +30,22 @@ import org.w3c.dom.NodeList; import org.xml.sax.InputSource; +// This reader supports both FindBugs and FindSecBugs, since the later is simply a FindBugs plugin. public class FindbugsReader extends Reader { - // This reader supports both FindBugs and FindSecBugs, since the later is simply a FindBugs - // plugin. + @Override + public boolean canRead(ResultFile resultFile) { + return resultFile.filename().endsWith(".xml") + && resultFile.line(1).startsWith(" -1) { + // tr.setTool(tr.getToolName() + "-OnDemand"); + // } + // } finally { + // br.close(); + // } + // } catch (NoSuchFileException e) { + // // Do nothing if the filtertemplate.xml file doesn't exist in the .fpr archive + // } finally { + // outputFile.delete(); + // } + + private TestCaseResult parseFortifyVulnerability(Node vuln) { TestCaseResult tcr = new TestCaseResult(); Node ci = getNamedNode("ClassInfo", vuln.getChildNodes()); @@ -159,24 +225,25 @@ private static TestCaseResult parseFortifyVulnerability(Node vuln) { return null; } - private static int cweLookup(String vtype, String subtype, Node unifiedNode) { + private int cweLookup(String vtype, String subtype, Node unifiedNode) { switch (vtype) { case "Access Control": - return 284; + return CweNumber.IMPROPER_ACCESS_CONTROL; case "Command Injection": - return 78; + return CweNumber.COMMAND_INJECTION; case "Cookie Security": { // Verify its the exact type we are looking for (e.g., not HttpOnly finding) - if ("Cookie not Sent Over SSL".equals(subtype)) return 614; + if ("Cookie not Sent Over SSL".equals(subtype)) + return CweNumber.INSECURE_COOKIE; else return 00; } case "Cross-Site Request Forgery": - return 352; + return CweNumber.CSRF; case "Cross-Site Scripting": { @@ -264,7 +331,7 @@ private static int cweLookup(String vtype, String subtype, Node unifiedNode) { return 99; case "SQL Injection": - return 89; + return CweNumber.SQL_INJECTION; case "System Information Leak": return 209; case "Trust Boundary Violation": diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/FusionLiteInsightReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/FusionLiteInsightReader.java index c3d58af5..9ab8dcf0 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/FusionLiteInsightReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/FusionLiteInsightReader.java @@ -20,7 +20,6 @@ */ package org.owasp.benchmarkutils.score.parsers; -import java.io.File; import java.io.FileInputStream; import java.net.URI; import java.net.URISyntaxException; @@ -28,6 +27,7 @@ import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; import org.w3c.dom.Document; @@ -36,12 +36,19 @@ public class FusionLiteInsightReader extends Reader { - public TestSuiteResults parse(File f) throws Exception { + @Override + public boolean canRead(ResultFile resultFile) { + return resultFile.filename().endsWith(".xml") + && resultFile.line(1).startsWith(" invalid = new HashSet<>(); + private final Set invalid = new HashSet<>(); + + @Override + public boolean canRead(ResultFile resultFile) { + return resultFile.filename().endsWith(".hlg"); + } public static void main(final String[] args) throws Exception { File f = new File("hdivAgentLog.hlg"); + ResultFile resultFile = new ResultFile(f); HdivReader cr = new HdivReader(); - System.out.println(cr.parse(f)); + System.out.println(cr.parse(resultFile)); } - public TestSuiteResults parse(final File f) throws Exception { + @Override + public TestSuiteResults parse(ResultFile resultFile) throws Exception { TestSuiteResults tr = new TestSuiteResults("Hdiv", true, TestSuiteResults.ToolType.IAST); - BufferedReader reader = new BufferedReader(new FileReader(f)); + BufferedReader reader = new BufferedReader(new StringReader(resultFile.content())); String firstLine = reader.readLine(); String lastLine = ""; String line = ""; diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/HorusecReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/HorusecReader.java index 0b46b0c4..cd4a1ae7 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/HorusecReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/HorusecReader.java @@ -26,25 +26,34 @@ import org.json.JSONArray; import org.json.JSONObject; import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.CweNumber; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; public class HorusecReader extends Reader { - public static boolean isHorusecReport(final JSONObject json) { + private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); + + @Override + public boolean canRead(ResultFile resultFile) { try { - return json.getJSONArray("analysisVulnerabilities") - .getJSONObject(0) - .getJSONObject("vulnerabilities") - .has("securityTool"); + return resultFile.isJson() + && resultFile + .json() + .getJSONArray("analysisVulnerabilities") + .getJSONObject(0) + .getJSONObject("vulnerabilities") + .has("securityTool"); } catch (Exception e) { return false; } } - private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); + @Override + public TestSuiteResults parse(ResultFile resultFile) throws Exception { + JSONObject json = resultFile.json(); - public TestSuiteResults parse(JSONObject json) throws Exception { TestSuiteResults tr = new TestSuiteResults("Horusec", false, TestSuiteResults.ToolType.SAST); @@ -73,7 +82,6 @@ private TestCaseResult parseTestCaseResult(JSONObject finding) { if (filename.contains(BenchmarkScore.TESTCASENAME)) { tcr.setNumber(testNumber(filename)); - tcr.setCWE(figureCwe(vuln)); } @@ -81,6 +89,7 @@ private TestCaseResult parseTestCaseResult(JSONObject finding) { } catch (Exception e) { e.printStackTrace(); } + return null; } @@ -95,32 +104,32 @@ private int figureCwe(JSONObject vuln) { switch (cwe) { case "79": - return 79; // xss + return CweNumber.XSS; case "89": - return 89; // sql injection + return CweNumber.SQL_INJECTION; case "326": case "327": - return 327; // Broken or Risky Cryptographic Algorithm + return CweNumber.BROKEN_CRYPTO; case "328": - return 328; // weak hash + return CweNumber.REVERSIBLE_HASH; case "329": - return 329; // static initialization vector for crypto + return CweNumber.STATIC_CRYPTO_INIT; case "330": - return 330; // weak random + return CweNumber.WEAK_RANDOM; case "502": if (category(details).equals("LDAP deserialization should be disabled")) { - return 90; // LDAP injection + return CweNumber.LDAP_INJECTION; } - return 502; // insecure deserialization + return CweNumber.INSECURE_DESERIALIZATION; case "611": - return 611; // xml entity + return CweNumber.XML_ENTITIES; case "614": - return 614; // insecure cookie use + return CweNumber.INSECURE_COOKIE; case "643": - return 643; // xpath injection + return CweNumber.XPATH_INJECTION; case "649": - return 649; // obfuscation + return CweNumber.OBFUSCATION; default: System.out.println( "INFO: Found following CWE which we haven't seen before: " + cwe); diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/InsiderReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/InsiderReader.java index d5c9d173..83a7ad29 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/InsiderReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/InsiderReader.java @@ -23,18 +23,22 @@ import org.json.JSONArray; import org.json.JSONObject; import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.CweNumber; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; -public class InsiderReader { +public class InsiderReader extends Reader { private static final String[] expectedVulnerabilityKeys = { "cvss", "cwe", "line", "class", "vul_id", "method", "column", "description" }; - public static boolean isInsiderReport(final JSONObject json) { + @Override + public boolean canRead(ResultFile resultFile) { try { - return hasExpectedKeys(json.getJSONArray("vulnerabilities").getJSONObject(0)); + return hasExpectedKeys( + resultFile.json().getJSONArray("vulnerabilities").getJSONObject(0)); } catch (Exception e) { return false; } @@ -50,11 +54,12 @@ private static boolean hasExpectedKeys(JSONObject vulnerability) { return true; } - public TestSuiteResults parse(JSONObject json) throws Exception { + @Override + public TestSuiteResults parse(ResultFile resultFile) throws Exception { TestSuiteResults tr = new TestSuiteResults("Insider", false, TestSuiteResults.ToolType.SAST); - JSONArray arr = json.getJSONArray("vulnerabilities"); + JSONArray arr = resultFile.json().getJSONArray("vulnerabilities"); for (int i = 0; i < arr.length(); i++) { TestCaseResult tcr = parseTestCaseResult(arr.getJSONObject(i)); @@ -91,14 +96,14 @@ private int cweNumber(JSONObject finding) { switch (cwe) { case "78": - return 78; // command injection + return CweNumber.COMMAND_INJECTION; case "326": case "327": - return 327; // weak encryption DES + return CweNumber.BROKEN_CRYPTO; case "330": - return 330; // weak random + return CweNumber.WEAK_RANDOM; case "532": - return 532; // sensitive log + return CweNumber.SENSITIVE_LOGFILE; default: System.out.println( diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/JuliaReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/JuliaReader.java index 2c7f3d8d..b03d2e13 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/JuliaReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/JuliaReader.java @@ -17,11 +17,11 @@ */ package org.owasp.benchmarkutils.score.parsers; -import java.io.File; -import java.io.FileInputStream; +import java.io.StringReader; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; import org.w3c.dom.Document; @@ -31,12 +31,25 @@ public class JuliaReader extends Reader { - public TestSuiteResults parse(File f) throws Exception { + // refactoring resilient + // TODO: Update to handle package paths from other test suites + private final String prefixOfTest = + "org.owasp.benchmark.testcode." + BenchmarkScore.TESTCASENAME; + + @Override + public boolean canRead(ResultFile resultFile) { + return resultFile.filename().endsWith(".xml") + && (resultFile.line(1).startsWith(" prettyjson.txt */ - JSONObject obj = new JSONObject(content); + JSONObject obj = resultFile.json(); // String resultsFormatVersion = obj.getString( "version" ); // Note: no threadfix version // info included in format. diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/LGTMReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/LGTMReader.java index 7894add7..72870d42 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/LGTMReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/LGTMReader.java @@ -17,35 +17,50 @@ */ package org.owasp.benchmarkutils.score.parsers; -import java.io.File; -import java.nio.file.Files; -import java.nio.file.Paths; import java.util.HashMap; import org.json.JSONArray; import org.json.JSONObject; import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; public class LGTMReader extends Reader { - public TestSuiteResults parse(File f) throws Exception { - String content = new String(Files.readAllBytes(Paths.get(f.getPath()))); + private final String LGTMCWEPREFIX = "external/cwe/cwe-"; + private final int LGTMCWEPREFIXLENGTH = LGTMCWEPREFIX.length(); + @Override + public boolean canRead(ResultFile resultFile) { + try { + return resultFile.filename().endsWith(".sarif") + && resultFile.isJson() + && resultFile + .json() + .getJSONArray("runs") + .getJSONObject(0) + .getJSONObject("properties") + .has("semmle.sourceLanguage"); + } catch (Exception e) { + return false; + } + } + + @Override + public TestSuiteResults parse(ResultFile resultFile) throws Exception { /* * This parser was written against version 2.1.0 of the sarif-schema * NOTE: To help understand contents of JSON file, use: http://jsonviewer.stack.hu to view it. */ - JSONObject obj = new JSONObject(content); // String resultsFormatVersion = obj.getString( "version" ); // Might be needed in future // if format changes - JSONArray runs = obj.getJSONArray("runs"); + JSONArray runs = resultFile.json().getJSONArray("runs"); TestSuiteResults tr = new TestSuiteResults("LGTM", true, TestSuiteResults.ToolType.SAST); // Scan time is not included in the sarif-schema. But scan time is provided on their web // site next to results - tr.setTime(f); // This grabs the scan time out of the filename, if provided + tr.setTime(resultFile.file()); // This grabs the scan time out of the filename, if provided // e.g., Benchmark_1.2_LGTM-660.sarif, means the scan took 660 seconds. for (int i = 0; i < runs.length(); i++) { @@ -85,11 +100,7 @@ public TestSuiteResults parse(File f) throws Exception { return tr; } - private static final String LGTMCWEPREFIX = "external/cwe/cwe-"; - private static final int LGTMCWEPREFIXLENGTH = LGTMCWEPREFIX.length(); - private HashMap parseLGTMRules(JSONArray rulesJSON) { - HashMap rulesUsed = new HashMap(); for (int j = 0; j < rulesJSON.length(); j++) { diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/NJSScanReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/NJSScanReader.java index 65a2dd9c..a844d7a1 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/NJSScanReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/NJSScanReader.java @@ -22,11 +22,12 @@ import org.json.JSONException; import org.json.JSONObject; import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; /** - * Class with static methods to read from the results of njsscan and place them in the conforming + * Class with methods to read from the results of njsscan and place them in the conforming * TestSuiteResults. See: https://github.com/ajinabraham/njsscan */ public class NJSScanReader extends Reader { @@ -34,13 +35,13 @@ public class NJSScanReader extends Reader { /** * Searches for the key "njsscan_version" in the given json object * - * @param json The json object to search the key for + * @param resultFile The result file to search the key for * @return True if "njsscan_version" is present, false otherwise */ - public static boolean isNJSScanReport(JSONObject json) { + @Override + public boolean canRead(ResultFile resultFile) { try { - json.getString("njsscan_version"); - return true; + return resultFile.isJson() && resultFile.json().has("njsscan_version"); } catch (JSONException jsonE) { return false; } @@ -51,10 +52,11 @@ public static boolean isNJSScanReport(JSONObject json) { * that the JSONObject supplied is a njsscan report using the function * NJSScanReader.isNJSScanReport(json) * - * @param json The JSONObject generated from a njsscan report + * @param resultFile The ResultFile containing the JSONObject generated from a njsscan report * @return A TestSuiteResults object containing a mapping of test cases */ - public static TestSuiteResults parse(JSONObject json) { + @Override + public TestSuiteResults parse(ResultFile resultFile) throws Exception { JSONObject cwe_object; TestSuiteResults tsrs = @@ -62,11 +64,11 @@ public static TestSuiteResults parse(JSONObject json) { try { // "njsscan_version" holds the version of the program - String njsscan_version = json.getString("njsscan_version"); + String njsscan_version = resultFile.json().getString("njsscan_version"); tsrs.setToolVersion(njsscan_version); // "nodejs" holds a dictionary of all the encountered cwes - cwe_object = json.getJSONObject("nodejs"); + cwe_object = resultFile.json().getJSONObject("nodejs"); String[] cwes = JSONObject.getNames(cwe_object); // Iterate through all CWEs and process them @@ -133,7 +135,7 @@ public static TestSuiteResults parse(JSONObject json) { * @param issue The JSONObject which contains the "files" and "metadata" key * @return Array of TestCaseResult all for the same CWE */ - private static TestCaseResult[] parseCWE(JSONObject CWE) { + private TestCaseResult[] parseCWE(JSONObject CWE) { List results = new ArrayList(); try { @@ -180,7 +182,7 @@ private static TestCaseResult[] parseCWE(JSONObject CWE) { * @return A TestCaseResult with the information from the file or null if finding is not in a * test case source file */ - private static TestCaseResult produceTestCaseResult(JSONObject file, int cwe_identifier) { + private TestCaseResult produceTestCaseResult(JSONObject file, int cwe_identifier) { TestCaseResult tcr = new TestCaseResult(); tcr.setCWE(cwe_identifier); @@ -211,7 +213,7 @@ private static TestCaseResult produceTestCaseResult(JSONObject file, int cwe_ide return tcr; } - private static int cweLookup(int cwe) { + private int cweLookup(int cwe) { switch (cwe) { case 23: // Relative Path Traversal <-- care about this one return 22; // We expect 22, not 23 diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/NetsparkerReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/NetsparkerReader.java index 69e4ca32..310e2dc8 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/NetsparkerReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/NetsparkerReader.java @@ -19,22 +19,26 @@ import java.util.List; import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.CweNumber; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; import org.w3c.dom.Node; public class NetsparkerReader extends Reader { - public TestSuiteResults parse(Node root) throws Exception { + @Override + public boolean canRead(ResultFile resultFile) { + return resultFile.filename().endsWith(".xml") + && resultFile.xmlRootNodeName().equals("netsparker"); + } + + @Override + public TestSuiteResults parse(ResultFile resultFile) throws Exception { TestSuiteResults tr = new TestSuiteResults("Netsparker", true, TestSuiteResults.ToolType.DAST); - Node target = getNamedChild("target", root); - - // - // https://localhost:8443/benchmark/ - // 211116 - // + Node target = getNamedChild("target", resultFile.xmlRootNode()); String duration = getNamedChild("scantime", target).getTextContent(); try { @@ -44,11 +48,7 @@ public TestSuiteResults parse(Node root) throws Exception { tr.setTime(duration); } - // No version information in XML - // String version = getNamedChild("TBD", root ).getTextContent(); - // tr.setToolVersion( version ); - - List issueList = getNamedChildren("vulnerability", root); + List issueList = getNamedChildren("vulnerability", resultFile.xmlRootNode()); for (Node issue : issueList) { try { @@ -63,31 +63,7 @@ public TestSuiteResults parse(Node root) throws Exception { return tr; } - // - // - // https://localhost:8443/benchmark/securecookie-00/BenchmarkTest00087?BenchmarkTest00087=whatever - // CookieNotMarkedAsSecure - // Important - // 100 - // - // - // - // - // - // - // A9 - // A6 - // 15 - // 614 - // 102 - // 6.5.4 - // 6.5.10 - // 6.5.10 - // - // - // - - private TestCaseResult parseNetsparkerIssue(Node flaw) throws Exception { + private TestCaseResult parseNetsparkerIssue(Node flaw) { TestCaseResult tcr = new TestCaseResult(); String type = getNamedChild("type", flaw).getTextContent(); @@ -103,10 +79,8 @@ private TestCaseResult parseNetsparkerIssue(Node flaw) throws Exception { String evidence = getAttributeValue("name", info); tcr.setEvidence(severity + "::" + evidence); - // Low - // 90 - Node classification = getNamedChild("classification", flaw); + // Note: not all vulnerabilities have CWEs in Netsparker if (classification != null) { Node vulnId = getNamedChild("CWE", classification); @@ -138,14 +112,14 @@ private TestCaseResult parseNetsparkerIssue(Node flaw) throws Exception { return null; } - private static int cweLookup(String cweNum) { + private int cweLookup(String cweNum) { if (cweNum == null || cweNum.isEmpty()) { return 0000; } int cwe = Integer.parseInt(cweNum); switch (cwe) { case 80: - return 614; // insecure cookie use + return CweNumber.INSECURE_COOKIE; // insecure cookie use // case "insecure-cookie" : return 614; // insecure cookie use // case "sql-injection" : return 89; // sql injection // case "cmd-injection" : return 78; // command injection diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/NoisyCricketReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/NoisyCricketReader.java index 4c34289f..c39fb555 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/NoisyCricketReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/NoisyCricketReader.java @@ -19,20 +19,28 @@ import java.util.List; import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; import org.w3c.dom.Node; public class NoisyCricketReader extends Reader { - public TestSuiteResults parse(Node root) throws Exception { + @Override + public boolean canRead(ResultFile resultFile) { + return resultFile.filename().endsWith(".xml") + && resultFile.xmlRootNodeName().equals("noisycricket"); + } + + @Override + public TestSuiteResults parse(ResultFile resultFile) throws Exception { TestSuiteResults tr = new TestSuiteResults("NoisyCricket", false, TestSuiteResults.ToolType.SAST); tr.setTime("1 minute"); - Node meta = getNamedChild("meta", root); + Node meta = getNamedChild("meta", resultFile.xmlRootNode()); tr.setToolVersion(getAttributeValue("version", meta)); - Node vulns = getNamedChild("vulnerabilities", root); + Node vulns = getNamedChild("vulnerabilities", resultFile.xmlRootNode()); List items = getNamedChildren("vulnerability", vulns); for (Node item : items) { try { @@ -69,6 +77,5 @@ private void parseNoisyCricketIssue(Node item, TestSuiteResults tr) { tr.put(tcr); } } - return; } } diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/PMDReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/PMDReader.java index 98e6624a..10654651 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/PMDReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/PMDReader.java @@ -17,13 +17,13 @@ */ package org.owasp.benchmarkutils.score.parsers; -import java.io.File; import java.io.FileInputStream; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; import org.w3c.dom.Document; @@ -33,19 +33,25 @@ public class PMDReader extends Reader { - public TestSuiteResults parse(File f) throws Exception { + @Override + public boolean canRead(ResultFile resultFile) { + return resultFile.filename().endsWith(".xml") && resultFile.line(1).startsWith(" parsePMDItem(Node fileNode) { - List results = new ArrayList(); String filename = fileNode.getAttributes().getNamedItem("name").getNodeValue(); @@ -102,7 +107,7 @@ private List parsePMDItem(Node fileNode) { return results; } - private static int figureCWE(String rule) { + private int figureCWE(String rule) { switch (rule) { case "AvoidUsingOctalValues": case "CollapsibleIfStatements": diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ParasoftReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ParasoftReader.java index 77450830..9da70bc3 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ParasoftReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ParasoftReader.java @@ -17,12 +17,13 @@ */ package org.owasp.benchmarkutils.score.parsers; -import java.io.File; -import java.io.FileInputStream; +import java.io.StringReader; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.CweNumber; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; import org.w3c.dom.Document; @@ -32,12 +33,19 @@ public class ParasoftReader extends Reader { - public TestSuiteResults parse(File f) throws Exception { + @Override + public boolean canRead(ResultFile resultFile) { + return resultFile.filename().endsWith(".xml") + && resultFile.line(1).startsWith(" @@ -59,7 +63,7 @@ public TestSuiteResults parse(File f, Node root) throws Exception { // // - List appendix = getNamedChildren("APPENDIX", root); + List appendix = getNamedChildren("APPENDIX", resultFile.xmlRootNode()); List scanList = getNamedChildren("SCAN_LIST", appendix); List scan = getNamedChildren("SCAN", scanList); @@ -94,7 +98,7 @@ public TestSuiteResults parse(File f, Node root) throws Exception { // false // - List resultsList = getNamedChildren("RESULTS", root); + List resultsList = getNamedChildren("RESULTS", resultFile.xmlRootNode()); List vulnerabilityList = getNamedChildren("VULNERABILITY_LIST", resultsList); List issueList = getNamedChildren("VULNERABILITY", vulnerabilityList); diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/Rapid7Reader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/Rapid7Reader.java index dd1b98bd..2d256381 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/Rapid7Reader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/Rapid7Reader.java @@ -19,13 +19,21 @@ import java.util.List; import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; import org.w3c.dom.Node; public class Rapid7Reader extends Reader { - public TestSuiteResults parse(Node root) throws Exception { + @Override + public boolean canRead(ResultFile resultFile) { + return resultFile.filename().endsWith(".xml") + && resultFile.xmlRootNodeName().equals("VulnSummary"); + } + + @Override + public TestSuiteResults parse(ResultFile resultFile) throws Exception { TestSuiteResults tr = new TestSuiteResults("Rapid7 AppSpider", true, TestSuiteResults.ToolType.DAST); @@ -46,13 +54,13 @@ public TestSuiteResults parse(Node root) throws Exception { // // - String duration = getNamedChild("ScanDuration", root).getTextContent(); + String duration = getNamedChild("ScanDuration", resultFile.xmlRootNode()).getTextContent(); tr.setTime(duration); - String version = getNamedChild("AppVersion", root).getTextContent(); + String version = getNamedChild("AppVersion", resultFile.xmlRootNode()).getTextContent(); tr.setToolVersion(version); - Node issues = getNamedChild("VulnList", root); + Node issues = getNamedChild("VulnList", resultFile.xmlRootNode()); List issueList = getNamedChildren("Vuln", issues); for (Node issue : issueList) { @@ -197,7 +205,7 @@ private TestCaseResult parseRapid7Item(Node flaw) throws Exception { return null; } - private static int cweLookup(String cweNum, String evidence) { + private int cweLookup(String cweNum, String evidence) { int cwe = 0000; if (cweNum != null && !cweNum.isEmpty()) { cwe = Integer.parseInt(cweNum); diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/Reader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/Reader.java index ed0ce4e6..34c7814c 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/Reader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/Reader.java @@ -18,12 +18,76 @@ package org.owasp.benchmarkutils.score.parsers; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import org.owasp.benchmarkutils.score.ResultFile; +import org.owasp.benchmarkutils.score.TestSuiteResults; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; -public class Reader { +public abstract class Reader { + + public static List allReaders() { + return Arrays.asList( + new AcunetixReader(), + new AppScanDynamicReader(), + new AppScanDynamicReader2(), + new AppScanSourceReader(), + new AppScanSourceReader2(), + new ArachniReader(), + new BurpJsonReader(), + new BurpReader(), + new CASTAIPReader(), + new CheckmarxESReader(), + new CheckmarxIASTReader(), + new CheckmarxReader(), + new CodeQLReader(), + new ContrastReader(), + new CoverityReader(), + new CrashtestReader(), + new FaastReader(), + new FindbugsReader(), + new FortifyReader(), + new FusionLiteInsightReader(), + new HCLReader(), + new HdivReader(), + new HorusecReader(), + new InsiderReader(), + new JuliaReader(), + new KiuwanReader(), + new LGTMReader(), + new NetsparkerReader(), + new NJSScanReader(), + new NoisyCricketReader(), + new ParasoftReader(), + new PMDReader(), + new QualysWASReader(), + new Rapid7Reader(), + new ReshiftReader(), + new SeekerReader(), + new SemgrepReader(), + new ShiftLeftReader(), + new ShiftLeftScanReader(), + new SnappyTickReader(), + new SonarQubeJsonReader(), + new SonarQubeReader(), + new SourceMeterReader(), + new ThunderScanReader(), + new VeracodeReader(), + new VisualCodeGrepperReader(), + new W3AFReader(), + new WapitiJsonReader(), + new WapitiReader(), + new WebInspectReader(), + new XanitizerReader(), + new ZapJsonReader(), + new ZapReader()); + } + + public abstract boolean canRead(ResultFile resultFile); + + public abstract TestSuiteResults parse(ResultFile resultFile) throws Exception; public static Node getNamedNode(String name, NodeList list) { for (int i = 0; i < list.getLength(); i++) { @@ -34,9 +98,9 @@ public static Node getNamedNode(String name, NodeList list) { } return null; } - // Returns the node inside this nodelist whose name matches 'name', that also has an attribute // called 'key' whose value matches 'keyvalue' + public static Node getNamedNode(String name, String keyValue, NodeList list) { if ((name == null) || (keyValue == null) || (list == null)) return null; for (int i = 0; i < list.getLength(); i++) { @@ -56,13 +120,12 @@ public static Node getNamedChild(String name, Node parent) { } public static List getNamedChildren(String name, List list) { - List results = new ArrayList(); + List results = new ArrayList<>(); for (Node n : list) { NodeList children = n.getChildNodes(); for (int i = 0; i < children.getLength(); i++) { Node child = children.item(i); if (child.getNodeName().equals(name)) { - // System.out.println("> " + child.getNodeName() + "::" + child.getNodeValue()); results.add(child); } } @@ -93,8 +156,7 @@ public static String getAttributeValue(String name, Node node) { if (nnm != null) { Node attrnode = nnm.getNamedItem(name); if (attrnode != null) { - String value = attrnode.getNodeValue(); - return value; + return attrnode.getNodeValue(); } } return null; diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ReshiftReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ReshiftReader.java index 23341615..55c83ab4 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ReshiftReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ReshiftReader.java @@ -17,15 +17,22 @@ */ package org.owasp.benchmarkutils.score.parsers; -import java.io.File; +import java.io.StringReader; import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVRecord; import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; public class ReshiftReader extends Reader { + @Override + public boolean canRead(ResultFile resultFile) { + return resultFile.filename().endsWith(".csv") + && resultFile.line(0).contains("Reshift Report"); + } + private static int cweLookup(String checkerKey) { checkerKey = checkerKey.replace("-SECOND-ORDER", ""); @@ -68,7 +75,8 @@ private static int cweLookup(String checkerKey) { return 0; } - public TestSuiteResults parse(File f) throws Exception { + @Override + public TestSuiteResults parse(ResultFile resultFile) throws Exception { TestSuiteResults tr = new TestSuiteResults("Reshift", true, TestSuiteResults.ToolType.SAST); /* The start of a Reshift .csv results file looks like this (where I've added the line #'s in front): @@ -84,7 +92,8 @@ public TestSuiteResults parse(File f) throws Exception { N: The rest of the results lines from here to end ... */ - java.io.BufferedReader inReader = new java.io.BufferedReader(new java.io.FileReader(f)); + java.io.BufferedReader inReader = + new java.io.BufferedReader(new StringReader(resultFile.content())); for (int i = 1; i <= 6; i++) { // Read 6 lines so we can skip over the preamble inReader.readLine(); } diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/SeekerReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/SeekerReader.java index e00763d3..5c0302e8 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/SeekerReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/SeekerReader.java @@ -17,15 +17,53 @@ */ package org.owasp.benchmarkutils.score.parsers; -import java.io.File; import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVRecord; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; public class SeekerReader extends Reader { - private static int cweLookup(String checkerKey) { + @Override + public boolean canRead(ResultFile resultFile) { + return resultFile.filename().endsWith(".csv") + && resultFile.line(0).contains("CheckerKey") + && resultFile.line(0).contains("LastDetectionURL"); + } + + @Override + public TestSuiteResults parse(ResultFile resultFile) throws Exception { + TestSuiteResults tr = new TestSuiteResults("Seeker", true, TestSuiteResults.ToolType.IAST); + + java.io.Reader inReader = new java.io.FileReader(resultFile.file()); + Iterable records = CSVFormat.RFC4180.withFirstRecordAsHeader().parse(inReader); + for (CSVRecord record : records) { + String checkerKey = record.get("CheckerKey"); + String url = record.get("LastDetectionURL"); + + TestCaseResult tcr = new TestCaseResult(); + tcr.setCategory(checkerKey); + tcr.setCWE(cweLookup(checkerKey)); + try { + if (url.length() >= 5) { + tcr.setNumber(Integer.parseInt(url.substring(url.length() - 5, url.length()))); + } + } catch (NumberFormatException e) { + System.out.println("> Parse error: " + record.toString()); + } + + if (tcr.getCWE() != 0) { + tr.put(tcr); + } + } + + tr.setTime("100"); + + return tr; + } + + private int cweLookup(String checkerKey) { checkerKey = checkerKey.replace("-SECOND-ORDER", ""); switch (checkerKey) { @@ -70,34 +108,4 @@ private static int cweLookup(String checkerKey) { } return 0; } - - public TestSuiteResults parse(File f) throws Exception { - TestSuiteResults tr = new TestSuiteResults("Seeker", true, TestSuiteResults.ToolType.IAST); - - java.io.Reader inReader = new java.io.FileReader(f); - Iterable records = CSVFormat.RFC4180.withFirstRecordAsHeader().parse(inReader); - for (CSVRecord record : records) { - String checkerKey = record.get("CheckerKey"); - String url = record.get("LastDetectionURL"); - - TestCaseResult tcr = new TestCaseResult(); - tcr.setCategory(checkerKey); - tcr.setCWE(cweLookup(checkerKey)); - try { - if (url.length() >= 5) { - tcr.setNumber(Integer.parseInt(url.substring(url.length() - 5, url.length()))); - } - } catch (NumberFormatException e) { - System.out.println("> Parse error: " + record.toString()); - } - - if (tcr.getCWE() != 0) { - tr.put(tcr); - } - } - - tr.setTime("100"); - - return tr; - } } diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/SemgrepReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/SemgrepReader.java index 737bc042..d4c5be5f 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/SemgrepReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/SemgrepReader.java @@ -20,15 +20,25 @@ import org.json.JSONArray; import org.json.JSONObject; import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; -public class SemgrepReader { - public TestSuiteResults parse(JSONObject jsonResults) { +public class SemgrepReader extends Reader { + + @Override + public boolean canRead(ResultFile resultFile) { + return resultFile.isJson() + && resultFile.json().has("results") + && resultFile.json().has("errors"); + } + + @Override + public TestSuiteResults parse(ResultFile resultFile) throws Exception { TestSuiteResults tr = new TestSuiteResults("Semgrep", false, TestSuiteResults.ToolType.SAST); - JSONArray results = jsonResults.getJSONArray("results"); + JSONArray results = resultFile.json().getJSONArray("results"); // engine version // duration time diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ShiftLeftReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ShiftLeftReader.java index bcec3531..5ef5ad46 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ShiftLeftReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ShiftLeftReader.java @@ -18,9 +18,8 @@ package org.owasp.benchmarkutils.score.parsers; import java.io.BufferedReader; -import java.io.File; import java.io.FileReader; -import java.io.IOException; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; import org.owasp.benchmarkutils.score.TestSuiteResults.ToolType; @@ -33,10 +32,17 @@ */ public class ShiftLeftReader extends Reader { - public TestSuiteResults parse(File f) throws IOException { + @Override + public boolean canRead(ResultFile resultFile) { + return resultFile.filename().endsWith(".sl"); + } + + @Override + public TestSuiteResults parse(ResultFile resultFile) throws Exception { TestSuiteResults tr = new TestSuiteResults("ShiftLeft", true, ToolType.SAST); - try (BufferedReader reader = new BufferedReader(new FileReader(f)); ) { + + try (BufferedReader reader = new BufferedReader(new FileReader(resultFile.file()))) { String line; while ((line = reader.readLine()) != null) { diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ShiftLeftScanReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ShiftLeftScanReader.java index b1f13cd9..e75c178c 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ShiftLeftScanReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ShiftLeftScanReader.java @@ -25,20 +25,21 @@ import org.json.JSONArray; import org.json.JSONObject; import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; -public class ShiftLeftScanReader { +public class ShiftLeftScanReader extends Reader { - public static boolean isShiftLeftScanReport(final String content) { - return content.contains("@ShiftLeft/sast-scan"); + @Override + public boolean canRead(ResultFile resultFile) { + return resultFile.content().contains("@ShiftLeft/sast-scan"); } - public TestSuiteResults parse(final String content) throws Exception { - String[] lines = content.split("\n"); - - JSONObject javaSourceAnalyzer = new JSONObject(lines[0]); - JSONObject classFileAnalyzer = new JSONObject(lines[1]); + @Override + public TestSuiteResults parse(ResultFile resultFile) throws Exception { + JSONObject javaSourceAnalyzer = new JSONObject(resultFile.line(0)); + JSONObject classFileAnalyzer = new JSONObject(resultFile.line(1)); // false indicates this is an open source/free tool. TestSuiteResults tr = diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/SnappyTickReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/SnappyTickReader.java index e5dcf184..b39bdc49 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/SnappyTickReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/SnappyTickReader.java @@ -22,16 +22,23 @@ import java.util.List; import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; import org.w3c.dom.Node; public class SnappyTickReader extends Reader { - public TestSuiteResults parse(Node root) throws Exception { + @Override + public boolean canRead(ResultFile resultFile) { + return resultFile.filename().endsWith(".xml") + && resultFile.xmlRootNodeName().equals("Report"); + } + @Override + public TestSuiteResults parse(ResultFile resultFile) throws Exception { // root Node is Report - Node toolInfo = getNamedChild("ToolInfo", root); + Node toolInfo = getNamedChild("ToolInfo", resultFile.xmlRootNode()); Node tool = getNamedChild("Tool", toolInfo); String toolName = getAttributeValue("Name", tool); TestSuiteResults tr = new TestSuiteResults(toolName, true, TestSuiteResults.ToolType.SAST); @@ -39,7 +46,7 @@ public TestSuiteResults parse(Node root) throws Exception { String version = getAttributeValue("Version", tool); tr.setToolVersion(version); - Node projectInfo = getNamedChild("ProjectInfo", root); + Node projectInfo = getNamedChild("ProjectInfo", resultFile.xmlRootNode()); Node project = getNamedChild("Project", projectInfo); String duration = getAttributeValue("Duration", project); tr.setTime(duration); @@ -57,7 +64,7 @@ public TestSuiteResults parse(Node root) throws Exception { // - Node vulnReport = getNamedChild("VulnerabilityReport", root); + Node vulnReport = getNamedChild("VulnerabilityReport", resultFile.xmlRootNode()); // Loop through all the Severity nodes List sevLevels = getNamedChildren("Severity", vulnReport); @@ -95,8 +102,7 @@ public TestSuiteResults parse(Node root) throws Exception { return tr; } - private static int extractTestNumber(String testfile) { - + private int extractTestNumber(String testfile) { if (testfile.startsWith(BenchmarkScore.TESTCASENAME)) { String testno = testfile.substring(BenchmarkScore.TESTCASENAME.length()); try { @@ -108,8 +114,7 @@ private static int extractTestNumber(String testfile) { return -1; } - private static int cweLookup(String checkerKey) { - + private int cweLookup(String checkerKey) { switch (checkerKey.trim()) { case "1004": return 614; // HTTPOnly Flag Not Set For Cookies:insecure cookie use diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/SonarQubeJsonReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/SonarQubeJsonReader.java index 2820d0c9..8b4a8efb 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/SonarQubeJsonReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/SonarQubeJsonReader.java @@ -17,31 +17,36 @@ */ package org.owasp.benchmarkutils.score.parsers; -import java.io.File; -import java.nio.file.Files; -import java.nio.file.Paths; import org.json.JSONArray; import org.json.JSONObject; import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; public class SonarQubeJsonReader extends Reader { - public TestSuiteResults parse(File f) throws Exception { + @Override + public boolean canRead(ResultFile resultFile) { + // SonarQube has two different JSON formats, one for standard issues and + // another for 'hotspots' which are security issues. Both are handled by + // the same parser for SonarQube. + return resultFile.isJson() + && (resultFile.json().has("hotspots") || resultFile.json().has("issues")) + && !resultFile.json().has("type"); // Ignore Coverty results + } + @Override + public TestSuiteResults parse(ResultFile resultFile) throws Exception { TestSuiteResults tr = new TestSuiteResults("SonarQube", false, TestSuiteResults.ToolType.SAST); // If the filename includes an elapsed time in seconds (e.g., TOOLNAME-seconds.xml), // set the compute time on the score card. - tr.setTime(f); - - String content = new String(Files.readAllBytes(Paths.get(f.getPath()))); - JSONObject obj = new JSONObject(content); + tr.setTime(resultFile.file()); - parseIssues(tr, obj); - parseHotspots(tr, obj); + parseIssues(tr, resultFile.json()); + parseHotspots(tr, resultFile.json()); return tr; } @@ -185,7 +190,7 @@ private TestCaseResult parseSonarQubeHotSpotIssue(JSONObject finding) { * in some findings to move such issues to the 'right' CWE. * As such, we specifically look at the message in some cases to fix the mapping. */ - public static int securityCategoryCWELookup(String secCat, String message) { + public int securityCategoryCWELookup(String secCat, String message) { // Not sure where to look up all the possible security categories in SonarQube, but the // mappings seem obvious enough. diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/SonarQubeReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/SonarQubeReader.java index 373c4959..3491d605 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/SonarQubeReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/SonarQubeReader.java @@ -18,12 +18,12 @@ package org.owasp.benchmarkutils.score.parsers; import java.io.ByteArrayInputStream; -import java.io.File; -import java.nio.file.Files; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.CweNumber; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; import org.w3c.dom.Document; @@ -33,12 +33,19 @@ public class SonarQubeReader extends Reader { - public TestSuiteResults parse(File f) throws Exception { + @Override + public boolean canRead(ResultFile resultFile) { + return resultFile.filename().endsWith(".xml") + && (resultFile.line(0).startsWith("")); + } + + @Override + public TestSuiteResults parse(ResultFile resultFile) throws Exception { DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); // Prevent XXE docBuilderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder(); - byte[] bytes = Files.readAllBytes(f.toPath()); // Because the Sonar results file is not well formed, i.e., it has multiple root elements, // not @@ -48,7 +55,7 @@ public TestSuiteResults parse(File f) throws Exception { // org.xml.sax.SAXParseException; // lineNumber: X; columnNumber: YY; The markup in the document following the root element // must be well-formed. - String fixed = "" + new String(bytes, "UTF-8") + ""; + String fixed = "" + resultFile.content() + ""; InputSource is = new InputSource(new ByteArrayInputStream(fixed.getBytes())); Document doc = docBuilder.parse(is); @@ -91,7 +98,7 @@ public TestSuiteResults parse(File f) throws Exception { // If the filename includes an elapsed time in seconds (e.g., TOOLNAME-seconds.xml), // set the compute time on the score card. TODO: Move this to BenchmarkScore for ALL tools? - tr.setTime(f); + tr.setTime(resultFile.file()); return tr; } @@ -173,151 +180,178 @@ public static int cweLookup(String squidNumber) { // the #'s with no leading zeroes to look up the 'squid' rule. switch (squidNumber) { case "S100": - return 0000; // Method names should comply with a naming convention + return -1; // Method names should comply with a naming convention case "S105": case "S00105": - return 000; // Replace all tab characters in this file by sequences of white-spaces. + return -1; // Replace all tab characters in this file by sequences of white-spaces. case "S106": - return 0000; // Replace this usage of System.out or System.err by a logger. + return -1; // Replace this usage of System.out or System.err by a logger. case "S108": - return 0000; // Nested blocks of code should not be left empty + return -1; // Nested blocks of code should not be left empty case "S112": case "S00112": - return 397; // Generic exceptions should never be thrown + return CweNumber + .THROW_GENERIC_EXCEPTION; // Generic exceptions should never be thrown case "S115": - return 0000; // Constant names should comply with a naming convention + return -1; // Constant names should comply with a naming convention case "S116": - return 0000; // Field names should comply with a naming convention + return -1; // Field names should comply with a naming convention case "S117": - return 0000; // Local variable and method parameter names should comply with a + return -1; // Local variable and method parameter names should comply with a // naming convention case "S121": case "S00121": - return 483; // Control structures should always use curly braces + return CweNumber + .INCORRECT_BLOCK_DELIMITATION; // Control structures should always use curly + // braces case "S125": - return 0000; // Sections of code should not be commented out + return -1; // Sections of code should not be commented out case "S128": - return 484; // Switch cases should end with an unconditional"break" statement + return CweNumber + .OMITTED_BREAK; // Switch cases should end with an unconditional "break" + // statement case "S131": - return 478; // "switch" statements should have "default" clauses + return CweNumber + .MISSING_DEFAULT_CASE; // "switch" statements should have "default" clauses case "S135": - return 0000; // Loops should not contain more than a single "break" or "continue" + return -1; // Loops should not contain more than a single "break" or "continue" // statement case "S864": - return 783; // Limited dependence should be placed on operator precedence rules in + return CweNumber + .OPERATOR_PRECEDENCE_LOGIC; // Limited dependence should be placed on + // operator precedence rules in // expressions case "S888": - return 835; // Relational operators should be used in"for" loop termination + return CweNumber + .LOOP_WITH_UNREACHABLE_EXIT; // Relational operators should be used in "for" + // loop termination // conditions case "S899": - return 754; // Return values should not be ignored when they contain the operation + return CweNumber + .IMPROPER_CHECK_FOR_CONDITIONS; // Return values should not be ignored when + // they contain the operation // status code case "S1066": - return 0000; // Collapsible "if" statements should be merged + return -1; // Collapsible "if" statements should be merged case "S1075": - return 0000; // URIs should not be hardcoded + return -1; // URIs should not be hardcoded case "S1104": - return 493; // Class variable fields should not have public accessibility + return CweNumber + .PUBLIC_VAR_WITHOUT_FINAL; // Class variable fields should not have public + // accessibility case "S1116": - return 0000; // Empty statements should be removed + return -1; // Empty statements should be removed case "S1117": - return 0000; // Local variables should not shadow class fields + return -1; // Local variables should not shadow class fields case "S1118": - return 0000; // Utility classes should not have public constructors + return -1; // Utility classes should not have public constructors case "S1128": - return 0000; // Unnecessary imports should be removed + return -1; // Unnecessary imports should be removed case "S1130": - return 0000; // "throws" declarations should not be superfluous + return -1; // "throws" declarations should not be superfluous case "S1132": - return 0000; // Strings literals should be placed on the left side when checking for + return -1; // Strings literals should be placed on the left side when checking for // equality case "S1134": - return 0000; // Track uses of "FIXME" tags + return -1; // Track uses of "FIXME" tags case "S1135": - return 0000; // Track uses of "TODO" tags + return -1; // Track uses of "TODO" tags case "S1141": - return 0000; // Try-catch blocks should not be nested + return -1; // Try-catch blocks should not be nested case "S1143": - return 584; // "return " statements should not occur in "finally" blocks + return CweNumber.RETURN_INSIDE_FINALLY; // "return " statements should not occur in + // "finally" blocks case "S1144": - return 0000; // Unused "private" methods should be removed + return -1; // Unused "private" methods should be removed case "S1145": - return 0000; // "if" statement conditions should not unconditionally evaluate + return -1; // "if" statement conditions should not unconditionally evaluate // to"true" or to"false" case "S1147": - return 382; // Exit methods should not be called + return CweNumber.SYSTEM_EXIT; // Exit methods should not be called case "S1149": - return 0000; // Synchronized classes Vector, Hashtable, Stack and StringBuffer + return -1; // Synchronized classes Vector, Hashtable, Stack and StringBuffer // should not be used case "S1155": - return 0000; // Collection.isEmpty() should be used to test for emptiness + return -1; // Collection.isEmpty() should be used to test for emptiness case "S1161": - return 0000; // "@Override" should be used on overriding and implementing methods + return -1; // "@Override" should be used on overriding and implementing methods case "S1163": - return 0000; // Exceptions should not be thrown in finally blocks + return -1; // Exceptions should not be thrown in finally blocks case "S1168": - return 0000; // Empty arrays and collections should be returned instead of null + return -1; // Empty arrays and collections should be returned instead of null case "S1171": - return 0000; // Only static class initializers should be used + return -1; // Only static class initializers should be used case "S1172": - return 0000; // Unused method parameters should be removed + return -1; // Unused method parameters should be removed case "S1174": - return 583; // "Object.finalize()" should remain protected (versus public) when - // overriding + return CweNumber + .FINALIZE_DECLARED_PUBLIC; // "Object.finalize()" should remain protected + // (versus public) when overriding case "S1181": - return 396; // Throwable and Error should not be caught + return CweNumber + .CATCH_GENERIC_EXCEPTION; // Throwable and Error should not be caught case "S1182": - return 580; // Classes that override"clone" should be"Cloneable" and - // call"super.clone()" + return CweNumber + .CLONE_WITHOUT_SUPER_CLONE; // Classes that override "clone" should be + // "Cloneable" and + // call "super.clone()" case "S1186": - return 0000; // Methods should not be empty + return -1; // Methods should not be empty case "S1192": - return 0000; // String literals should not be duplicated + return -1; // String literals should not be duplicated case "S1197": - return 0000; // Array designators "[]" should be on the type, not the variable + return -1; // Array designators "[]" should be on the type, not the variable case "S1199": - return 0000; // Nested code blocks should not be used + return -1; // Nested code blocks should not be used case "S1206": - return 581; // "equals(Object obj)" and"hashCode()" should be overridden in pairs + return CweNumber + .OBJECT_MODEL_VIOLATION; // "equals(Object obj)" and"hashCode()" should be + // overridden in pairs case "S1210": - return 0000; // "equals(Object obj)" should be overridden along with the + return -1; // "equals(Object obj)" should be overridden along with the // "compareTo(T obj)" method case "S1217": - return 572; // Thread.run() and Runnable.run() should not be called directly + return CweNumber + .THREAD_WRONG_CALL; // Thread.run() and Runnable.run() should not be called + // directly case "S1301": - return 0000; // "switch" statements should have at least 3 "case" clauses + return -1; // "switch" statements should have at least 3 "case" clauses case "S1481": - return 0000; // Remove this unused "c" local variable. + return -1; // Remove this unused "c" local variable. case "S1444": - return 500; // "public static" fields should always be constant + return CweNumber.PUBLIC_STATIC_NOT_FINAL; // "public static" fields should always be + // constant case "S1479": - return 0000; // "switch" statements should not have too many "case" clauses + return -1; // "switch" statements should not have too many "case" clauses case "S1488": - return 0000; // Local variables should not be declared and then immediately returned + return -1; // Local variables should not be declared and then immediately returned // or thrown case "S1643": - return 0000; // Strings should not be concatenated using '+' in a loop + return -1; // Strings should not be concatenated using '+' in a loop case "S1659": - return 0000; // Multiple variables should not be declared on the same line + return -1; // Multiple variables should not be declared on the same line case "S1696": - return 395; // "NullPointerException" should not be caught + return CweNumber + .CATCHING_NULL_POINTER_EXCEPTION; // "NullPointerException" should not be + // caught case "S1698": - return 595; // Objects should be compared with"equals()" + return CweNumber + .OBJECT_REFERENCE_COMPARISON; // Objects should be compared with"equals()" case "S1724": - return 0000; // Deprecated classes and interfaces should not be extended/implemented + return -1; // Deprecated classes and interfaces should not be extended/implemented case "S1850": - return 0000; // "instanceof" operators that always return "true" or"false" should be + return -1; // "instanceof" operators that always return "true" or"false" should be // removed case "S1854": - return 563; // Unused assignments should be removed + return CweNumber.UNUSED_VAR_ASSIGNMENT; // Unused assignments should be removed case "S1872": return 486; // Classes should not be compared by name case "S1873": return 582; // "static final" arrays should be"private" case "S1874": - return 0000; // "@Deprecated" code should not be used + return -1; // "@Deprecated" code should not be used case "S1905": - return 0000; // Redundant casts should not be used + return -1; // Redundant casts should not be used case "S1948": return 594; // Fields in a"Serializable" class should either be transient or // serializable @@ -326,40 +360,49 @@ public static int cweLookup(String squidNumber) { case "S2068": return 259; // Credentials should not be hard-coded case "S2070": - return 328; // Benchmark Vuln: SHA-1 and Message-Digest hash algorithms should not + return CweNumber.REVERSIBLE_HASH; // Benchmark Vuln: SHA-1 and Message-Digest hash + // algorithms should not // be used case "S2076": - return 78; // Benchmark Vuln: Values passed to OS commands should be sanitized + return CweNumber + .COMMAND_INJECTION; // Benchmark Vuln: Values passed to OS commands should + // be sanitized case "S2077": - return 89; // Benchmark Vuln: Values passed to SQL commands should be sanitized + return CweNumber + .SQL_INJECTION; // Benchmark Vuln: Values passed to SQL commands should be + // sanitized case "S2078": - return 90; // Benchmark Vuln: Values passed to LDAP queries should be sanitized + return CweNumber + .LDAP_INJECTION; // Benchmark Vuln: Values passed to LDAP queries should be + // sanitized case "S2083": - return 22; // Benchmark Vuln: I/O function calls should not be vulnerable to path + return CweNumber.PATH_TRAVERSAL; // Benchmark Vuln: I/O function calls should not be + // vulnerable to path // injection attacks case "S2089": return 293; // HTTP referers should not be relied on case "S2091": - return 643; // Benchmark Vuln: XPath expressions should not be vulnerable to + return CweNumber.XPATH_INJECTION; // Benchmark Vuln: XPath expressions should not be + // vulnerable to // injection attacks case "S2092": - return 614; // Benchmark Vuln: Cookies should be "secure" + return CweNumber.INSECURE_COOKIE; // Benchmark Vuln: Cookies should be "secure" case "S2093": - return 0000; // Try-with-resources should be used + return -1; // Try-with-resources should be used case "S2095": return 459; // Resources should be closed case "S2130": - return 0000; // Parsing should be used to convert "Strings" to primitives + return -1; // Parsing should be used to convert "Strings" to primitives case "S2147": - return 0000; // Catches should be combined + return -1; // Catches should be combined case "S2157": - return 0000; // "Cloneables" should implement "clone" + return -1; // "Cloneables" should implement "clone" case "S2160": - return 0000; // Subclasses that add fields should override "equals" + return -1; // Subclasses that add fields should override "equals" case "S2176": - return 0000; // Class names should not shadow interfaces or superclasses + return -1; // Class names should not shadow interfaces or superclasses case "S2178": - return 0000; // Short-circuit logic should be used in boolean contexts + return -1; // Short-circuit logic should be used in boolean contexts case "S2184": return 190; // Math operands should be cast before assignment case "S2222": @@ -367,25 +410,31 @@ public static int cweLookup(String squidNumber) { case "S2225": return 476; // "toString()" and"clone()" methods should not return null case "S2245": - return 330; // Benchmark Vuln: Pseudorandom number generators (PRNGs) should not be + return CweNumber + .WEAK_RANDOM; // Benchmark Vuln: Pseudorandom number generators (PRNGs) + // should not be // used in secure contexts case "S2254": - return 0000; // "HttpServletRequest.getRequestedSessionId()" should not be used + return -1; // "HttpServletRequest.getRequestedSessionId()" should not be used case "S2257": - return 327; // Benchmark Vuln: Only standard cryptographic algorithms should be used + return CweNumber + .BROKEN_CRYPTO; // Benchmark Vuln: Only standard cryptographic algorithms + // should be used case "S2259": return 476; // Null pointers should not be dereferenced case "S2275": - return 0000; // Printf-style format strings should not lead to unexpected behavior + return -1; // Printf-style format strings should not lead to unexpected behavior // at runtime case "S2277": return 780; // Cryptographic RSA algorithms should always incorporate OAEP (Optimal // Asymmetric Encryption Padding) case "S2278": - return 327; // Benchmark Vuln: DES (Data Encryption Standard) and DESede (3DES) + return CweNumber + .BROKEN_CRYPTO; // Benchmark Vuln: DES (Data Encryption Standard) and DESede + // (3DES) // should not be used case "S2293": - return 0000; // The diamond operator ("<>") should be used + return -1; // The diamond operator ("<>") should be used case "S2384": return 374; // Mutable members should not be stored or returned directly case "S2386": @@ -393,79 +442,85 @@ public static int cweLookup(String squidNumber) { case "S2441": return 579; // Non-serializable objects should not be stored in"HttpSessions" case "S2479": - return 0000; // Whitespace and control characters in literals should be explicit + return -1; // Whitespace and control characters in literals should be explicit case "S2583": return 489; // Conditions should not unconditionally evaluate to"TRUE" or to"FALSE" case "S2589": - return 0000; // Boolean expressions should not be gratuitous - CWEs: 570/571 + return -1; // Boolean expressions should not be gratuitous - CWEs: 570/571 case "S2658": return 470; // Use of Externally-Controlled Input to Select Classes or Code ('Unsafe // Reflection') case "S2677": - return 0000; // "read" and "readLine" return values should be used + return -1; // "read" and "readLine" return values should be used case "S2681": return 483; // Multiline blocks should be enclosed in curly braces case "S2696": - return 0000; // Instance methods should not write to "static" fields + return -1; // Instance methods should not write to "static" fields case "S2755": - return 611; // XML parsers should not be vulnerable to XXE attacks + return CweNumber + .XML_ENTITIES; // XML parsers should not be vulnerable to XXE attacks case "S2786": - return 0000; // Nested "enum"s should not be declared static + return -1; // Nested "enum"s should not be declared static case "S2864": - return 0000; // "entrySet()" should be iterated when both the key and value are + return -1; // "entrySet()" should be iterated when both the key and value are // needed case "S3008": - return 0000; // Static non-final field names should comply with a naming convention + return -1; // Static non-final field names should comply with a naming convention case "S3012": - return 0000; // Arrays should not be copied using loops + return -1; // Arrays should not be copied using loops case "S3400": - return 0000; // Methods should not return constants + return -1; // Methods should not return constants case "S3518": return 369; // Zero should not be a possible denominator case "S3599": - return 0000; // Double Brace Initialization should not be used + return -1; // Double Brace Initialization should not be used case "S3626": - return 0000; // Jump statements should not be redundant + return -1; // Jump statements should not be redundant case "S3649": - return 89; // Database queries should not be vulnerable to injection attacks + return CweNumber + .SQL_INJECTION; // Database queries should not be vulnerable to injection + // attacks case "S3740": - return 0000; // Raw types should not be used + return -1; // Raw types should not be used case "S3776": - return 0000; // Cognitive Complexity of methods should not be too high + return -1; // Cognitive Complexity of methods should not be too high case "S3824": - return 0000; // "Map.get" and value test should be replaced with single method call + return -1; // "Map.get" and value test should be replaced with single method call case "S3973": - return 0000; // A conditionally executed single line should be denoted by + return -1; // A conditionally executed single line should be denoted by // indentation case "S4042": - return 0000; // "java.nio.Files#delete" should be preferred + return -1; // "java.nio.Files#delete" should be preferred case "S4435": - return 611; // XML transformers should be secured + return CweNumber.XML_ENTITIES; // XML transformers should be secured case "S4488": - return 0000; // Composed "@RequestMapping" variants should be preferred + return -1; // Composed "@RequestMapping" variants should be preferred case "S4719": - return 0000; // "StandardCharsets" constants should be preferred + return -1; // "StandardCharsets" constants should be preferred case "S4838": - return 0000; // An iteration on a Collection should be performed on the type handled + return -1; // An iteration on a Collection should be performed on the type handled // by the Collection - case "S5131": - return 79; // Endpoints should not be vulnerable to reflected cross-site scripting + case "S5131": // Endpoints should not be vulnerable to reflected cross-site scripting // (XSS) attacks + return CweNumber.XSS; case "S5261": - return 0000; // "else" statements should be clearly matched with an "if" + return -1; // "else" statements should be clearly matched with an "if" case "S5361": - return 0000; // "String#replace" should be preferred to "String#replaceAll" + return -1; // "String#replace" should be preferred to "String#replaceAll" case "S5542": - return 327; // Benchmark Vuln: Encryption algorithms should be used with secure mode + return CweNumber + .BROKEN_CRYPTO; // Benchmark Vuln: Encryption algorithms should be used with + // secure mode // and padding scheme case "S5547": - return 327; // Benchmark Vuln: Cipher algorithms should be robust + return CweNumber + .BROKEN_CRYPTO; // Benchmark Vuln: Cipher algorithms should be robust case "CallToDeprecatedMethod": case "ClassVariableVisibilityCheck": case "DuplicatedBlocks": case "SwitchLastCaseIsDefaultCheck": - return 0000; // Don't care. Not sure why these are being returned instead of an + return -1; // Don't care. Not sure why these are being returned instead of an // S#### value default: System.out.println( diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/SourceMeterReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/SourceMeterReader.java index eadb9c59..21f97804 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/SourceMeterReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/SourceMeterReader.java @@ -17,15 +17,17 @@ */ package org.owasp.benchmarkutils.score.parsers; -import java.io.File; -import java.io.FileInputStream; -import java.util.List; -import org.apache.commons.io.IOUtils; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; public class SourceMeterReader extends Reader { + @Override + public boolean canRead(ResultFile resultFile) { + return resultFile.filename().endsWith(".txt") && resultFile.line(0).startsWith("Possible "); + } + // Possible Cross-site Scripting Vulnerability: // Source: String getValue() // Sink: void println(String arg0) @@ -35,17 +37,16 @@ public class SourceMeterReader extends Reader { // /home/istvan/owasp/ellenorzes/benchmark/src/main/java/org/owasp/benchmark/testcode/BenchmarkTest00023.java(80):(80,33,81,61)[0] // /home/istvan/owasp/ellenorzes/benchmark/src/main/java/org/owasp/benchmark/testcode/BenchmarkTest00023.java(80):(80,4,81,62)[0] - public TestSuiteResults parse(File fileToParse) throws Exception { + @Override + public TestSuiteResults parse(ResultFile resultFile) throws Exception { TestSuiteResults tr = new TestSuiteResults( "SourceMeter VulnerabilityHunter", true, TestSuiteResults.ToolType.SAST); - List sourceLines = IOUtils.readLines(new FileInputStream(fileToParse)); - String vuln = null; String file = null; boolean nextLine = false; - for (String line : sourceLines) { + for (String line : resultFile.lines()) { try { if (line.length() == 0) { vuln = null; diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ThunderScanReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ThunderScanReader.java index 197c9cdc..8d7143ae 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ThunderScanReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ThunderScanReader.java @@ -17,7 +17,6 @@ */ package org.owasp.benchmarkutils.score.parsers; -import java.io.File; import java.io.FileInputStream; import java.util.ArrayList; import java.util.HashMap; @@ -26,6 +25,7 @@ import javax.xml.parsers.DocumentBuilder; import org.owasp.benchmarkutils.helpers.Utils; import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; import org.w3c.dom.Document; @@ -36,12 +36,18 @@ public class ThunderScanReader extends Reader { - private static List fileListDuplicates = new ArrayList(); + private final List fileListDuplicates = new ArrayList<>(); - public TestSuiteResults parse(File f) throws Exception { + @Override + public boolean canRead(ResultFile resultFile) { + return resultFile.filename().endsWith(".xml") + && resultFile.line(1).startsWith(" "); + } + @Override + public TestSuiteResults parse(ResultFile resultFile) throws Exception { DocumentBuilder dBuilder = Utils.safeDocBuilderFactory.newDocumentBuilder(); - InputSource fileInput = new InputSource(new FileInputStream(f)); + InputSource fileInput = new InputSource(new FileInputStream(resultFile.file())); Document doc = dBuilder.parse(fileInput); TestSuiteResults testResults = @@ -59,7 +65,6 @@ public TestSuiteResults parse(File f) throws Exception { if (vulnerabilities.getLength() < 1) continue; for (int j = 0; j < vulnerabilities.getLength(); j++) { - Node vulnerability = vulnerabilities.item(j); Element vulnElement = (Element) vulnerability; @@ -79,8 +84,7 @@ public TestSuiteResults parse(File f) throws Exception { return testResults; } - private static TestCaseResult parseThunderScanVulnerability( - Element vulnElement, String vulnType) { + private TestCaseResult parseThunderScanVulnerability(Element vulnElement, String vulnType) { TestCaseResult tcResult = new TestCaseResult(); diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/VeracodeReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/VeracodeReader.java index 09a962eb..c052ccc7 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/VeracodeReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/VeracodeReader.java @@ -17,13 +17,13 @@ */ package org.owasp.benchmarkutils.score.parsers; -import java.io.File; import java.io.FileInputStream; import java.text.SimpleDateFormat; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; import org.w3c.dom.Document; @@ -33,12 +33,23 @@ public class VeracodeReader extends Reader { - public TestSuiteResults parse(File f) throws Exception { + // submitted_date="2015-05-23 00:04:57 UTC" + // published_date="2015-05-28 15:28:35 UTC" + private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss zzz"); + + @Override + public boolean canRead(ResultFile resultFile) { + return resultFile.filename().endsWith(".xml") + && resultFile.line(1).startsWith(" - // w3af - Web Application Attack and Audit Framework - // Version: 1.7.6 - // Revision: 27b1516a3f - 04 Apr 2017 20:45 - // - - // Only start time available in XML. No stop time - // String duration = getNamedChild("scantime", root ).getTextContent(); - // try { - // long millis = Long.parseLong(duration); - // tr.setTime( TestResults.formatTime( millis ) ); - // } catch( Exception e ) { - // tr.setTime( duration ); - // } - - Node versionNode = getNamedChild("w3af-version", root); - String version = versionNode.getTextContent(); - version = version.substring(version.indexOf("Version: ") + "Version: ".length()); - version = version.substring(0, version.indexOf('\n')); - tr.setToolVersion(version); + tr.setToolVersion(parseVersion(root)); List issueList = getNamedChildren("vulnerability", root); @@ -80,20 +68,14 @@ public TestSuiteResults parse(File f) throws Exception { return tr; } - // - // 10 - // - // - // - // - // - // - - private TestCaseResult parseW3AFIssue(Node flaw) throws Exception { + private String parseVersion(Node root) { + Node versionNode = getNamedChild("w3af-version", root); + String version = versionNode.getTextContent(); + version = version.substring(version.indexOf("Version: ") + "Version: ".length()); + return version.substring(0, version.indexOf('\n')); + } + + private TestCaseResult parseW3AFIssue(Node flaw) { TestCaseResult tcr = new TestCaseResult(); String type = getAttributeValue("plugin", flaw); @@ -131,13 +113,13 @@ private TestCaseResult parseW3AFIssue(Node flaw) throws Exception { return null; } - private static int cweLookup(String name) { + private int cweLookup(String name) { if (name == null || name.isEmpty()) { return 0000; } switch (name) { case "Cross site scripting vulnerability": - return 79; // xss + return CweNumber.XSS; // case "insecure-cookie" : return 614; // insecure cookie use // case "sql-injection" : return 89; // sql injection // case "cmd-injection" : return 78; // command injection diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/WapitiJsonReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/WapitiJsonReader.java index 2a3f98f9..f0afe628 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/WapitiJsonReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/WapitiJsonReader.java @@ -26,23 +26,30 @@ import org.json.JSONArray; import org.json.JSONObject; import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; public class WapitiJsonReader extends Reader { - public static boolean isWapitiReport(JSONObject json) { + @Override + public boolean canRead(ResultFile resultFile) { try { - return json.getJSONObject("infos").getString("version").startsWith("Wapiti"); + return resultFile + .json() + .getJSONObject("infos") + .getString("version") + .startsWith("Wapiti"); } catch (Exception e) { return false; } } - public static TestSuiteResults parse(JSONObject json) throws Exception { + @Override + public TestSuiteResults parse(ResultFile resultFile) throws Exception { TestSuiteResults tr = new TestSuiteResults("Wapiti", false, TestSuiteResults.ToolType.DAST); - JSONObject vulnerabilities = json.getJSONObject("vulnerabilities"); + JSONObject vulnerabilities = resultFile.json().getJSONObject("vulnerabilities"); Map categoryCweMap = new HashMap<>(); @@ -98,7 +105,7 @@ public static TestSuiteResults parse(JSONObject json) throws Exception { } } - tr.setToolVersion(readVersion(json)); + tr.setToolVersion(readVersion(resultFile.json())); return tr; } diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/WapitiReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/WapitiReader.java index 3e315db6..8c6a630c 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/WapitiReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/WapitiReader.java @@ -17,12 +17,12 @@ */ package org.owasp.benchmarkutils.score.parsers; -import java.io.File; -import java.io.FileInputStream; +import java.io.StringReader; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; import org.w3c.dom.Document; @@ -31,13 +31,18 @@ public class WapitiReader extends Reader { - public TestSuiteResults parse(File f) throws Exception { + @Override + public boolean canRead(ResultFile resultFile) { + return resultFile.filename().endsWith(".xml") && resultFile.line(4).contains("Wapiti"); + } + @Override + public TestSuiteResults parse(ResultFile resultFile) throws Exception { DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); // Prevent XXE docBuilderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder(); - InputSource is = new InputSource(new FileInputStream(f)); + InputSource is = new InputSource(new StringReader(resultFile.content())); Document doc = docBuilder.parse(is); TestSuiteResults tr = new TestSuiteResults("Wapiti", false, TestSuiteResults.ToolType.DAST); @@ -46,6 +51,7 @@ public TestSuiteResults parse(File f) throws Exception { Node root = doc.getDocumentElement(); Node reportInfo = getNamedChild("report_infos", root); List infoList = getNamedChildren("info", reportInfo); + for (Node info : infoList) { String name = getAttributeValue("name", info); if ("generatorVersion".equals(name)) { diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/WebInspectReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/WebInspectReader.java index 62e4e1f0..d1dacce8 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/WebInspectReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/WebInspectReader.java @@ -19,13 +19,21 @@ import java.util.List; import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; import org.w3c.dom.Node; public class WebInspectReader extends Reader { - public TestSuiteResults parse(Node root) throws Exception { + @Override + public boolean canRead(ResultFile resultFile) { + return resultFile.filename().endsWith(".xml") + && resultFile.xmlRootNodeName().equals("Scan"); + } + + @Override + public TestSuiteResults parse(ResultFile resultFile) throws Exception { TestSuiteResults tr = new TestSuiteResults("HP WebInspect", true, TestSuiteResults.ToolType.DAST); @@ -34,11 +42,11 @@ public TestSuiteResults parse(Node root) throws Exception { // 9/11/2015 1:56:13 // PM02:59:39.0365257 - String duration = getNamedChild("Duration", root).getTextContent(); + String duration = getNamedChild("Duration", resultFile.xmlRootNode()).getTextContent(); duration = duration.substring(0, duration.indexOf('.')); tr.setTime(duration); - Node issues = getNamedChild("Issues", root); + Node issues = getNamedChild("Issues", resultFile.xmlRootNode()); List issueList = getNamedChildren("Issue", issues); for (Node issue : issueList) { @@ -104,7 +112,7 @@ private TestCaseResult parseWebInspectIssue(Node flaw) throws Exception { return null; } - private static int cweLookup(String rule) { + private int cweLookup(String rule) { switch (rule) { case "810": return 0000; // Poor Error Handling: Unhandled Exception diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/XanitizerReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/XanitizerReader.java index 251a2558..e0926584 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/XanitizerReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/XanitizerReader.java @@ -17,11 +17,11 @@ */ package org.owasp.benchmarkutils.score.parsers; -import java.io.File; import javax.xml.XMLConstants; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; import org.xml.sax.Attributes; @@ -30,12 +30,17 @@ public class XanitizerReader extends Reader { - public XanitizerReader() {} + @Override + public boolean canRead(ResultFile resultFile) { + return resultFile.filename().endsWith(".xml") + && resultFile.line(1).startsWith("This file is part of the Open Web Application Security Project (OWASP) Benchmark Project For + * details, please see https://owasp.org/www-project-benchmark/. + * + *

The OWASP Benchmark is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Foundation, version 2. + * + *

The OWASP Benchmark is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * @author Sascha Knoop + * @created 2021 + */ +package org.owasp.benchmarkutils.score.parsers; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.CweNumber; +import org.owasp.benchmarkutils.score.ResultFile; +import org.owasp.benchmarkutils.score.TestHelper; +import org.owasp.benchmarkutils.score.TestSuiteResults; + +public class AcunetixReaderTest extends ReaderTestBase { + + private ResultFile resultFile; + + @BeforeEach + void setUp() { + resultFile = TestHelper.resultFileOf("testfiles/Benchmark_1.2-Acunetix-v1.4.1.xml"); + BenchmarkScore.TESTCASENAME = "BenchmarkTest"; + } + + @Test + public void onlyAcunetixReaderReportsCanReadAsTrue() { + assertOnlyMatcherClassIs(this.resultFile, AcunetixReader.class); + } + + @Test + void readerHandlesGivenResultFile() throws Exception { + AcunetixReader reader = new AcunetixReader(); + TestSuiteResults result = reader.parse(resultFile); + + assertEquals(TestSuiteResults.ToolType.DAST, result.getToolType()); + assertTrue(result.isCommercial()); + assertEquals("Acunetix 360", result.getToolName()); + + assertEquals(2, result.getTotalResults()); + + assertEquals(CweNumber.COMMAND_INJECTION, result.get(1).get(0).getCWE()); + assertEquals(CweNumber.XSS, result.get(2).get(0).getCWE()); + } +} diff --git a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/AppScanDynamicReader2Test.java b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/AppScanDynamicReader2Test.java new file mode 100644 index 00000000..cb0ca2f1 --- /dev/null +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/AppScanDynamicReader2Test.java @@ -0,0 +1,63 @@ +/** + * OWASP Benchmark Project + * + *

This file is part of the Open Web Application Security Project (OWASP) Benchmark Project For + * details, please see https://owasp.org/www-project-benchmark/. + * + *

The OWASP Benchmark is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Foundation, version 2. + * + *

The OWASP Benchmark is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * @author Sascha Knoop + * @created 2021 + */ +package org.owasp.benchmarkutils.score.parsers; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.CweNumber; +import org.owasp.benchmarkutils.score.ResultFile; +import org.owasp.benchmarkutils.score.TestHelper; +import org.owasp.benchmarkutils.score.TestSuiteResults; + +public class AppScanDynamicReader2Test extends ReaderTestBase { + + private ResultFile resultFile; + + @BeforeEach + void setUp() { + resultFile = + TestHelper.resultFileOf( + "testfiles/Benchmark_1.2-AppScanDynamicReader2-v10.0.6.xml"); + BenchmarkScore.TESTCASENAME = "BenchmarkTest"; + } + + @Test + public void onlyAppScanDynamicReader2ReportsCanReadAsTrue() { + assertOnlyMatcherClassIs(this.resultFile, AppScanDynamicReader2.class); + } + + @Test + void readerHandlesGivenV10ResultFile() throws Exception { + AppScanDynamicReader2 reader = new AppScanDynamicReader2(); + TestSuiteResults result = reader.parse(resultFile); + + assertEquals(TestSuiteResults.ToolType.DAST, result.getToolType()); + assertTrue(result.isCommercial()); + assertEquals("HCL AppScan Dynamic", result.getToolName()); + assertEquals("10.0.6", result.getToolVersion()); + + assertEquals(2, result.getTotalResults()); + + assertEquals(CweNumber.SQL_INJECTION, result.get(1).get(0).getCWE()); + assertEquals(CweNumber.SQL_INJECTION, result.get(2).get(0).getCWE()); + } +} diff --git a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/ArachniReaderTest.java b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/ArachniReaderTest.java new file mode 100644 index 00000000..5ed85fbc --- /dev/null +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/ArachniReaderTest.java @@ -0,0 +1,60 @@ +/** + * OWASP Benchmark Project + * + *

This file is part of the Open Web Application Security Project (OWASP) Benchmark Project For + * details, please see https://owasp.org/www-project-benchmark/. + * + *

The OWASP Benchmark is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Foundation, version 2. + * + *

The OWASP Benchmark is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * @author Sascha Knoop + * @created 2021 + */ +package org.owasp.benchmarkutils.score.parsers; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.CweNumber; +import org.owasp.benchmarkutils.score.ResultFile; +import org.owasp.benchmarkutils.score.TestHelper; +import org.owasp.benchmarkutils.score.TestSuiteResults; + +public class ArachniReaderTest extends ReaderTestBase { + + private ResultFile resultFile; + + @BeforeEach + void setUp() { + resultFile = TestHelper.resultFileOf("testfiles/Benchmark_1.2-Arachni-v2.0dev.xml"); + BenchmarkScore.TESTCASENAME = "BenchmarkTest"; + } + + @Test + public void onlyArachniReaderReportsCanReadAsTrue() { + assertOnlyMatcherClassIs(this.resultFile, ArachniReader.class); + } + + @Test + void readerHandlesGivenResultFile() throws Exception { + ArachniReader reader = new ArachniReader(); + TestSuiteResults result = reader.parse(resultFile); + + assertEquals(TestSuiteResults.ToolType.DAST, result.getToolType()); + assertFalse(result.isCommercial()); + assertEquals("Arachni", result.getToolName()); + + assertEquals(2, result.getTotalResults()); + + assertEquals(CweNumber.XSS, result.get(1).get(0).getCWE()); + assertEquals(CweNumber.XSS, result.get(2).get(0).getCWE()); + } +} diff --git a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/BurpReaderTest.java b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/BurpReaderTest.java new file mode 100644 index 00000000..f05a69ed --- /dev/null +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/BurpReaderTest.java @@ -0,0 +1,60 @@ +/** + * OWASP Benchmark Project + * + *

This file is part of the Open Web Application Security Project (OWASP) Benchmark Project For + * details, please see https://owasp.org/www-project-benchmark/. + * + *

The OWASP Benchmark is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Foundation, version 2. + * + *

The OWASP Benchmark is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * @author Sascha Knoop + * @created 2021 + */ +package org.owasp.benchmarkutils.score.parsers; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.CweNumber; +import org.owasp.benchmarkutils.score.ResultFile; +import org.owasp.benchmarkutils.score.TestHelper; +import org.owasp.benchmarkutils.score.TestSuiteResults; + +public class BurpReaderTest extends ReaderTestBase { + + private ResultFile resultFile; + + @BeforeEach + void setUp() { + resultFile = TestHelper.resultFileOf("testfiles/Benchmark_1.2-BurpPro-v2020.2.1.xml"); + BenchmarkScore.TESTCASENAME = "BenchmarkTest"; + } + + @Test + public void onlyBurpReaderReportsCanReadAsTrue() { + assertOnlyMatcherClassIs(this.resultFile, BurpReader.class); + } + + @Test + void readerHandlesGivenResultFile() throws Exception { + BurpReader reader = new BurpReader(); + TestSuiteResults result = reader.parse(resultFile); + + assertEquals(TestSuiteResults.ToolType.DAST, result.getToolType()); + assertTrue(result.isCommercial()); + assertEquals("Burp Suite Pro", result.getToolName()); + + assertEquals(2, result.getTotalResults()); + + assertEquals(CweNumber.COMMAND_INJECTION, result.get(1).get(0).getCWE()); + assertEquals(CweNumber.SQL_INJECTION, result.get(2).get(0).getCWE()); + } +} diff --git a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/CASTAIPReaderTest.java b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/CASTAIPReaderTest.java new file mode 100644 index 00000000..48dad7ab --- /dev/null +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/CASTAIPReaderTest.java @@ -0,0 +1,60 @@ +/** + * OWASP Benchmark Project + * + *

This file is part of the Open Web Application Security Project (OWASP) Benchmark Project For + * details, please see https://owasp.org/www-project-benchmark/. + * + *

The OWASP Benchmark is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Foundation, version 2. + * + *

The OWASP Benchmark is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * @author Sascha Knoop + * @created 2021 + */ +package org.owasp.benchmarkutils.score.parsers; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.CweNumber; +import org.owasp.benchmarkutils.score.ResultFile; +import org.owasp.benchmarkutils.score.TestHelper; +import org.owasp.benchmarkutils.score.TestSuiteResults; + +public class CASTAIPReaderTest extends ReaderTestBase { + + private ResultFile resultFile; + + @BeforeEach + void setUp() { + resultFile = TestHelper.resultFileOf("testfiles/Benchmark_1.2-CAST_AIP-v8.2.3.xml"); + BenchmarkScore.TESTCASENAME = "BenchmarkTest"; + } + + @Test + public void onlyCASTAIPReaderReportsCanReadAsTrue() { + assertOnlyMatcherClassIs(this.resultFile, CASTAIPReader.class); + } + + @Test + void readerHandlesGivenResultFile() throws Exception { + CASTAIPReader reader = new CASTAIPReader(); + TestSuiteResults result = reader.parse(resultFile); + + assertEquals(TestSuiteResults.ToolType.SAST, result.getToolType()); + assertTrue(result.isCommercial()); + assertEquals("CAST AIP", result.getToolName()); + + assertEquals(2, result.getTotalResults()); + + assertEquals(CweNumber.COMMAND_INJECTION, result.get(1).get(0).getCWE()); + assertEquals(CweNumber.SQL_INJECTION, result.get(2).get(0).getCWE()); + } +} diff --git a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/CheckmarxIASTReaderTest.java b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/CheckmarxIASTReaderTest.java new file mode 100644 index 00000000..1cde8ee1 --- /dev/null +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/CheckmarxIASTReaderTest.java @@ -0,0 +1,60 @@ +/** + * OWASP Benchmark Project + * + *

This file is part of the Open Web Application Security Project (OWASP) Benchmark Project For + * details, please see https://owasp.org/www-project-benchmark/. + * + *

The OWASP Benchmark is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Foundation, version 2. + * + *

The OWASP Benchmark is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * @author Sascha Knoop + * @created 2021 + */ +package org.owasp.benchmarkutils.score.parsers; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.CweNumber; +import org.owasp.benchmarkutils.score.ResultFile; +import org.owasp.benchmarkutils.score.TestHelper; +import org.owasp.benchmarkutils.score.TestSuiteResults; + +public class CheckmarxIASTReaderTest extends ReaderTestBase { + + private ResultFile resultFile; + + @BeforeEach + void setUp() { + resultFile = TestHelper.resultFileOf("testfiles/Benchmark_1.2-CxIAST.csv"); + BenchmarkScore.TESTCASENAME = "BenchmarkTest"; + } + + @Test + public void onlyCheckmarxIASTReaderReportsCanReadAsTrue() { + assertOnlyMatcherClassIs(this.resultFile, CheckmarxIASTReader.class); + } + + @Test + void readerHandlesGivenResultFile() throws Exception { + CheckmarxIASTReader reader = new CheckmarxIASTReader(); + TestSuiteResults result = reader.parse(resultFile); + + assertEquals(TestSuiteResults.ToolType.IAST, result.getToolType()); + assertTrue(result.isCommercial()); + assertEquals("CxIAST", result.getToolName()); + + assertEquals(2, result.getTotalResults()); + + assertEquals(CweNumber.SQL_INJECTION, result.get(1).get(0).getCWE()); + assertEquals(CweNumber.PATH_TRAVERSAL, result.get(2).get(0).getCWE()); + } +} diff --git a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/CheckmarxReaderTest.java b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/CheckmarxReaderTest.java new file mode 100644 index 00000000..acd0f8bf --- /dev/null +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/CheckmarxReaderTest.java @@ -0,0 +1,60 @@ +/** + * OWASP Benchmark Project + * + *

This file is part of the Open Web Application Security Project (OWASP) Benchmark Project For + * details, please see https://owasp.org/www-project-benchmark/. + * + *

The OWASP Benchmark is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Foundation, version 2. + * + *

The OWASP Benchmark is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * @author Sascha Knoop + * @created 2021 + */ +package org.owasp.benchmarkutils.score.parsers; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.CweNumber; +import org.owasp.benchmarkutils.score.ResultFile; +import org.owasp.benchmarkutils.score.TestHelper; +import org.owasp.benchmarkutils.score.TestSuiteResults; + +public class CheckmarxReaderTest extends ReaderTestBase { + + private ResultFile resultFile; + + @BeforeEach + void setUp() { + resultFile = TestHelper.resultFileOf("testfiles/Benchmark_1.2-Checkmarx-v8.2.xml"); + BenchmarkScore.TESTCASENAME = "BenchmarkTest"; + } + + @Test + public void onlyCheckmarxReaderTestReportsCanReadAsTrue() { + assertOnlyMatcherClassIs(this.resultFile, CheckmarxReader.class); + } + + @Test + void readerHandlesGivenResultFile() throws Exception { + CheckmarxReader reader = new CheckmarxReader(); + TestSuiteResults result = reader.parse(resultFile); + + assertEquals(TestSuiteResults.ToolType.SAST, result.getToolType()); + assertTrue(result.isCommercial()); + assertEquals("Checkmarx CxSAST", result.getToolName()); + + assertEquals(2, result.getTotalResults()); + + assertEquals(CweNumber.XSS, result.get(1).get(0).getCWE()); + assertEquals(CweNumber.SQL_INJECTION, result.get(2).get(0).getCWE()); + } +} diff --git a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/CovertyReaderTest.java b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/CovertyReaderTest.java new file mode 100644 index 00000000..b91d5a65 --- /dev/null +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/CovertyReaderTest.java @@ -0,0 +1,60 @@ +/** + * OWASP Benchmark Project + * + *

This file is part of the Open Web Application Security Project (OWASP) Benchmark Project For + * details, please see https://owasp.org/www-project-benchmark/. + * + *

The OWASP Benchmark is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Foundation, version 2. + * + *

The OWASP Benchmark is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * @author Sascha Knoop + * @created 2021 + */ +package org.owasp.benchmarkutils.score.parsers; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.CweNumber; +import org.owasp.benchmarkutils.score.ResultFile; +import org.owasp.benchmarkutils.score.TestHelper; +import org.owasp.benchmarkutils.score.TestSuiteResults; + +public class CovertyReaderTest extends ReaderTestBase { + + private ResultFile resultFile; + + @BeforeEach + void setUp() { + resultFile = TestHelper.resultFileOf("testfiles/Benchmark_1.2-Coverity-v3.0.json"); + BenchmarkScore.TESTCASENAME = "BenchmarkTest"; + } + + @Test + public void onlyCovertyReaderReportsCanReadAsTrue() { + assertOnlyMatcherClassIs(this.resultFile, CoverityReader.class); + } + + @Test + void readerHandlesGivenResultFile() throws Exception { + CoverityReader reader = new CoverityReader(); + TestSuiteResults result = reader.parse(resultFile); + + assertEquals(TestSuiteResults.ToolType.SAST, result.getToolType()); + assertTrue(result.isCommercial()); + assertEquals("Coverity Code Advisor", result.getToolName()); + + assertEquals(2, result.getTotalResults()); + + assertEquals(CweNumber.PATH_TRAVERSAL, result.get(1).get(0).getCWE()); + assertEquals(CweNumber.SQL_INJECTION, result.get(2).get(0).getCWE()); + } +} diff --git a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/FindbugsReaderTest.java b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/FindbugsReaderTest.java new file mode 100644 index 00000000..5160b2c7 --- /dev/null +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/FindbugsReaderTest.java @@ -0,0 +1,84 @@ +/** + * OWASP Benchmark Project + * + *

This file is part of the Open Web Application Security Project (OWASP) Benchmark Project For + * details, please see https://owasp.org/www-project-benchmark/. + * + *

The OWASP Benchmark is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Foundation, version 2. + * + *

The OWASP Benchmark is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * @author Sascha Knoop + * @created 2021 + */ +package org.owasp.benchmarkutils.score.parsers; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.CweNumber; +import org.owasp.benchmarkutils.score.ResultFile; +import org.owasp.benchmarkutils.score.TestHelper; +import org.owasp.benchmarkutils.score.TestSuiteResults; + +public class FindbugsReaderTest extends ReaderTestBase { + + private ResultFile findSecBugsResultFile; + private ResultFile spotBugsResultFile; + + @BeforeEach + void setUp() { + findSecBugsResultFile = + TestHelper.resultFileOf("testfiles/Benchmark_1.2-findsecbugs-v1.11.0-105.xml"); + spotBugsResultFile = + TestHelper.resultFileOf("testfiles/Benchmark_1.2-spotbugs-v4.1.4-104.xml"); + BenchmarkScore.TESTCASENAME = "BenchmarkTest"; + } + + @Test + public void onlyFindbugsReaderReportsCanReadAsTrueForFindSecBugsFile() { + assertOnlyMatcherClassIs(this.findSecBugsResultFile, FindbugsReader.class); + } + + @Test + public void onlyFindbugsReaderReportsCanReadAsTrueForSpotBugsFile() { + assertOnlyMatcherClassIs(this.spotBugsResultFile, FindbugsReader.class); + } + + @Test + void readerHandlesGivenFindSecBugsResultFile() throws Exception { + FindbugsReader reader = new FindbugsReader(); + TestSuiteResults result = reader.parse(findSecBugsResultFile); + + assertEquals(TestSuiteResults.ToolType.SAST, result.getToolType()); + assertFalse(result.isCommercial()); + assertEquals("SBwFindSecBugs", result.getToolName()); + + assertEquals(2, result.getTotalResults()); + + assertEquals(CweNumber.XSS, result.get(1).get(0).getCWE()); + assertEquals(CweNumber.SQL_INJECTION, result.get(2).get(0).getCWE()); + } + + @Test + void readerHandlesGivenSpotBugsResultFile() throws Exception { + FindbugsReader reader = new FindbugsReader(); + TestSuiteResults result = reader.parse(spotBugsResultFile); + + assertEquals(TestSuiteResults.ToolType.SAST, result.getToolType()); + assertFalse(result.isCommercial()); + assertEquals("SpotBugs", result.getToolName()); + + assertEquals(2, result.getTotalResults()); + + assertEquals(CweNumber.SQL_INJECTION, result.get(1).get(0).getCWE()); + assertEquals(CweNumber.PATH_TRAVERSAL, result.get(2).get(0).getCWE()); + } +} diff --git a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/FortifyReaderTest.java b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/FortifyReaderTest.java new file mode 100644 index 00000000..6f48e7a5 --- /dev/null +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/FortifyReaderTest.java @@ -0,0 +1,62 @@ +/** + * OWASP Benchmark Project + * + *

This file is part of the Open Web Application Security Project (OWASP) Benchmark Project For + * details, please see https://owasp.org/www-project-benchmark/. + * + *

The OWASP Benchmark is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Foundation, version 2. + * + *

The OWASP Benchmark is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * @author Sascha Knoop + * @created 2021 + */ +package org.owasp.benchmarkutils.score.parsers; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.CweNumber; +import org.owasp.benchmarkutils.score.ResultFile; +import org.owasp.benchmarkutils.score.TestHelper; +import org.owasp.benchmarkutils.score.TestSuiteResults; + +public class FortifyReaderTest extends ReaderTestBase { + + private ResultFile resultFile; + + @BeforeEach + void setUp() { + resultFile = + TestHelper.resultFileOf("testfiles/Benchmark_1.2-Fortify20.20_2020Q1-1234.fpr"); + BenchmarkScore.TESTCASENAME = "BenchmarkTest"; + } + + @Test + public void onlyFortifyReaderReportsCanReadAsTrue() { + assertOnlyMatcherClassIs(this.resultFile, FortifyReader.class); + } + + @Test + void readerHandlesGivenResultFile() throws Exception { + FortifyReader reader = new FortifyReader(); + TestSuiteResults result = reader.parse(resultFile); + + assertEquals(TestSuiteResults.ToolType.SAST, result.getToolType()); + assertTrue(result.isCommercial()); + assertEquals("Fortify", result.getToolName()); + assertEquals("0:20:34", result.getTime()); + + assertEquals(2, result.getTotalResults()); + + assertEquals(CweNumber.COMMAND_INJECTION, result.get(1).get(0).getCWE()); + assertEquals(CweNumber.SQL_INJECTION, result.get(2).get(0).getCWE()); + } +} diff --git a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/HCLReaderTest.java b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/HCLReaderTest.java new file mode 100644 index 00000000..341fa90c --- /dev/null +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/HCLReaderTest.java @@ -0,0 +1,60 @@ +/** + * OWASP Benchmark Project + * + *

This file is part of the Open Web Application Security Project (OWASP) Benchmark Project For + * details, please see https://owasp.org/www-project-benchmark/. + * + *

The OWASP Benchmark is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Foundation, version 2. + * + *

The OWASP Benchmark is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * @author Sascha Knoop + * @created 2021 + */ +package org.owasp.benchmarkutils.score.parsers; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.CweNumber; +import org.owasp.benchmarkutils.score.ResultFile; +import org.owasp.benchmarkutils.score.TestHelper; +import org.owasp.benchmarkutils.score.TestSuiteResults; + +public class HCLReaderTest extends ReaderTestBase { + + private ResultFile resultFile; + + @BeforeEach + void setUp() { + resultFile = TestHelper.resultFileOf("testfiles/Benchmark_1.2_HCL-IAST.hcl"); + BenchmarkScore.TESTCASENAME = "BenchmarkTest"; + } + + @Test + public void onlyHCLReaderReportsCanReadAsTrue() { + assertOnlyMatcherClassIs(this.resultFile, HCLReader.class); + } + + @Test + void readerHandlesGivenResultFile() throws Exception { + HCLReader reader = new HCLReader(); + TestSuiteResults result = reader.parse(resultFile); + + assertEquals(TestSuiteResults.ToolType.IAST, result.getToolType()); + assertTrue(result.isCommercial()); + assertEquals("HCL IAST", result.getToolName()); + + assertEquals(2, result.getTotalResults()); + + assertEquals(CweNumber.PATH_TRAVERSAL, result.get(1).get(0).getCWE()); + assertEquals(CweNumber.SQL_INJECTION, result.get(2).get(0).getCWE()); + } +} diff --git a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/HdivReaderTest.java b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/HdivReaderTest.java new file mode 100644 index 00000000..8f418d4f --- /dev/null +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/HdivReaderTest.java @@ -0,0 +1,60 @@ +/** + * OWASP Benchmark Project + * + *

This file is part of the Open Web Application Security Project (OWASP) Benchmark Project For + * details, please see https://owasp.org/www-project-benchmark/. + * + *

The OWASP Benchmark is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Foundation, version 2. + * + *

The OWASP Benchmark is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * @author Sascha Knoop + * @created 2021 + */ +package org.owasp.benchmarkutils.score.parsers; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.CweNumber; +import org.owasp.benchmarkutils.score.ResultFile; +import org.owasp.benchmarkutils.score.TestHelper; +import org.owasp.benchmarkutils.score.TestSuiteResults; + +public class HdivReaderTest extends ReaderTestBase { + + private ResultFile resultFile; + + @BeforeEach + void setUp() { + resultFile = TestHelper.resultFileOf("testfiles/Benchmark_1.2-hdivAgentLog.hlg"); + BenchmarkScore.TESTCASENAME = "BenchmarkTest"; + } + + @Test + public void onlyHdivReaderReportsCanReadAsTrue() { + assertOnlyMatcherClassIs(this.resultFile, HdivReader.class); + } + + @Test + void readerHandlesGivenResultFile() throws Exception { + HdivReader reader = new HdivReader(); + TestSuiteResults result = reader.parse(resultFile); + + assertEquals(TestSuiteResults.ToolType.IAST, result.getToolType()); + assertTrue(result.isCommercial()); + assertEquals("Hdiv", result.getToolName()); + + assertEquals(2, result.getTotalResults()); + + assertEquals(CweNumber.PATH_TRAVERSAL, result.get(1).get(0).getCWE()); + assertEquals(CweNumber.REVERSIBLE_HASH, result.get(2).get(0).getCWE()); + } +} diff --git a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/HorusecReaderTest.java b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/HorusecReaderTest.java new file mode 100644 index 00000000..9662ab51 --- /dev/null +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/HorusecReaderTest.java @@ -0,0 +1,62 @@ +/** + * OWASP Benchmark Project + * + *

This file is part of the Open Web Application Security Project (OWASP) Benchmark Project For + * details, please see https://owasp.org/www-project-benchmark/. + * + *

The OWASP Benchmark is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Foundation, version 2. + * + *

The OWASP Benchmark is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * @author Sascha Knoop + * @created 2021 + */ +package org.owasp.benchmarkutils.score.parsers; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.CweNumber; +import org.owasp.benchmarkutils.score.ResultFile; +import org.owasp.benchmarkutils.score.TestHelper; +import org.owasp.benchmarkutils.score.TestSuiteResults; + +public class HorusecReaderTest extends ReaderTestBase { + + private ResultFile resultFile; + + @BeforeEach + void setUp() { + resultFile = TestHelper.resultFileOf("testfiles/Benchmark_1.2-horusec-v2.5.0.json"); + BenchmarkScore.TESTCASENAME = "BenchmarkTest"; + } + + @Test + public void onlyHorusecReaderReportsCanReadAsTrue() { + assertOnlyMatcherClassIs(this.resultFile, HorusecReader.class); + } + + @Test + void readerHandlesGivenResultFile() throws Exception { + HorusecReader reader = new HorusecReader(); + TestSuiteResults result = reader.parse(resultFile); + + assertEquals(TestSuiteResults.ToolType.SAST, result.getToolType()); + assertFalse(result.isCommercial()); + assertEquals("Horusec", result.getToolName()); + assertEquals("1:23:45", result.getTime()); + assertEquals("v2.5.0", result.getToolVersion()); + + assertEquals(2, result.getTotalResults()); + + assertEquals(CweNumber.XSS, result.get(1).get(0).getCWE()); + assertEquals(CweNumber.SQL_INJECTION, result.get(2).get(0).getCWE()); + } +} diff --git a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/InsiderReaderTest.java b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/InsiderReaderTest.java new file mode 100644 index 00000000..1a703562 --- /dev/null +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/InsiderReaderTest.java @@ -0,0 +1,60 @@ +/** + * OWASP Benchmark Project + * + *

This file is part of the Open Web Application Security Project (OWASP) Benchmark Project For + * details, please see https://owasp.org/www-project-benchmark/. + * + *

The OWASP Benchmark is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Foundation, version 2. + * + *

The OWASP Benchmark is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * @author Sascha Knoop + * @created 2021 + */ +package org.owasp.benchmarkutils.score.parsers; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.CweNumber; +import org.owasp.benchmarkutils.score.ResultFile; +import org.owasp.benchmarkutils.score.TestHelper; +import org.owasp.benchmarkutils.score.TestSuiteResults; + +public class InsiderReaderTest extends ReaderTestBase { + + private ResultFile resultFile; + + @BeforeEach + void setUp() { + resultFile = TestHelper.resultFileOf("testfiles/Benchmark_1.2-insider-v3.0.0.json"); + BenchmarkScore.TESTCASENAME = "BenchmarkTest"; + } + + @Test + public void onlyInsiderReaderReportsCanReadAsTrue() { + assertOnlyMatcherClassIs(this.resultFile, InsiderReader.class); + } + + @Test + void readerHandlesGivenResultFile() throws Exception { + InsiderReader reader = new InsiderReader(); + TestSuiteResults result = reader.parse(resultFile); + + assertEquals(TestSuiteResults.ToolType.SAST, result.getToolType()); + assertFalse(result.isCommercial()); + assertEquals("Insider", result.getToolName()); + + assertEquals(2, result.getTotalResults()); + + assertEquals(CweNumber.COMMAND_INJECTION, result.get(1).get(0).getCWE()); + assertEquals(CweNumber.BROKEN_CRYPTO, result.get(2).get(0).getCWE()); + } +} diff --git a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/JuliaReaderTest.java b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/JuliaReaderTest.java new file mode 100644 index 00000000..9581fecd --- /dev/null +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/JuliaReaderTest.java @@ -0,0 +1,60 @@ +/** + * OWASP Benchmark Project + * + *

This file is part of the Open Web Application Security Project (OWASP) Benchmark Project For + * details, please see https://owasp.org/www-project-benchmark/. + * + *

The OWASP Benchmark is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Foundation, version 2. + * + *

The OWASP Benchmark is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * @author Sascha Knoop + * @created 2021 + */ +package org.owasp.benchmarkutils.score.parsers; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.CweNumber; +import org.owasp.benchmarkutils.score.ResultFile; +import org.owasp.benchmarkutils.score.TestHelper; +import org.owasp.benchmarkutils.score.TestSuiteResults; + +public class JuliaReaderTest extends ReaderTestBase { + + private ResultFile resultFile; + + @BeforeEach + void setUp() { + resultFile = TestHelper.resultFileOf("testfiles/Benchmark_1.2-JuliaSoft-v2.3.2.1.xml"); + BenchmarkScore.TESTCASENAME = "BenchmarkTest"; + } + + @Test + public void onlyJuliaReaderReportsCanReadAsTrue() { + assertOnlyMatcherClassIs(this.resultFile, JuliaReader.class); + } + + @Test + void readerHandlesGivenResultFile() throws Exception { + JuliaReader reader = new JuliaReader(); + TestSuiteResults result = reader.parse(resultFile); + + assertEquals(TestSuiteResults.ToolType.SAST, result.getToolType()); + assertTrue(result.isCommercial()); + assertEquals("Julia", result.getToolName()); + + assertEquals(2, result.getTotalResults()); + + assertEquals(CweNumber.INSECURE_COOKIE, result.get(1).get(0).getCWE()); + assertEquals(CweNumber.BROKEN_CRYPTO, result.get(2).get(0).getCWE()); + } +} diff --git a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/KiuwanReaderTest.java b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/KiuwanReaderTest.java new file mode 100644 index 00000000..002de909 --- /dev/null +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/KiuwanReaderTest.java @@ -0,0 +1,62 @@ +/** + * OWASP Benchmark Project + * + *

This file is part of the Open Web Application Security Project (OWASP) Benchmark Project For + * details, please see https://owasp.org/www-project-benchmark/. + * + *

The OWASP Benchmark is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Foundation, version 2. + * + *

The OWASP Benchmark is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * @author Sascha Knoop + * @created 2021 + */ +package org.owasp.benchmarkutils.score.parsers; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.CweNumber; +import org.owasp.benchmarkutils.score.ResultFile; +import org.owasp.benchmarkutils.score.TestHelper; +import org.owasp.benchmarkutils.score.TestSuiteResults; + +public class KiuwanReaderTest extends ReaderTestBase { + + private ResultFile resultFile; + + @BeforeEach + void setUp() { + resultFile = TestHelper.resultFileOf("testfiles/Benchmark_1.2-Kiuwan-20191012.threadfix"); + BenchmarkScore.TESTCASENAME = "BenchmarkTest"; + } + + @Test + public void onlyKiuwanReaderReportsCanReadAsTrue() { + assertOnlyMatcherClassIs(this.resultFile, KiuwanReader.class); + } + + @Test + void readerHandlesGivenResultFile() throws Exception { + KiuwanReader reader = new KiuwanReader(); + TestSuiteResults result = reader.parse(resultFile); + + assertEquals(TestSuiteResults.ToolType.SAST, result.getToolType()); + assertTrue(result.isCommercial()); + assertEquals("Kiuwan", result.getToolName()); + assertEquals("some.version", result.getToolVersion()); + assertEquals("01:23:45", result.getTime()); + + assertEquals(2, result.getTotalResults()); + + assertEquals(CweNumber.XSS, result.get(1).get(0).getCWE()); + assertEquals(CweNumber.SQL_INJECTION, result.get(2).get(0).getCWE()); + } +} diff --git a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/NetsparkerReaderTest.java b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/NetsparkerReaderTest.java new file mode 100644 index 00000000..684220da --- /dev/null +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/NetsparkerReaderTest.java @@ -0,0 +1,60 @@ +/** + * OWASP Benchmark Project + * + *

This file is part of the Open Web Application Security Project (OWASP) Benchmark Project For + * details, please see https://owasp.org/www-project-benchmark/. + * + *

The OWASP Benchmark is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Foundation, version 2. + * + *

The OWASP Benchmark is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * @author Sascha Knoop + * @created 2021 + */ +package org.owasp.benchmarkutils.score.parsers; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.CweNumber; +import org.owasp.benchmarkutils.score.ResultFile; +import org.owasp.benchmarkutils.score.TestHelper; +import org.owasp.benchmarkutils.score.TestSuiteResults; + +public class NetsparkerReaderTest extends ReaderTestBase { + + private ResultFile resultFile; + + @BeforeEach + void setUp() { + resultFile = TestHelper.resultFileOf("testfiles/Benchmark_1.2-Netsparker.xml"); + BenchmarkScore.TESTCASENAME = "BenchmarkTest"; + } + + @Test + public void onlyNetsparkerReaderReportsCanReadAsTrue() { + assertOnlyMatcherClassIs(this.resultFile, NetsparkerReader.class); + } + + @Test + void readerHandlesGivenResultFile() throws Exception { + NetsparkerReader reader = new NetsparkerReader(); + TestSuiteResults result = reader.parse(resultFile); + + assertEquals(TestSuiteResults.ToolType.DAST, result.getToolType()); + assertTrue(result.isCommercial()); + assertEquals("Netsparker", result.getToolName()); + + assertEquals(2, result.getTotalResults()); + + assertEquals(CweNumber.INSECURE_COOKIE, result.get(1).get(0).getCWE()); + assertEquals(CweNumber.COOKIE_WITHOUT_HTTPONLY, result.get(2).get(0).getCWE()); + } +} diff --git a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/ParasoftReaderTest.java b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/ParasoftReaderTest.java new file mode 100644 index 00000000..6491fed9 --- /dev/null +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/ParasoftReaderTest.java @@ -0,0 +1,61 @@ +/** + * OWASP Benchmark Project + * + *

This file is part of the Open Web Application Security Project (OWASP) Benchmark Project For + * details, please see https://owasp.org/www-project-benchmark/. + * + *

The OWASP Benchmark is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Foundation, version 2. + * + *

The OWASP Benchmark is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * @author Sascha Knoop + * @created 2021 + */ +package org.owasp.benchmarkutils.score.parsers; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.CweNumber; +import org.owasp.benchmarkutils.score.ResultFile; +import org.owasp.benchmarkutils.score.TestHelper; +import org.owasp.benchmarkutils.score.TestSuiteResults; + +public class ParasoftReaderTest extends ReaderTestBase { + + private ResultFile resultFile; + + @BeforeEach + void setUp() { + resultFile = TestHelper.resultFileOf("testfiles/Benchmark_1.2-ParasoftJTest-v10.2.3.xml"); + BenchmarkScore.TESTCASENAME = "BenchmarkTest"; + } + + @Test + public void onlyParasoftReaderReportsCanReadAsTrue() { + assertOnlyMatcherClassIs(this.resultFile, ParasoftReader.class); + } + + @Test + void readerHandlesGivenResultFile() throws Exception { + ParasoftReader reader = new ParasoftReader(); + TestSuiteResults result = reader.parse(resultFile); + + assertEquals(TestSuiteResults.ToolType.SAST, result.getToolType()); + assertTrue(result.isCommercial()); + assertEquals("Parasoft Jtest", result.getToolName()); + assertEquals("0:12:34", result.getTime()); + + assertEquals(2, result.getTotalResults()); + + assertEquals(CweNumber.PATH_TRAVERSAL, result.get(1).get(0).getCWE()); + assertEquals(CweNumber.XSS, result.get(2).get(0).getCWE()); + } +} diff --git a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/ReaderTestBase.java b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/ReaderTestBase.java new file mode 100644 index 00000000..95598366 --- /dev/null +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/ReaderTestBase.java @@ -0,0 +1,22 @@ +package org.owasp.benchmarkutils.score.parsers; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.List; +import java.util.stream.Collectors; +import org.owasp.benchmarkutils.score.ResultFile; + +public abstract class ReaderTestBase { + + void assertOnlyMatcherClassIs(ResultFile resultFile, Class c) { + List readers = + Reader.allReaders().stream() + .filter(r -> r.canRead(resultFile)) + .collect(Collectors.toList()); + + assertEquals(1, readers.size()); + + assertTrue(readers.get(0).getClass().isAssignableFrom(c)); + } +} diff --git a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/SemgrepReaderTest.java b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/SemgrepReaderTest.java new file mode 100644 index 00000000..17f80c26 --- /dev/null +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/SemgrepReaderTest.java @@ -0,0 +1,60 @@ +/** + * OWASP Benchmark Project + * + *

This file is part of the Open Web Application Security Project (OWASP) Benchmark Project For + * details, please see https://owasp.org/www-project-benchmark/. + * + *

The OWASP Benchmark is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Foundation, version 2. + * + *

The OWASP Benchmark is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * @author Sascha Knoop + * @created 2021 + */ +package org.owasp.benchmarkutils.score.parsers; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.CweNumber; +import org.owasp.benchmarkutils.score.ResultFile; +import org.owasp.benchmarkutils.score.TestHelper; +import org.owasp.benchmarkutils.score.TestSuiteResults; + +public class SemgrepReaderTest extends ReaderTestBase { + + private ResultFile resultFile; + + @BeforeEach + void setUp() { + resultFile = TestHelper.resultFileOf("testfiles/Benchmark_1.2-semgrep-v0.65.0.json"); + BenchmarkScore.TESTCASENAME = "BenchmarkTest"; + } + + @Test + public void onlySemgrepReaderReportsCanReadAsTrue() { + assertOnlyMatcherClassIs(this.resultFile, SemgrepReader.class); + } + + @Test + void readerHandlesGivenResultFile() throws Exception { + SemgrepReader reader = new SemgrepReader(); + TestSuiteResults result = reader.parse(resultFile); + + assertEquals(TestSuiteResults.ToolType.SAST, result.getToolType()); + assertFalse(result.isCommercial()); + assertEquals("Semgrep", result.getToolName()); + + assertEquals(2, result.getTotalResults()); + + assertEquals(CweNumber.SQL_INJECTION, result.get(1).get(0).getCWE()); + assertEquals(CweNumber.INSECURE_COOKIE, result.get(2).get(0).getCWE()); + } +} diff --git a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/ShiftLeftScanReaderTest.java b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/ShiftLeftScanReaderTest.java new file mode 100644 index 00000000..f9f62232 --- /dev/null +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/ShiftLeftScanReaderTest.java @@ -0,0 +1,60 @@ +/** + * OWASP Benchmark Project + * + *

This file is part of the Open Web Application Security Project (OWASP) Benchmark Project For + * details, please see https://owasp.org/www-project-benchmark/. + * + *

The OWASP Benchmark is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Foundation, version 2. + * + *

The OWASP Benchmark is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * @author Sascha Knoop + * @created 2021 + */ +package org.owasp.benchmarkutils.score.parsers; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.CweNumber; +import org.owasp.benchmarkutils.score.ResultFile; +import org.owasp.benchmarkutils.score.TestHelper; +import org.owasp.benchmarkutils.score.TestSuiteResults; + +public class ShiftLeftScanReaderTest extends ReaderTestBase { + + private ResultFile resultFile; + + @BeforeEach + void setUp() { + resultFile = TestHelper.resultFileOf("testfiles/Benchmark_1.2-shiftleftscan-v2.0.3.json"); + BenchmarkScore.TESTCASENAME = "BenchmarkTest"; + } + + @Test + public void onlyShiftLeftScanReaderReportsCanReadAsTrue() { + assertOnlyMatcherClassIs(this.resultFile, ShiftLeftScanReader.class); + } + + @Test + void readerHandlesGivenResultFile() throws Exception { + ShiftLeftScanReader reader = new ShiftLeftScanReader(); + TestSuiteResults result = reader.parse(resultFile); + + assertEquals(TestSuiteResults.ToolType.SAST, result.getToolType()); + assertFalse(result.isCommercial()); + assertEquals("ShiftLeft Scan", result.getToolName()); + + assertEquals(2, result.getTotalResults()); + + assertEquals(CweNumber.COOKIE_WITHOUT_HTTPONLY, result.get(1).get(0).getCWE()); + assertEquals(CweNumber.PATH_TRAVERSAL, result.get(2).get(0).getCWE()); + } +} diff --git a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/SonarQubeJsonReaderTest.java b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/SonarQubeJsonReaderTest.java new file mode 100644 index 00000000..7262e4e8 --- /dev/null +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/SonarQubeJsonReaderTest.java @@ -0,0 +1,60 @@ +/** + * OWASP Benchmark Project + * + *

This file is part of the Open Web Application Security Project (OWASP) Benchmark Project For + * details, please see https://owasp.org/www-project-benchmark/. + * + *

The OWASP Benchmark is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Foundation, version 2. + * + *

The OWASP Benchmark is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * @author Sascha Knoop + * @created 2021 + */ +package org.owasp.benchmarkutils.score.parsers; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.CweNumber; +import org.owasp.benchmarkutils.score.ResultFile; +import org.owasp.benchmarkutils.score.TestHelper; +import org.owasp.benchmarkutils.score.TestSuiteResults; + +public class SonarQubeJsonReaderTest extends ReaderTestBase { + + private ResultFile resultFile; + + @BeforeEach + void setUp() { + resultFile = TestHelper.resultFileOf("testfiles/Benchmark_1.2-sonarqube-v9.1.0.47736.json"); + BenchmarkScore.TESTCASENAME = "BenchmarkTest"; + } + + @Test + public void onlySonarQubeJsonReaderReportsCanReadAsTrue() { + assertOnlyMatcherClassIs(this.resultFile, SonarQubeJsonReader.class); + } + + @Test + void readerHandlesGivenResultFile() throws Exception { + SonarQubeJsonReader reader = new SonarQubeJsonReader(); + TestSuiteResults result = reader.parse(resultFile); + + assertEquals(TestSuiteResults.ToolType.SAST, result.getToolType()); + assertFalse(result.isCommercial()); + assertEquals("SonarQube", result.getToolName()); + + assertEquals(2, result.getTotalResults()); + + assertEquals(CweNumber.BROKEN_CRYPTO, result.get(1).get(0).getCWE()); + assertEquals(CweNumber.SQL_INJECTION, result.get(2).get(0).getCWE()); + } +} diff --git a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/SonarQubeReaderTest.java b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/SonarQubeReaderTest.java new file mode 100644 index 00000000..2f58a36b --- /dev/null +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/SonarQubeReaderTest.java @@ -0,0 +1,62 @@ +/** + * OWASP Benchmark Project + * + *

This file is part of the Open Web Application Security Project (OWASP) Benchmark Project For + * details, please see https://owasp.org/www-project-benchmark/. + * + *

The OWASP Benchmark is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Foundation, version 2. + * + *

The OWASP Benchmark is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * @author Sascha Knoop + * @created 2021 + */ +package org.owasp.benchmarkutils.score.parsers; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.CweNumber; +import org.owasp.benchmarkutils.score.ResultFile; +import org.owasp.benchmarkutils.score.TestHelper; +import org.owasp.benchmarkutils.score.TestSuiteResults; + +public class SonarQubeReaderTest extends ReaderTestBase { + + private ResultFile pluginResultFile; + + @BeforeEach + void setUp() { + pluginResultFile = + TestHelper.resultFileOf("testfiles/Benchmark_1.2-sonar-Java-Plugin-v3.14-1234.xml"); + BenchmarkScore.TESTCASENAME = "BenchmarkTest"; + } + + @Test + public void onlySonarQubeReaderReportsCanReadAsTrueForPluginResultFile() { + assertOnlyMatcherClassIs(this.pluginResultFile, SonarQubeReader.class); + } + + @Test + void readerHandlesGivenPluginResultFile() throws Exception { + SonarQubeReader reader = new SonarQubeReader(); + TestSuiteResults result = reader.parse(pluginResultFile); + + assertEquals(TestSuiteResults.ToolType.SAST, result.getToolType()); + assertFalse(result.isCommercial()); + assertEquals("SonarQube Java Plugin", result.getToolName()); + assertEquals("0:20:34", result.getTime()); + + assertEquals(2, result.getTotalResults()); + + assertEquals(CweNumber.COMMAND_INJECTION, result.get(1).get(0).getCWE()); + assertEquals(CweNumber.WEAK_RANDOM, result.get(2).get(0).getCWE()); + } +} diff --git a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/VisualCodeGrepperReaderTest.java b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/VisualCodeGrepperReaderTest.java new file mode 100644 index 00000000..129269e7 --- /dev/null +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/VisualCodeGrepperReaderTest.java @@ -0,0 +1,61 @@ +/** + * OWASP Benchmark Project + * + *

This file is part of the Open Web Application Security Project (OWASP) Benchmark Project For + * details, please see https://owasp.org/www-project-benchmark/. + * + *

The OWASP Benchmark is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Foundation, version 2. + * + *

The OWASP Benchmark is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * @author Sascha Knoop + * @created 2021 + */ +package org.owasp.benchmarkutils.score.parsers; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.CweNumber; +import org.owasp.benchmarkutils.score.ResultFile; +import org.owasp.benchmarkutils.score.TestHelper; +import org.owasp.benchmarkutils.score.TestSuiteResults; + +public class VisualCodeGrepperReaderTest extends ReaderTestBase { + + private ResultFile resultFile; + + @BeforeEach + void setUp() { + resultFile = + TestHelper.resultFileOf("testfiles/Benchmark_1.2-visualcodegrepper-v2.2.0.xml"); + BenchmarkScore.TESTCASENAME = "BenchmarkTest"; + } + + @Test + public void onlyFindbugsReaderReportsCanReadAsTrue() { + assertOnlyMatcherClassIs(this.resultFile, VisualCodeGrepperReader.class); + } + + @Test + void readerHandlesGivenResultFile() throws Exception { + VisualCodeGrepperReader reader = new VisualCodeGrepperReader(); + TestSuiteResults result = reader.parse(resultFile); + + assertEquals(TestSuiteResults.ToolType.SAST, result.getToolType()); + assertFalse(result.isCommercial()); + assertEquals("VisualCodeGrepper", result.getToolName()); + + assertEquals(2, result.getTotalResults()); + + assertEquals(CweNumber.SQL_INJECTION, result.get(1).get(0).getCWE()); + assertEquals(CweNumber.XSS, result.get(2).get(0).getCWE()); + } +} diff --git a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/W3AFReaderTest.java b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/W3AFReaderTest.java new file mode 100644 index 00000000..aee29b19 --- /dev/null +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/W3AFReaderTest.java @@ -0,0 +1,60 @@ +/** + * OWASP Benchmark Project + * + *

This file is part of the Open Web Application Security Project (OWASP) Benchmark Project For + * details, please see https://owasp.org/www-project-benchmark/. + * + *

The OWASP Benchmark is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Foundation, version 2. + * + *

The OWASP Benchmark is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * @author Sascha Knoop + * @created 2021 + */ +package org.owasp.benchmarkutils.score.parsers; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.CweNumber; +import org.owasp.benchmarkutils.score.ResultFile; +import org.owasp.benchmarkutils.score.TestHelper; +import org.owasp.benchmarkutils.score.TestSuiteResults; + +public class W3AFReaderTest extends ReaderTestBase { + + private ResultFile resultFile; + + @BeforeEach + void setUp() { + resultFile = TestHelper.resultFileOf("testfiles/Benchmark_1.2-w3af-v1.7.6.xml"); + BenchmarkScore.TESTCASENAME = "BenchmarkTest"; + } + + @Test + public void onlyW3AFReaderReportsCanReadAsTrue() { + assertOnlyMatcherClassIs(this.resultFile, W3AFReader.class); + } + + @Test + void readerHandlesGivenResultFile() throws Exception { + W3AFReader reader = new W3AFReader(); + TestSuiteResults result = reader.parse(resultFile); + + assertEquals(TestSuiteResults.ToolType.DAST, result.getToolType()); + assertFalse(result.isCommercial()); + assertEquals("W3AF", result.getToolName()); + + assertEquals(2, result.getTotalResults()); + + assertEquals(CweNumber.XSS, result.get(1).get(0).getCWE()); + assertEquals(CweNumber.XSS, result.get(2).get(0).getCWE()); + } +} diff --git a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/WapitiJsonReaderTest.java b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/WapitiJsonReaderTest.java new file mode 100644 index 00000000..d6887e7e --- /dev/null +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/WapitiJsonReaderTest.java @@ -0,0 +1,60 @@ +/** + * OWASP Benchmark Project + * + *

This file is part of the Open Web Application Security Project (OWASP) Benchmark Project For + * details, please see https://owasp.org/www-project-benchmark/. + * + *

The OWASP Benchmark is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Foundation, version 2. + * + *

The OWASP Benchmark is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * @author Sascha Knoop + * @created 2021 + */ +package org.owasp.benchmarkutils.score.parsers; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.CweNumber; +import org.owasp.benchmarkutils.score.ResultFile; +import org.owasp.benchmarkutils.score.TestHelper; +import org.owasp.benchmarkutils.score.TestSuiteResults; + +public class WapitiJsonReaderTest extends ReaderTestBase { + + private ResultFile resultFile; + + @BeforeEach + void setUp() { + resultFile = TestHelper.resultFileOf("testfiles/Benchmark_1.2-wapiti-v3.0.5.json"); + BenchmarkScore.TESTCASENAME = "BenchmarkTest"; + } + + @Test + public void onlyWapitiJsonReaderReportsCanReadAsTrue() { + assertOnlyMatcherClassIs(this.resultFile, WapitiJsonReader.class); + } + + @Test + void readerHandlesGivenResultFile() throws Exception { + WapitiJsonReader reader = new WapitiJsonReader(); + TestSuiteResults result = reader.parse(resultFile); + + assertEquals(TestSuiteResults.ToolType.DAST, result.getToolType()); + assertFalse(result.isCommercial()); + assertEquals("Wapiti", result.getToolName()); + + assertEquals(2, result.getTotalResults()); + + assertEquals(CweNumber.COMMAND_INJECTION, result.get(1).get(0).getCWE()); + assertEquals(CweNumber.PATH_TRAVERSAL, result.get(2).get(0).getCWE()); + } +} diff --git a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/WapitiReaderTest.java b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/WapitiReaderTest.java new file mode 100644 index 00000000..fda99bf1 --- /dev/null +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/WapitiReaderTest.java @@ -0,0 +1,60 @@ +/** + * OWASP Benchmark Project + * + *

This file is part of the Open Web Application Security Project (OWASP) Benchmark Project For + * details, please see https://owasp.org/www-project-benchmark/. + * + *

The OWASP Benchmark is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Foundation, version 2. + * + *

The OWASP Benchmark is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * @author Sascha Knoop + * @created 2021 + */ +package org.owasp.benchmarkutils.score.parsers; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.CweNumber; +import org.owasp.benchmarkutils.score.ResultFile; +import org.owasp.benchmarkutils.score.TestHelper; +import org.owasp.benchmarkutils.score.TestSuiteResults; + +public class WapitiReaderTest extends ReaderTestBase { + + private ResultFile resultFile; + + @BeforeEach + void setUp() { + resultFile = TestHelper.resultFileOf("testfiles/Benchmark_1.2-Wapiti-v3.0.3.xml"); + BenchmarkScore.TESTCASENAME = "BenchmarkTest"; + } + + @Test + public void onlyWapitiReaderReportsCanReadAsTrue() { + assertOnlyMatcherClassIs(this.resultFile, WapitiReader.class); + } + + @Test + void readerHandlesGivenResultFile() throws Exception { + WapitiReader reader = new WapitiReader(); + TestSuiteResults result = reader.parse(resultFile); + + assertEquals(TestSuiteResults.ToolType.DAST, result.getToolType()); + assertFalse(result.isCommercial()); + assertEquals("Wapiti", result.getToolName()); + + assertEquals(2, result.getTotalResults()); + + assertEquals(CweNumber.SQL_INJECTION, result.get(1).get(0).getCWE()); + assertEquals(CweNumber.COMMAND_INJECTION, result.get(2).get(0).getCWE()); + } +} diff --git a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/ZapJsonReaderTest.java b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/ZapJsonReaderTest.java new file mode 100644 index 00000000..a7ece5d7 --- /dev/null +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/ZapJsonReaderTest.java @@ -0,0 +1,60 @@ +/** + * OWASP Benchmark Project + * + *

This file is part of the Open Web Application Security Project (OWASP) Benchmark Project For + * details, please see https://owasp.org/www-project-benchmark/. + * + *

The OWASP Benchmark is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Foundation, version 2. + * + *

The OWASP Benchmark is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * @author Sascha Knoop + * @created 2021 + */ +package org.owasp.benchmarkutils.score.parsers; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.CweNumber; +import org.owasp.benchmarkutils.score.ResultFile; +import org.owasp.benchmarkutils.score.TestHelper; +import org.owasp.benchmarkutils.score.TestSuiteResults; + +public class ZapJsonReaderTest extends ReaderTestBase { + + private ResultFile resultFile; + + @BeforeEach + void setUp() { + resultFile = TestHelper.resultFileOf("testfiles/Benchmark_1.2-ZAP-v2.10.0.json"); + BenchmarkScore.TESTCASENAME = "BenchmarkTest"; + } + + @Test + public void onlyZapJsonReaderReportsCanReadAsTrue() { + assertOnlyMatcherClassIs(this.resultFile, ZapJsonReader.class); + } + + @Test + void readerHandlesGivenResultFile() throws Exception { + ZapJsonReader reader = new ZapJsonReader(); + TestSuiteResults result = reader.parse(resultFile); + + assertEquals(TestSuiteResults.ToolType.DAST, result.getToolType()); + assertFalse(result.isCommercial()); + assertEquals("OWASP ZAP", result.getToolName()); + + assertEquals(2, result.getTotalResults()); + + assertEquals(CweNumber.PATH_TRAVERSAL, result.get(1).get(0).getCWE()); + assertEquals(CweNumber.XSS, result.get(2).get(0).getCWE()); + } +} diff --git a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/ZapReaderTest.java b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/ZapReaderTest.java new file mode 100644 index 00000000..dae50402 --- /dev/null +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/ZapReaderTest.java @@ -0,0 +1,60 @@ +/** + * OWASP Benchmark Project + * + *

This file is part of the Open Web Application Security Project (OWASP) Benchmark Project For + * details, please see https://owasp.org/www-project-benchmark/. + * + *

The OWASP Benchmark is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Foundation, version 2. + * + *

The OWASP Benchmark is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * @author Sascha Knoop + * @created 2021 + */ +package org.owasp.benchmarkutils.score.parsers; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.owasp.benchmarkutils.score.BenchmarkScore; +import org.owasp.benchmarkutils.score.CweNumber; +import org.owasp.benchmarkutils.score.ResultFile; +import org.owasp.benchmarkutils.score.TestHelper; +import org.owasp.benchmarkutils.score.TestSuiteResults; + +public class ZapReaderTest extends ReaderTestBase { + + private ResultFile resultFile; + + @BeforeEach + void setUp() { + resultFile = TestHelper.resultFileOf("testfiles/Benchmark_1.2-ZAP_WEEKLY.xml"); + BenchmarkScore.TESTCASENAME = "BenchmarkTest"; + } + + @Test + public void onlyZapReaderReportsCanReadAsTrue() { + assertOnlyMatcherClassIs(this.resultFile, ZapReader.class); + } + + @Test + void readerHandlesGivenResultFile() throws Exception { + ZapReader reader = new ZapReader(); + TestSuiteResults result = reader.parse(resultFile); + + assertEquals(TestSuiteResults.ToolType.DAST, result.getToolType()); + assertFalse(result.isCommercial()); + assertEquals("OWASP ZAP", result.getToolName()); + + assertEquals(2, result.getTotalResults()); + + assertEquals(CweNumber.XSS, result.get(1).get(0).getCWE()); + assertEquals(CweNumber.SQL_INJECTION, result.get(2).get(0).getCWE()); + } +} diff --git a/plugin/src/test/resources/testfiles/Benchmark_1.2-Acunetix-v1.4.1.xml b/plugin/src/test/resources/testfiles/Benchmark_1.2-Acunetix-v1.4.1.xml new file mode 100644 index 00000000..41227777 --- /dev/null +++ b/plugin/src/test/resources/testfiles/Benchmark_1.2-Acunetix-v1.4.1.xml @@ -0,0 +1,41 @@ + + + + 00000000000000000000000000000000 + https://localhost:8443/benchmark/ + 01/01/1970 01:01 AM + 1.23:45:67.0123456 + + + + 00000000-0000-0000-0000-000000000000 + https://localhost:8443/benchmark/cmdi-01/BenchmarkTest00001 + CommandInjection + Command Injection + Critical + 100 + True + Revived + 1/01/1970 1:01:01 PM -01:00 + 1/01/1970 1:01:01 PM -01:00 + + 78 + + + + 00000000-0000-0000-0000-000000000000 + https://localhost:8443/benchmark/xss-01/BenchmarkTest00002 + Cross-siteScripting + Cross-site Scripting + High + 100 + True + Revived + 1/01/1970 1:01:01 PM -01:00 + 1/01/1970 1:01:01 PM -01:00 + + 79 + + + + diff --git a/plugin/src/test/resources/testfiles/Benchmark_1.2-AppScanDynamicReader2-v10.0.6.xml b/plugin/src/test/resources/testfiles/Benchmark_1.2-AppScanDynamicReader2-v10.0.6.xml new file mode 100644 index 00000000..eefbc5d8 --- /dev/null +++ b/plugin/src/test/resources/testfiles/Benchmark_1.2-AppScanDynamicReader2-v10.0.6.xml @@ -0,0 +1,44 @@ + + + + HCL AppScan Standard + 10.0.6 + + + https://localhost:8443/benchmark + + + 01:23:45.6789012 + + + + https://localhost:8443/benchmark/sqli-00/BenchmarkTest00001 + attSqlInjectionChecks + + + https://localhost:8443/benchmark/sqli-00/BenchmarkTest00002 + attSqlInjectionChecks + + + + + 89 + + attSqlInjectionChecks + + + 1111111111 + + + + GET /benchmark/sqli-00/BenchmarkTest00001.html?BenchmarkTest00001=SafeText + HTTP/1.1 + + + + POST /benchmark/sqli-00/BenchmarkTest00002 HTTP/1.1 + + + + + diff --git a/plugin/src/test/resources/testfiles/Benchmark_1.2-Arachni-v2.0dev.xml b/plugin/src/test/resources/testfiles/Benchmark_1.2-Arachni-v2.0dev.xml new file mode 100644 index 00000000..8e974218 --- /dev/null +++ b/plugin/src/test/resources/testfiles/Benchmark_1.2-Arachni-v2.0dev.xml @@ -0,0 +1,62 @@ + + + 2.0dev + 1970-01-01T01:01:01+01:00 + 1970-01-01T01:02:03+01:00 + + + DOM-based Cross-Site Scripting (XSS) via input fields + + high + + DOM XSS via input field + Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com> + 0.2.1 + xss_dom_inputs + + 79 + 0000000000 + + + + + + + Arachni::Element::GenericDOM + input + https://127.0.0.2:8443/benchmark/BenchmarkTest00001.html + https://127.0.0.2:8443/benchmark/BenchmarkTest00001.html + <input type="button" id="login-btn" value="Login"> + click + login-btn + + + + DOM-based Cross-Site Scripting (XSS) via input fields + + high + + DOM XSS via input field + Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com> + 0.2.1 + xss_dom_inputs + + 79 + 0000000000 + + + + + + + Arachni::Element::GenericDOM + input + https://127.0.0.2:8443/benchmark/BenchmarkTest00002.html + https://127.0.0.2:8443/benchmark/BenchmarkTest00002.html + <input type="button" id="login-btn" value="Login"> + click + login-btn + + + + diff --git a/plugin/src/test/resources/testfiles/Benchmark_1.2-BurpPro-v2020.2.1.xml b/plugin/src/test/resources/testfiles/Benchmark_1.2-BurpPro-v2020.2.1.xml new file mode 100644 index 00000000..0014e4df --- /dev/null +++ b/plugin/src/test/resources/testfiles/Benchmark_1.2-BurpPro-v2020.2.1.xml @@ -0,0 +1,34 @@ + + + + 0000000000000000000 + 1048832 + + https://localhost:8443 + + + High + Certain + Lorem Ipsum + Lorem Ipsum + Lorem Ipsum + Lorem Ipsum + Lorem Ipsum + + + 0000000000000000000 + 1049088 + + https://localhost:8443 + + + High + Certain + Lorem Ipsum + Lorem Ipsum + Lorem Ipsum + Lorem Ipsum + Lorem Ipsum + Lorem Ipsum + + diff --git a/plugin/src/test/resources/testfiles/Benchmark_1.2-CAST_AIP-v8.2.3.xml b/plugin/src/test/resources/testfiles/Benchmark_1.2-CAST_AIP-v8.2.3.xml new file mode 100644 index 00000000..2ea26c41 --- /dev/null +++ b/plugin/src/test/resources/testfiles/Benchmark_1.2-CAST_AIP-v8.2.3.xml @@ -0,0 +1,9 @@ + + + + Avoid OS command injection vulnerabilities ( CWE-78 ) + + + Avoid SQL injection vulnerabilities ( CWE-89 ) + + diff --git a/plugin/src/test/resources/testfiles/Benchmark_1.2-Checkmarx-v8.2.xml b/plugin/src/test/resources/testfiles/Benchmark_1.2-Checkmarx-v8.2.xml new file mode 100644 index 00000000..0035b50b --- /dev/null +++ b/plugin/src/test/resources/testfiles/Benchmark_1.2-Checkmarx-v8.2.xml @@ -0,0 +1,21 @@ + + + + + + + /testcode/BenchmarkTest00001.java + + + + + + + + + /testcode/BenchmarkTest00002.java + + + + + diff --git a/plugin/src/test/resources/testfiles/Benchmark_1.2-Coverity-v3.0.json b/plugin/src/test/resources/testfiles/Benchmark_1.2-Coverity-v3.0.json new file mode 100644 index 00000000..2a70b687 --- /dev/null +++ b/plugin/src/test/resources/testfiles/Benchmark_1.2-Coverity-v3.0.json @@ -0,0 +1,107 @@ +{ + "type" : "Coverity issues", + "formatVersion" : 3, + "suppressedIssueCount" : 0, + "issues" : [ + { + "mergeKey" : "00000000000000000000000000000000", + "occurrenceCountForMK" : 1, + "occurrenceNumberInMK" : 1, + "checkerName" : "PATH_MANIPULATION", + "subcategory" : "none", + "extra" : "fileName", + "domain" : "STATIC_JAVA", + "mainEventFilePathname" : "somepath\\src\\main\\java\\org\\owasp\\benchmark\\testcode\\BenchmarkTest00001.java", + "strippedMainEventFilePathname" : "somepath\\src\\main\\java\\org\\owasp\\benchmark\\testcode\\BenchmarkTest00001.java", + "mainEventLineNumber" : 0, + "properties" : {}, + "functionDisplayName" : "org.owasp.benchmark.testcode.BenchmarkTest00001.doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)", + "functionMangledName" : "org.owasp.benchmark.testcode.BenchmarkTest00001.doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)", + "ordered" : true, + "events" : [ + { + "covLStrEventDescription" : "Lorem Ipsum", + "eventDescription" : "Lorem Ipsum", + "eventNumber" : 0, + "eventTreePosition" : "0", + "eventSet" : 0, + "eventTag" : "tainted_source", + "filePathname" : "somepath\\src\\main\\java\\org\\owasp\\benchmark\\testcode\\BenchmarkTest00001.java", + "strippedFilePathname" : "somepath\\src\\main\\java\\org\\owasp\\benchmark\\testcode\\BenchmarkTest00001.java", + "lineNumber" : 0, + "main" : false, + "moreInformationId" : null, + "remediation" : false, + "events" : null + } + ], + "stateOnServer" : null, + "checkerProperties" : { + "category" : "High impact security", + "categoryDescription" : "High impact security", + "cweCategory" : "22", + "issueKinds" : [ + "SECURITY" + ], + "eventSetCaptions" : [], + "impact" : "High", + "impactDescription" : "High", + "subcategoryLocalEffect" : "Lorem Ipsum", + "subcategoryShortDescription" : "Lorem Ipsum", + "subcategoryLongDescription" : "Lorem Ipsum" + } + }, + { + "mergeKey" : "00000000000000000000000000000000", + "occurrenceCountForMK" : 1, + "occurrenceNumberInMK" : 1, + "checkerName" : "SQLI", + "subcategory" : "sink", + "extra" : "sql", + "domain" : "STATIC_JAVA", + "mainEventFilePathname" : "somepath\\src\\main\\java\\org\\owasp\\benchmark\\testcode\\BenchmarkTest00002.java", + "strippedMainEventFilePathname" : "somepath\\src\\main\\java\\org\\owasp\\benchmark\\testcode\\BenchmarkTest00002.java", + "mainEventLineNumber" : 0, + "properties" : {}, + "functionDisplayName" : "org.owasp.benchmark.testcode.BenchmarkTest00002.doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)", + "functionMangledName" : "org.owasp.benchmark.testcode.BenchmarkTest00002.doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)", + "ordered" : true, + "events" : [ + { + "covLStrEventDescription" : "Lorem Ipsum", + "eventDescription" : "Lorem Ipsum", + "eventNumber" : 1, + "eventTreePosition" : "0", + "eventSet" : 0, + "eventTag" : "tainted_source", + "filePathname" : "somepath\\src\\main\\java\\org\\owasp\\benchmark\\testcode\\BenchmarkTest00002.java", + "strippedFilePathname" : "somepath\\src\\main\\java\\org\\owasp\\benchmark\\testcode\\BenchmarkTest00002.java", + "lineNumber" : 0, + "main" : false, + "moreInformationId" : null, + "remediation" : false, + "events" : null + } + ], + "stateOnServer" : null, + "checkerProperties" : { + "category" : "High impact security", + "categoryDescription" : "High impact security", + "cweCategory" : "89", + "issueKinds" : [ + "SECURITY" + ], + "eventSetCaptions" : [ + "Lorem Ipsum" + ], + "impact" : "High", + "impactDescription" : "High", + "subcategoryLocalEffect" : "Lorem Ipsum", + "subcategoryShortDescription" : "Lorem Ipsum", + "subcategoryLongDescription" : "Lorem Ipsum" + } + } + ], + "desktopAnalysisSettings" : null, + "error" : null +} diff --git a/plugin/src/test/resources/testfiles/Benchmark_1.2-CxIAST.csv b/plugin/src/test/resources/testfiles/Benchmark_1.2-CxIAST.csv new file mode 100644 index 00000000..622fa299 --- /dev/null +++ b/plugin/src/test/resources/testfiles/Benchmark_1.2-CxIAST.csv @@ -0,0 +1,3 @@ +Vulnerability ID,Vulnerability Type,Severity,First Detection Time (YYYY/MM/dd HH:mm),Status,State,URL,Method,Source Filename,Source Line,Source Input,Destination Filename,Destination Line,Destination Output,Assigned User,CWE +2,Blind_SQL_Injection,MEDIUM,1970/01/01 01:01,NEW,TO_VERIFY,/sqli-01/BenchmarkTest00001?someparams,POST,org/owasp/benchmark/testcode/BenchmarkTest00001.java,43,BenchmarkTest00001,org/owasp/benchmark/testcode/BenchmarkTest00001.java,1,something,,89 +1,Path_Traversal,MEDIUM,1970/01/01 01:01,NEW,TO_VERIFY,/pathtraver-01/BenchmarkTest00002?someparams,POST,org/owasp/benchmark/testcode/BenchmarkTest00002.java,43,BenchmarkTest00002,org/owasp/benchmark/testcode/BenchmarkTest00002.java,1,something,,22 diff --git a/plugin/src/test/resources/testfiles/Benchmark_1.2-Fortify20.20_2020Q1-1234.fpr b/plugin/src/test/resources/testfiles/Benchmark_1.2-Fortify20.20_2020Q1-1234.fpr new file mode 100644 index 00000000..0315f818 Binary files /dev/null and b/plugin/src/test/resources/testfiles/Benchmark_1.2-Fortify20.20_2020Q1-1234.fpr differ diff --git a/plugin/src/test/resources/testfiles/Benchmark_1.2-JuliaSoft-v2.3.2.1.xml b/plugin/src/test/resources/testfiles/Benchmark_1.2-JuliaSoft-v2.3.2.1.xml new file mode 100644 index 00000000..7a5fab86 --- /dev/null +++ b/plugin/src/test/resources/testfiles/Benchmark_1.2-JuliaSoft-v2.3.2.1.xml @@ -0,0 +1,43 @@ + + + 00000000-0000-0000-0000-000000000000 + COMPLETED + 1970-01-01T01:01:01.001-01:00 + 2.3.2.1 + 123456 + + benchmark.jar + 614 + org.owasp.benchmark.testcode.BenchmarkTest00001 + Cookie + 1 + doPost + 1 + 1 + InsecureCookieWarning + org/owasp/benchmark/testcode/BenchmarkTest00001.java + false + Security_Features + BUG + Lorem Ipsum + Lorem Ipsum + + + benchmark.jar + 327 + org.owasp.benchmark.testcode.BenchmarkTest00002 + Cryptography + 1 + doPost + 1 + 1 + RiskyCryptographicAlgorithmWarning + org/owasp/benchmark/testcode/BenchmarkTest00002.java + false + Security_Features + BUG + Lorem Ipsum + Lorem Ipsum + + 0:01:01.123 + diff --git a/plugin/src/test/resources/testfiles/Benchmark_1.2-Kiuwan-20191012.threadfix b/plugin/src/test/resources/testfiles/Benchmark_1.2-Kiuwan-20191012.threadfix new file mode 100644 index 00000000..85cca5a2 --- /dev/null +++ b/plugin/src/test/resources/testfiles/Benchmark_1.2-Kiuwan-20191012.threadfix @@ -0,0 +1,69 @@ +{ + "collectionType": "SAST", + "created": "1970-01-01T01:01:01Z", + "exported": "1970-01-01T01:01:01Z", + "source": "Kiuwan", + "executiveSummary": "Lorem Ipsum", + "metadata": { + "Kiuwan-EngineVersion": "some.version", + "Kiuwan-AnalysisDuration": "01:23:45" + }, + "findings": [ + { + "nativeId": "0000000000", + "severity": "Critical", + "nativeSeverity": "Very High", + "summary": "Lorem Ipsum", + "scannerDetail": "Lorem Ipsum", + "scannerRecommendation": "Lorem Ipsum", + "staticDetails": { + "parameter": "", + "dataFlow": [ + { + "file": "Benchmark/src/main/java/org/owasp/benchmark/testcode/BenchmarkTest00001.java", + "lineNumber": 47, + "columnNumber": 1, + "parameter": "", + "text": "param = request.getHeader(\"BenchmarkTest00001\");", + "sequence": 0 + } + ] + }, + "mappings": [ + { + "mappingType": "CWE", + "value": "79", + "primary": true + } + ] + }, + { + "nativeId": "0000000000", + "severity": "Critical", + "nativeSeverity": "Very High", + "summary": "Lorem Ipsum", + "scannerDetail": "Lorem Ipsum", + "scannerRecommendation": "", + "staticDetails": { + "parameter": "", + "dataFlow": [ + { + "file": "Benchmark/src/main/java/org/owasp/benchmark/testcode/BenchmarkTest00002.java", + "lineNumber": 47, + "columnNumber": 1, + "parameter": "", + "text": "param = request.getHeader(\"BenchmarkTest00002\");", + "sequence": 0 + } + ] + }, + "mappings": [ + { + "mappingType": "CWE", + "value": "564", + "primary": true + } + ] + } + ] +} diff --git a/plugin/src/test/resources/testfiles/Benchmark_1.2-Netsparker.xml b/plugin/src/test/resources/testfiles/Benchmark_1.2-Netsparker.xml new file mode 100644 index 00000000..3fbf2125 --- /dev/null +++ b/plugin/src/test/resources/testfiles/Benchmark_1.2-Netsparker.xml @@ -0,0 +1,50 @@ + + + + + https://localhost:8443/benchmark/ + 123456 + + + https://localhost:8443/benchmark/securecookie-00/BenchmarkTest00001?BenchmarkTest00001=whatever + CookieNotMarkedAsSecure + Important + 100 + + + + Extra Information + + + A9 + A6 + 15 + 614 + 102 + 6.5.4 + 6.5.10 + 6.5.10 + + + + https://localhost:8443/benchmark/securecookie-00/BenchmarkTest00002 + CookieNotMarkedAsHttpOnly + Low + 100 + + + + Extra Information + + + A6 + A5 + 15 + 1004 + 107 + + + + + + diff --git a/plugin/src/test/resources/testfiles/Benchmark_1.2-ParasoftJTest-v10.2.3.xml b/plugin/src/test/resources/testfiles/Benchmark_1.2-ParasoftJTest-v10.2.3.xml new file mode 100644 index 00000000..2bf8fb81 --- /dev/null +++ b/plugin/src/test/resources/testfiles/Benchmark_1.2-ParasoftJTest-v10.2.3.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/plugin/src/test/resources/testfiles/Benchmark_1.2-Wapiti-v3.0.3.xml b/plugin/src/test/resources/testfiles/Benchmark_1.2-Wapiti-v3.0.3.xml new file mode 100644 index 00000000..3665b412 --- /dev/null +++ b/plugin/src/test/resources/testfiles/Benchmark_1.2-Wapiti-v3.0.3.xml @@ -0,0 +1,333 @@ + + + + wapiti + Wapiti 3.0.3 + folder + Thu, 01 Jan 1970 01:01:01 +0000 + https://localhost:8443/benchmark/ + + + + + + + + + + + + http://www.owasp.org/index.php/SQL_Injection + http://www.owasp.org/index.php/SQL_Injection + + + http://en.wikipedia.org/wiki/SQL_injection + http://en.wikipedia.org/wiki/SQL_injection + + + CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL + Injection') + + http://cwe.mitre.org/data/definitions/89.html + + + + + GET + /benchmark/sqli-01/BenchmarkTest00001 + 1 + BenchmarkTest00001 + Spring JDBC Injection via injection in the parameter BenchmarkTest00001 + HTTP Request + CURL Command + + + + + + + + + + + + + http://www.owasp.org/index.php/Blind_SQL_Injection + http://www.owasp.org/index.php/Blind_SQL_Injection + + + http://www.imperva.com/resources/adc/blind_sql_server_injection.html + http://www.imperva.com/resources/adc/blind_sql_server_injection.html + + + CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL + Injection') + + http://cwe.mitre.org/data/definitions/89.html + + + + + + + + + + + + + + http://www.owasp.org/index.php/Path_Traversal + http://www.owasp.org/index.php/Path_Traversal + + + http://www.acunetix.com/websitesecurity/directory-traversal.htm + http://www.acunetix.com/websitesecurity/directory-traversal.htm + + + CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal') + + http://cwe.mitre.org/data/definitions/22.html + + + + + + + + + + + + + + http://www.owasp.org/index.php/Cross_Site_Scripting + http://www.owasp.org/index.php/Cross_Site_Scripting + + + http://en.wikipedia.org/wiki/Cross-site_scripting + http://en.wikipedia.org/wiki/Cross-site_scripting + + + CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site + Scripting') + + http://cwe.mitre.org/data/definitions/79.html + + + + + + + + + + + + + + http://www.owasp.org/index.php/CRLF_Injection + http://www.owasp.org/index.php/CRLF_Injection + + + http://www.acunetix.com/websitesecurity/crlf-injection.htm + http://www.acunetix.com/websitesecurity/crlf-injection.htm + + + CWE-93: Improper Neutralization of CRLF Sequences ('CRLF Injection') + http://cwe.mitre.org/data/definitions/93.html + + + + + + + + + + + + + + http://www.owasp.org/index.php/Command_Injection + http://www.owasp.org/index.php/Command_Injection + + + CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command + Injection') + + http://cwe.mitre.org/data/definitions/78.html + + + + + GET + /benchmark/cmdi-00/BenchmarkTest00002 + 1 + BenchmarkTest00002 + Blind command execution via injection in the parameter BenchmarkTest00002 + HTTP Request + CURL Command + + + + + + + + + + + + + http://blog.teusink.net/2009/07/common-apache-htaccess-misconfiguration.html + http://blog.teusink.net/2009/07/common-apache-htaccess-misconfiguration.html + + + CWE-538: File and Directory Information Exposure + http://cwe.mitre.org/data/definitions/538.html + + + + + + + + + + + + + + Testing for Old, Backup and Unreferenced Files (OWASP-CM-006) + http://www.owasp.org/index.php/Testing_for_Old,_Backup_and_Unreferenced_Files_(OWASP-CM-006) + + + + CWE-530: Exposure of Backup File to an Unauthorized Control Sphere + http://cwe.mitre.org/data/definitions/530.html + + + + + + + + + + + + + + The Open Source Vulnerability Database + http://osvdb.org/ + + + + + + + + + + + + + + Server Side Request Forgery (OWASP) + https://www.owasp.org/index.php/Server_Side_Request_Forgery + + + What is Server Side Request Forgery (Acunetix)? + https://www.acunetix.com/blog/articles/server-side-request-forgery-vulnerability/ + + + What is the Server Side Request Forgery Vulnerability (Netsparker) + https://www.netsparker.com/blog/web-security/server-side-request-forgery-vulnerability-ssrf/ + + + + CWE-918: Server-Side Request Forgery (SSRF) + https://cwe.mitre.org/data/definitions/918.html + + + + + + + + + + + + + + Owasp Open Redirect + + https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html + + + + CWE-601: URL Redirection to Untrusted Site ('Open Redirect') + https://cwe.mitre.org/data/definitions/601.html + + + + + + + + + + + + + + Owasp XML External Entity (XXE) Processing + https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Processing + + + CWE-611: Improper Restriction of XML External Entity Reference + https://cwe.mitre.org/data/definitions/611.html + + + + + + + + + + + + + + + + Wikipedia article for 5xx HTTP error codes + https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#5xx_Server_Error + + + + + + + + + + + + + + http://www.owasp.org/index.php/Asymmetric_resource_consumption_(amplification) + http://www.owasp.org/index.php/Asymmetric_resource_consumption_(amplification) + + + CWE-400: Uncontrolled Resource Consumption ('Resource Exhaustion') + http://cwe.mitre.org/data/definitions/400.html + + + + + + diff --git a/plugin/src/test/resources/testfiles/Benchmark_1.2-ZAP-v2.10.0.json b/plugin/src/test/resources/testfiles/Benchmark_1.2-ZAP-v2.10.0.json new file mode 100644 index 00000000..32cc6062 --- /dev/null +++ b/plugin/src/test/resources/testfiles/Benchmark_1.2-ZAP-v2.10.0.json @@ -0,0 +1,48 @@ +{ + "vulnerabilities": [ + { + "sourceid": "1", + "other": "Check 3", + "method": "POST", + "evidence": "etc", + "pluginId": "6", + "cweid": "22", + "confidence": "Medium", + "wascid": "33", + "description": "The Path Traversal attack technique allows an attacker access to files, directories, and commands that potentially reside outside the web document root directory. An attacker may manipulate a URL in such a way that the web site will execute or reveal the contents of arbitrary files anywhere on the web server. Any device that exposes an HTTP-based interface is potentially vulnerable to Path Traversal.\n\nMost web sites restrict user access to a specific portion of the file-system, typically called the \"web document root\" or \"CGI root\" directory. These directories contain the files intended for user access and the executable necessary to drive web application functionality. To access files or execute commands anywhere on the file-system, Path Traversal attacks will utilize the ability of special-characters sequences.\n\nThe most basic Path Traversal attack uses the \"../\" special-character sequence to alter the resource location requested in the URL. Although most popular web servers will prevent this technique from escaping the web document root, alternate encodings of the \"../\" sequence may help bypass the security filters. These method variations include valid and invalid Unicode-encoding (\"..%u2216\" or \"..%c0%af\") of the forward slash character, backslash characters (\"..\\\") on Windows-based servers, URL encoded characters \"%2e%2e%2f\"), and double URL encoding (\"..%255c\") of the backslash character.\n\nEven if the web server properly restricts Path Traversal attempts in the URL path, a web application itself may still be vulnerable due to improper handling of user-supplied input. This is a common problem of web applications that use template mechanisms or load static text from files. In variations of the attack, the original URL parameter value is substituted with the file name of one of the web application's dynamic scripts. Consequently, the results can reveal source code because the file is interpreted as text instead of an executable script. These techniques often employ additional special characters such as the dot (\".\") to reveal the listing of the current working directory, or \"%00\" NULL characters in order to bypass rudimentary file extension checks.", + "messageId": "16781", + "url": "https://localhost:8443/benchmark/cmdi-00/BenchmarkTest00001", + "reference": "http://projects.webappsec.org/Path-Traversal\nhttp://cwe.mitre.org/data/definitions/22.html", + "solution": "Assume all input is malicious. Use an \"accept known good\" input validation strategy, i.e., use a whitelist of acceptable inputs that strictly conform to specifications. Reject any input that does not strictly conform to specifications, or transform it into something that does. Do not rely exclusively on looking for malicious or malformed inputs (i.e., do not rely on a blacklist). However, blacklists can be useful for detecting potential attacks or determining which inputs are so malformed that they should be rejected outright.\n\nWhen performing input validation, consider all potentially relevant properties, including length, type of input, the full range of acceptable values, missing or extra inputs, syntax, consistency across related fields, and conformance to business rules. As an example of business rule logic, \"boat\" may be syntactically valid because it only contains alphanumeric characters, but it is not valid if you are expecting colors such as \"red\" or \"blue.\"\n\nFor filenames, use stringent whitelists that limit the character set to be used. If feasible, only allow a single \".\" character in the filename to avoid weaknesses, and exclude directory separators such as \"/\". Use a whitelist of allowable file extensions.\n\nWarning: if you attempt to cleanse your data, then do so that the end result is not in the form that can be dangerous. A sanitizing mechanism can remove characters such as '.' and ';' which may be required for some exploits. An attacker can try to fool the sanitizing mechanism into \"cleaning\" data into a dangerous form. Suppose the attacker injects a '.' inside a filename (e.g. \"sensi.tiveFile\") and the sanitizing mechanism removes the character resulting in the valid filename, \"sensitiveFile\". If the input data are now assumed to be safe, then the file may be compromised. \n\nInputs should be decoded and canonicalized to the application's current internal representation before being validated. Make sure that your application does not decode the same input twice. Such errors could be used to bypass whitelist schemes by introducing dangerous inputs after they have been checked.\n\nUse a built-in path canonicalization function (such as realpath() in C) that produces the canonical version of the pathname, which effectively removes \"..\" sequences and symbolic links.\n\nRun your code using the lowest privileges that are required to accomplish the necessary tasks. If possible, create isolated accounts with limited privileges that are only used for a single task. That way, a successful attack will not immediately give the attacker access to the rest of the software or its environment. For example, database applications rarely need to run as the database administrator, especially in day-to-day operations.\n\nWhen the set of acceptable objects, such as filenames or URLs, is limited or known, create a mapping from a set of fixed input values (such as numeric IDs) to the actual filenames or URLs, and reject all other inputs.\n\nRun your code in a \"jail\" or similar sandbox environment that enforces strict boundaries between the process and the operating system. This may effectively restrict which files can be accessed in a particular directory or which commands can be executed by your software.\n\nOS-level examples include the Unix chroot jail, AppArmor, and SELinux. In general, managed code may provide some protection. For example, java.io.FilePermission in the Java SecurityManager allows you to specify restrictions on file operations.\n\nThis may not be a feasible solution, and it only limits the impact to the operating system; the rest of your application may still be subject to compromise.", + "alert": "Path Traversal", + "param": "BenchmarkTest00001", + "attack": "/", + "name": "Path Traversal", + "risk": "High", + "id": "2052", + "alertRef": "6" + }, + { + "sourceid": "1", + "other": "", + "method": "POST", + "evidence": "", + "pluginId": "40012", + "cweid": "79", + "confidence": "Medium", + "wascid": "8", + "description": "Cross-site Scripting (XSS) is an attack technique that involves echoing attacker-supplied code into a user's browser instance. A browser instance can be a standard web browser client, or a browser object embedded in a software product such as the browser within WinAmp, an RSS reader, or an email client. The code itself is usually written in HTML/JavaScript, but may also extend to VBScript, ActiveX, Java, Flash, or any other browser-supported technology.\nWhen an attacker gets a user's browser to execute his/her code, the code will run within the security context (or zone) of the hosting web site. With this level of privilege, the code has the ability to read, modify and transmit any sensitive data accessible by the browser. A Cross-site Scripted user could have his/her account hijacked (cookie theft), their browser redirected to another location, or possibly shown fraudulent content delivered by the web site they are visiting. Cross-site Scripting attacks essentially compromise the trust relationship between a user and the web site. Applications utilizing browser object instances which load content from the file system may execute code under the local machine zone allowing for system compromise.\n\nThere are three types of Cross-site Scripting attacks: non-persistent, persistent and DOM-based.\nNon-persistent attacks and DOM-based attacks require a user to either visit a specially crafted link laced with malicious code, or visit a malicious web page containing a web form, which when posted to the vulnerable site, will mount the attack. Using a malicious form will oftentimes take place when the vulnerable resource only accepts HTTP POST requests. In such a case, the form can be submitted automatically, without the victim's knowledge (e.g. by using JavaScript). Upon clicking on the malicious link or submitting the malicious form, the XSS payload will get echoed back and will get interpreted by the user's browser and execute. Another technique to send almost arbitrary requests (GET and POST) is by using an embedded client, such as Adobe Flash.\nPersistent attacks occur when the malicious code is submitted to a web site where it's stored for a period of time. Examples of an attacker's favorite targets often include message board posts, web mail messages, and web chat software. The unsuspecting user is not required to interact with any additional site/link (e.g. an attacker site or a malicious link sent via email), just simply view the web page containing the code.", + "messageId": "69383", + "url": "https://localhost:8443/benchmark/xss-00/BenchmarkTest00002", + "reference": "http://projects.webappsec.org/Cross-Site-Scripting\nhttp://cwe.mitre.org/data/definitions/79.html", + "solution": "Phase: Architecture and Design\nUse a vetted library or framework that does not allow this weakness to occur or provides constructs that make this weakness easier to avoid.\nExamples of libraries and frameworks that make it easier to generate properly encoded output include Microsoft's Anti-XSS library, the OWASP ESAPI Encoding module, and Apache Wicket.\n\nPhases: Implementation; Architecture and Design\nUnderstand the context in which your data will be used and the encoding that will be expected. This is especially important when transmitting data between different components, or when generating outputs that can contain multiple encodings at the same time, such as web pages or multi-part mail messages. Study all expected communication protocols and data representations to determine the required encoding strategies.\nFor any data that will be output to another web page, especially any data that was received from external inputs, use the appropriate encoding on all non-alphanumeric characters.\nConsult the XSS Prevention Cheat Sheet for more details on the types of encoding and escaping that are needed.\n\nPhase: Architecture and Design\nFor any security checks that are performed on the client side, ensure that these checks are duplicated on the server side, in order to avoid CWE-602. Attackers can bypass the client-side checks by modifying values after the checks have been performed, or by changing the client to remove the client-side checks entirely. Then, these modified values would be submitted to the server.\n\nIf available, use structured mechanisms that automatically enforce the separation between data and code. These mechanisms may be able to provide the relevant quoting, encoding, and validation automatically, instead of relying on the developer to provide this capability at every point where output is generated.\n\nPhase: Implementation\nFor every web page that is generated, use and specify a character encoding such as ISO-8859-1 or UTF-8. When an encoding is not specified, the web browser may choose a different encoding by guessing which encoding is actually being used by the web page. This can cause the web browser to treat certain sequences as special, opening up the client to subtle XSS attacks. See CWE-116 for more mitigations related to encoding/escaping.\n\nTo help mitigate XSS attacks against the user's session cookie, set the session cookie to be HttpOnly. In browsers that support the HttpOnly feature (such as more recent versions of Internet Explorer and Firefox), this attribute can prevent the user's session cookie from being accessible to malicious client-side scripts that use document.cookie. This is not a complete solution, since HttpOnly is not supported by all browsers. More importantly, XMLHTTPRequest and other powerful browser technologies provide read access to HTTP headers, including the Set-Cookie header in which the HttpOnly flag is set.\n\nAssume all input is malicious. Use an \"accept known good\" input validation strategy, i.e., use a whitelist of acceptable inputs that strictly conform to specifications. Reject any input that does not strictly conform to specifications, or transform it into something that does. Do not rely exclusively on looking for malicious or malformed inputs (i.e., do not rely on a blacklist). However, blacklists can be useful for detecting potential attacks or determining which inputs are so malformed that they should be rejected outright.\n\nWhen performing input validation, consider all potentially relevant properties, including length, type of input, the full range of acceptable values, missing or extra inputs, syntax, consistency across related fields, and conformance to business rules. As an example of business rule logic, \"boat\" may be syntactically valid because it only contains alphanumeric characters, but it is not valid if you are expecting colors such as \"red\" or \"blue.\"\n\nEnsure that you perform input validation at well-defined interfaces within the application. This will help protect the application even if a component is reused or moved elsewhere.", + "alert": "Cross Site Scripting (Reflected)", + "param": "BenchmarkTest00002", + "attack": "", + "name": "Cross Site Scripting (Reflected)", + "risk": "High", + "id": "8886", + "alertRef": "40012" + } + ] +} diff --git a/plugin/src/test/resources/testfiles/Benchmark_1.2-ZAP_WEEKLY.xml b/plugin/src/test/resources/testfiles/Benchmark_1.2-ZAP_WEEKLY.xml new file mode 100644 index 00000000..0afae539 --- /dev/null +++ b/plugin/src/test/resources/testfiles/Benchmark_1.2-ZAP_WEEKLY.xml @@ -0,0 +1,57 @@ + + + + + + 40012 + Cross Site Scripting (Reflected) + Cross Site Scripting (Reflected) + 3 + 2 + High (Medium) + Lorem Ipsum + + + https://localhost:8443/benchmark/xss-01/BenchmarkTest00001 + POST + BenchmarkTest00001 + <script>alert(1);</script> + <script>alert(1);</script> + + + 1 + Lorem Ipsum + <p>http://projects.webappsec.org/Cross-Site-Scripting</p><p>http://cwe.mitre.org/data/definitions/79.html</p> + 79 + 8 + 1 + + + 40018 + SQL Injection - Hypersonic SQL + SQL Injection - Hypersonic SQL + 3 + 2 + High (Medium) + Lorem Ipsum + + + https://localhost:8443/benchmark/sqli-01/BenchmarkTest00002 + POST + BenchmarkTest00002 + ' + org.hsql + + + 1 + Lorem Ipsum + Lorem Ipsum + <p>https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html</p> + 89 + 19 + 1 + + + + + diff --git a/plugin/src/test/resources/testfiles/Benchmark_1.2-findsecbugs-v1.11.0-105.xml b/plugin/src/test/resources/testfiles/Benchmark_1.2-findsecbugs-v1.11.0-105.xml new file mode 100644 index 00000000..6a5bb880 --- /dev/null +++ b/plugin/src/test/resources/testfiles/Benchmark_1.2-findsecbugs-v1.11.0-105.xml @@ -0,0 +1,220 @@ + + + + /somepath/Benchmark/target/classes + /root/.m2/repository/javax/javaee-api/7.0/javaee-api-7.0.jar + /root/.m2/repository/com/sun/mail/javax.mail/1.5.0/javax.mail-1.5.0.jar + + /somepath/Benchmark/src/main/java + /somepath/Benchmark/target/generated-sources/annotations + /somepath/Benchmark/target + + + Potential XSS in Servlet + This use of java/io/PrintWriter.println(Ljava/lang/String;)V could be vulnerable to XSS in the + Servlet + + + + At BenchmarkTest00001.java:[lines 28-115] + + In class org.owasp.benchmark.testcode.BenchmarkTest00001 + + + + In method org.owasp.benchmark.testcode.BenchmarkTest00001.doPost(HttpServletRequest, + HttpServletResponse) + + + + At BenchmarkTest00001.java:[line 74] + + + Sink method java/io/PrintWriter.println(Ljava/lang/String;)V + + + Sink parameter 0 + + + Unknown source javax/naming/directory/Attribute.get()Ljava/lang/Object; + + + At BenchmarkTest00001.java:[line 77] + + + At BenchmarkTest00001.java:[line 80] + + + + Potential JDBC Injection + This use of java/sql/Connection.prepareCall(Ljava/lang/String;)Ljava/sql/CallableStatement; can be + vulnerable to SQL injection (with JDBC) + + + + At BenchmarkTest00002.java:[lines 28-67] + + In class org.owasp.benchmark.testcode.BenchmarkTest00002 + + + + In method org.owasp.benchmark.testcode.BenchmarkTest00002.doPost(HttpServletRequest, + HttpServletResponse) + + + + At BenchmarkTest00002.java:[line 57] + + + Sink method java/sql/Connection.prepareCall(Ljava/lang/String;)Ljava/sql/CallableStatement; + + + + Sink parameter 0 + + + Tainted source java/net/URLDecoder.decode(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; + + + + Tainted source + javax/servlet/http/HttpServletRequest.getHeader(Ljava/lang/String;)Ljava/lang/String; + + + + At BenchmarkTest00002.java:[line 46] + + + At BenchmarkTest00002.java:[line 50] + + + At BenchmarkTest00002.java:[line 52] + + + + Security + + + Predictable Pseudo Random Generator + + + LDAP Injection + + + Referer Header + + + Path traversal + + + Cookie without the HttpOnly flag + + + HTTP Response splitting vulnerability + + + HQL Injection + + + SQL Injection (JDBC) + + + XPath Injection + + + Potentially Sensitive Data in Cookie + + + Information Exposure Through An Error Message + + + Static IV + + + Potential XSS in Servlet + + + Trust Boundary Violation + + + DESede + + + Cipher with no integrity + + + Cipher is susceptible to padding oracle attack + + + XXE Vulnerability using DocumentBuilder + + + XXE Vulnerability using XSLT in TransformerFactory + + + MD2, MD4 and MD5 are weak hash functions + + + Overly permissive file permission + + + Command Injection + + + Dubious method used + + + Hard coded password + + + XXE Vulnerability using TransformerFactory + + + SHA-1 is a weak hash function + + + Query String + + + Potential SQL Problem + + + DES + + + Improper handling of Unicode transformations + + + Spring Endpoint + + + Potential Path Traversal (File Write) + + + HTTP Headers Untrusted + + + SQL Injection (Spring JDBC) + + + HTTP Response Splitting + + + Cookie without the secure flag + + + Cross site scripting vulnerability + + + HTTP Parameter Pollution + + + Potential Path Traversal (file read) + + + Servlet Parameter + + + + + diff --git a/plugin/src/test/resources/testfiles/Benchmark_1.2-hdivAgentLog.hlg b/plugin/src/test/resources/testfiles/Benchmark_1.2-hdivAgentLog.hlg new file mode 100644 index 00000000..711a6739 --- /dev/null +++ b/plugin/src/test/resources/testfiles/Benchmark_1.2-hdivAgentLog.hlg @@ -0,0 +1,7 @@ +05:40:55,460 CFG [FINE] LOREM IPSUM +05:41:58,220 ANL [FINE] benchmark SourceCodeVulnerability [origin=REQUEST, type=PATH_TRAVERSAL, url=/benchmark/pathtraver-01/BenchmarkTest00001, httpParameterName=BenchmarkTest00001, httpOriginalValue=FileName, taintedValue=SomeValue, className=org.owasp.benchmark.testcode.BenchmarkTest00001, lineNumber=1, score=1.0, hash=0000000000] +05:41:58,280 DTF [FINE] /benchmark/pathtraver-01/BenchmarkTest00001 +05:41:58,280 DTF [FINE] TaintedObjectsImpl [SomeDetails] +05:41:58,330 ANL [FINE] benchmark SourceCodeVulnerability [origin=REQUEST, type=INSECURE_HASHING, url=/benchmark/hash-01/BenchmarkTest00002, taintedValue=SomeValue, className=org.owasp.benchmark.testcode.BenchmarkTest00002, lineNumber=1, score=1.0, hash=0000000000] +05:41:58,380 DTF [FINE] /benchmark/hash-00/BenchmarkTest00002 +05:41:58,380 DTF [FINE] TaintedObjectsImpl [SomeDetails] diff --git a/plugin/src/test/resources/testfiles/Benchmark_1.2-horusec-v2.5.0.json b/plugin/src/test/resources/testfiles/Benchmark_1.2-horusec-v2.5.0.json new file mode 100644 index 00000000..593fbc1f --- /dev/null +++ b/plugin/src/test/resources/testfiles/Benchmark_1.2-horusec-v2.5.0.json @@ -0,0 +1,21 @@ +{ + "version": "v2.5.0", + "createdAt": "1970-01-01T00:00:00.0000000Z", + "finishedAt": "1970-01-01T01:23:45.0000000Z", + "analysisVulnerabilities": [ + { + "vulnerabilities": { + "file": "somepath/main/java/org/owasp/benchmark/testcode/BenchmarkTest00001.java", + "details": "Potential XSS in Servlet\nA potential XSS was found. It could be used to execute unwanted JavaScript in a client's browser. For more information checkout the CWE-79 (https://cwe.mitre.org/data/definitions/79.html) advisory", + "securityTool": "HorusecEngine" + } + }, + { + "vulnerabilities": { + "file": "somepath/main/java/org/owasp/benchmark/testcode/BenchmarkTest00002.java", + "details": "SQL Injection\nThe input values included in SQL queries need to be passed in safely. Bind variables in prepared statements can be used to easily mitigate the risk of SQL injection. Alternatively to prepare statements, each parameter can be escaped manually. For more information checkout the CWE-89 (https://cwe.mitre.org/data/definitions/89.html) advisory.", + "securityTool": "HorusecEngine" + } + } + ] +} diff --git a/plugin/src/test/resources/testfiles/Benchmark_1.2-insider-v3.0.0.json b/plugin/src/test/resources/testfiles/Benchmark_1.2-insider-v3.0.0.json new file mode 100644 index 00000000..5276277b --- /dev/null +++ b/plugin/src/test/resources/testfiles/Benchmark_1.2-insider-v3.0.0.json @@ -0,0 +1,215 @@ +{ + "libraries": [ + { + "name": "javax:javaee-api", + "current": "7.0" + }, + { + "name": "com.sun.jersey:jersey-servlet", + "current": "${version.jersey}" + }, + { + "name": "commons-codec:commons-codec", + "current": "1.15" + }, + { + "name": "commons-dbcp:commons-dbcp", + "current": "1.4" + }, + { + "name": "commons-io:commons-io", + "current": "2.6" + }, + { + "name": "commons-lang:commons-lang", + "current": "2.6" + }, + { + "name": "org.slf4j:slf4j-log4j12", + "current": "${version.slf4j}" + }, + { + "name": "org.apache.commons:commons-csv", + "current": "1.6" + }, + { + "name": "org.apache.commons:commons-lang3", + "current": "3.8.1" + }, + { + "name": "org.apache.directory.server:apacheds-core", + "current": "${version.apacheds}" + }, + { + "name": "org.apache.directory.server:apacheds-core-api", + "current": "${version.apacheds}" + }, + { + "name": "org.apache.directory.server:apacheds-core-constants", + "current": "${version.apacheds}" + }, + { + "name": "org.apache.directory.server:apacheds-jdbm-partition", + "current": "${version.apacheds}" + }, + { + "name": "org.apache.directory.server:apacheds-jdbm-store", + "current": "${version.apacheds}" + }, + { + "name": "org.apache.directory.server:apacheds-ldif-partition", + "current": "${version.apacheds}" + }, + { + "name": "org.apache.directory.server:apacheds-protocol-ldap", + "current": "${version.apacheds}" + }, + { + "name": "org.apache.directory.server:apacheds-protocol-shared", + "current": "${version.apacheds}" + }, + { + "name": "org.apache.directory.server:apacheds-xdbm-base", + "current": "${version.apacheds}" + }, + { + "name": "org.apache.directory.shared:shared-ldap", + "current": "${version.apache-shared-ldap}" + }, + { + "name": "org.apache.directory.shared:shared-ldap-schema", + "current": "${version.apache-shared-ldap}" + }, + { + "name": "org.apache.directory.shared:shared-ldap-schema-loader", + "current": "${version.apache-shared-ldap}" + }, + { + "name": "org.apache.directory.shared:shared-ldap-schema-manager", + "current": "${version.apache-shared-ldap}" + }, + { + "name": "org.apache.httpcomponents:httpclient", + "current": "4.5.13" + }, + { + "name": "org.apache.httpcomponents:httpcore", + "current": "4.4.14" + }, + { + "name": "org.bouncycastle:bcprov-jdk15on", + "current": "1.69" + }, + { + "name": "org.hibernate:hibernate-core", + "current": "${version.hibernate}" + }, + { + "name": "org.hibernate:hibernate-entitymanager", + "current": "${version.hibernate}" + }, + { + "name": "org.jdom:jdom2", + "current": "2.0.6" + }, + { + "name": "asm:asm", + "current": "3.3.1" + }, + { + "name": "cglib:cglib-nodep", + "current": "3.3.0" + }, + { + "name": "org.hsqldb:hsqldb", + "current": "2.3.6" + }, + { + "name": "org.jfree:jcommon", + "current": "1.0.24" + }, + { + "name": "org.jfree:jfreechart", + "current": "1.5.0" + }, + { + "name": "org.json:json", + "current": "20201115" + }, + { + "name": "org.mockito:mockito-core", + "current": "1.10.19" + }, + { + "name": "org.owasp.esapi:esapi", + "current": "2.2.3.0" + }, + { + "name": "org.springframework:spring-context", + "current": "${version.springframework}" + }, + { + "name": "org.springframework:spring-jdbc", + "current": "${version.springframework}" + }, + { + "name": "org.springframework:spring-tx", + "current": "${version.springframework}" + }, + { + "name": "org.springframework:spring-web", + "current": "${version.springframework}" + }, + { + "name": "org.springframework:spring-webmvc", + "current": "${version.springframework}" + }, + { + "name": "org.yaml:snakeyaml", + "current": "1.29" + }, + { + "name": "xml-apis:xml-apis", + "current": "1.4.01" + } + ], + "vulnerabilities": [ + { + "cvss": 4.2, + "cwe": "CWE-78", + "line": 0, + "class": "BenchmarkTest00001.java (0:0)", + "vul_id": "00000000000000000000000000000000", + "method": "Runtime r = Runtime.getRuntime();", + "column": 0, + "description": "The application executes Commands directly on the Operating System. If using any user input, it must be sanitized to the maximum, cleaning any unnecessary characters. In general, it is recommended to never use calls to native commands, being recommended the JNI (Java Native Interface) for such low level operations.", + "classMessage": "src/main/java/org/owasp/benchmark/testcode/BenchmarkTest00001.java (0:0)" + }, + { + "cvss": 4.2, + "cwe": "CWE-327", + "line": 0, + "class": "BenchmarkTest00002.java (0:0)", + "vul_id": "00000000000000000000000000000000", + "method": "javax.crypto.Cipher c = javax.crypto.Cipher.getInstance(\"DES/CBC/PKCS5Padding\");", + "column": 0, + "description": "DES (Data Encryption Standard) is a symmetric key cryptographic algorithm. Its 56-bit key makes it insecure for modern applications, it was developed in 1970, approved as a standard in 1976 and in 1977 the first vulnerability was discovered. Today it can be broken in about 2 days with a modern graphics card.", + "classMessage": "src/main/java/org/owasp/benchmark/testcode/BenchmarkTest00002.java (0:0)", + "recomendation": "Whenever possible, the use of DES encryption should be avoided, the recommended encryption is AES (Advanced Encryption Standard) with 256 bits, which has been approved by the American security agency (NSA) for encrypting top secret information." + } + ], + "none": 0, + "low": 0, + "medium": 0, + "high": 0, + "critical": 0, + "total": 0, + "sast": { + "name": "org.owasp:benchmark", + "version": "1.2", + "averageCvss": 0, + "securityScore": 0, + "size": "0 Bytes", + "numberOfLines": 0 + } +} diff --git a/plugin/src/test/resources/testfiles/Benchmark_1.2-semgrep-v0.65.0.json b/plugin/src/test/resources/testfiles/Benchmark_1.2-semgrep-v0.65.0.json new file mode 100644 index 00000000..a5b82ba0 --- /dev/null +++ b/plugin/src/test/resources/testfiles/Benchmark_1.2-semgrep-v0.65.0.json @@ -0,0 +1,112 @@ +{ + "errors": [], + "results": [ + { + "check_id": "java.lang.security.audit.formatted-sql-string.formatted-sql-string", + "end": { + "col": 0, + "line": 0 + }, + "extra": { + "is_ignored": false, + "lines": " String sql = \"SELECT * from USERS where USERNAME='foo' and PASSWORD='\" + bar + \"'\";\n\n try {\n java.sql.Statement statement =\n org.owasp.benchmark.helpers.DatabaseHelper.getSqlStatement();\n java.sql.ResultSet rs = statement.executeQuery(sql);\n org.owasp.benchmark.helpers.DatabaseHelper.printResults(rs, sql, response);\n } catch (java.sql.SQLException e) {\n if (org.owasp.benchmark.helpers.DatabaseHelper.hideSQLErrors) {\n response.getWriter().println(\"Error processing request.\");\n return;\n } else throw new ServletException(e);\n }", + "message": "Detected a formatted string in a SQL statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Use a prepared statements (java.sql.PreparedStatement) instead. You can obtain a PreparedStatement using 'connection.prepareStatement'.", + "metadata": { + "asvs": { + "control_id": "5.3.5 Injection", + "control_url": "https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements", + "section": "V5: Validation, Sanitization and Encoding Verification Requirements", + "version": "4" + }, + "category": "security", + "cwe": "CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')", + "license": "Commons Clause License Condition v1.0[LGPL-2.1-only]", + "owasp": "A1: Injection", + "references": [ + "https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html", + "https://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html#create_ps", + "https://software-security.sans.org/developer-how-to/fix-sql-injection-in-java-using-prepared-callable-statement" + ], + "source": "https://semgrep.dev/r/java.lang.security.audit.formatted-sql-string.formatted-sql-string", + "source-rule-url": "https://find-sec-bugs.github.io/bugs.htm#SQL_INJECTION" + }, + "metavars": { + "$CIPHER": { + "abstract_content": "javax.crypto.Cipher", + "end": { + "col": 0, + "line": 0, + "offset": 0 + }, + "start": { + "col": 0, + "line": 0, + "offset": 0 + }, + "unique_id": { + "md5sum": "00000000000000000000000000000000", + "type": "AST" + } + } + }, + "severity": "WARNING" + }, + "path": "src/main/java/org/owasp/benchmark/testcode/BenchmarkTest00001.java", + "start": { + "col": 0, + "line": 0 + } + }, + { + "check_id": "java.lang.security.audit.cookie-missing-secure-flag.cookie-missing-secure-flag", + "end": { + "col": 0, + "line": 0 + }, + "extra": { + "is_ignored": false, + "lines": " cookie.setSecure(false);", + "message": "A cookie was detected without setting the 'secure' flag. The 'secure' flag for cookies prevents the client from transmitting the cookie over insecure channels such as HTTP. Set the 'secure' flag by calling 'cookie.setSecure(true);'", + "metadata": { + "asvs": { + "control_id": "3.4.1 Missing Cookie Attribute", + "control_url": "https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v34-cookie-based-session-management", + "section": "V3: Session Management Verification Requirements", + "version": "4" + }, + "category": "security", + "cwe": "CWE-614: Sensitive Cookie in HTTPS Session Without 'Secure' Attribute", + "license": "Commons Clause License Condition v1.0[LGPL-2.1-only]", + "owasp": "A3: Sensitive Data Exposure", + "source": "https://semgrep.dev/r/java.lang.security.audit.cookie-missing-secure-flag.cookie-missing-secure-flag", + "source-rule-url": "https://find-sec-bugs.github.io/bugs.htm#INSECURE_COOKIE" + }, + "metavars": { + "$CIPHER": { + "abstract_content": "javax.crypto.Cipher", + "end": { + "col": 0, + "line": 0, + "offset": 0 + }, + "start": { + "col": 0, + "line": 0, + "offset": 0 + }, + "unique_id": { + "md5sum": "00000000000000000000000000000000", + "type": "AST" + } + } + }, + "severity": "WARNING" + }, + "path": "src/main/java/org/owasp/benchmark/testcode/BenchmarkTest00002.java", + "start": { + "col": 0, + "line": 0 + } + } + ] +} diff --git a/plugin/src/test/resources/testfiles/Benchmark_1.2-shiftleftscan-v2.0.3.json b/plugin/src/test/resources/testfiles/Benchmark_1.2-shiftleftscan-v2.0.3.json new file mode 100644 index 00000000..e63123ae --- /dev/null +++ b/plugin/src/test/resources/testfiles/Benchmark_1.2-shiftleftscan-v2.0.3.json @@ -0,0 +1,2 @@ +{"tool":{"driver":{"name":"Class File Analyzer","rules":[{"id":"XSS_SERVLET","help":{"text":"This use of java/io/PrintWriter.write(Ljava/lang/String;)V could be vulnerable to XSS in the Servlet \nAt DatabaseHelper.java:[lines 35-428] \nIn class org.owasp.benchmark.helpers.DatabaseHelper \nIn method org.owasp.benchmark.helpers.DatabaseHelper.printColTypes(ResultSetMetaData, PrintWriter) \nAt DatabaseHelper.java:[line 426] \nSink method java/io/PrintWriter.write(Ljava/lang/String;)V \nSink parameter 0 \nUnknown source java/sql/ResultSetMetaData.getColumnTypeName(I)Ljava/lang/String; \nAt DatabaseHelper.java:[line 426].","markdown":"This use of java/io/PrintWriter.write(Ljava/lang/String;)V could be vulnerable to XSS in the Servlet \nAt DatabaseHelper.java:[lines 35-428] \nIn class org.owasp.benchmark.helpers.DatabaseHelper \nIn method org.owasp.benchmark.helpers.DatabaseHelper.printColTypes(ResultSetMetaData, PrintWriter) \nAt DatabaseHelper.java:[line 426] \nSink method java/io/PrintWriter.write(Ljava/lang/String;)V \nSink parameter 0 \nUnknown source java/sql/ResultSetMetaData.getColumnTypeName(I)Ljava/lang/String; \nAt DatabaseHelper.java:[line 426]."},"name":"Xss Servlet","properties":{"tags":["Scan"],"precision":"high"},"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"This use of java/io/PrintWriter.write(Ljava/lang/String;)V could be vulnerable to XSS in the Servlet ."},"helpUri":"https://slscan.io?q=XSS_SERVLET","shortDescription":{"text":"This use of java/io/PrintWriter.write(Ljava/lang/String;)V could be vulnerable to XSS in the Servlet \nAt DatabaseHelper.java:[lines 35-428] \nIn class org.owasp.benchmark.helpers.DatabaseHelper \nIn method org.owasp.benchmark.helpers.DatabaseHelper.printColTypes(ResultSetMetaData, PrintWriter) \nAt DatabaseHelper.java:[line 426] \nSink method java/io/PrintWriter.write(Ljava/lang/String;)V \nSink parameter 0 \nUnknown source java/sql/ResultSetMetaData.getColumnTypeName(I)Ljava/lang/String; \nAt DatabaseHelper.java:[line 426]."}},{"id":"DMI_EMPTY_DB_PASSWORD","help":{"text":"Empty database password in new org.owasp.benchmark.helpers.HibernateUtil(boolean) \nAt HibernateUtil.java:[lines 47-327] \nIn class org.owasp.benchmark.helpers.HibernateUtil \nIn method new org.owasp.benchmark.helpers.HibernateUtil(boolean) \nAt HibernateUtil.java:[line 74].","markdown":"Empty database password in new org.owasp.benchmark.helpers.HibernateUtil(boolean) \nAt HibernateUtil.java:[lines 47-327] \nIn class org.owasp.benchmark.helpers.HibernateUtil \nIn method new org.owasp.benchmark.helpers.HibernateUtil(boolean) \nAt HibernateUtil.java:[line 74]."},"name":"DMI EMPTY DB PASSWORD","properties":{"tags":["Scan"],"precision":"high"},"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"Empty database password in new org.owasp.benchmark.helpers.HibernateUtil(boolean) ."},"helpUri":"https://slscan.io?q=DMI_EMPTY_DB_PASSWORD","shortDescription":{"text":"Empty database password in new org.owasp.benchmark.helpers.HibernateUtil(boolean) \nAt HibernateUtil.java:[lines 47-327] \nIn class org.owasp.benchmark.helpers.HibernateUtil \nIn method new org.owasp.benchmark.helpers.HibernateUtil(boolean) \nAt HibernateUtil.java:[line 74]."}},{"id":"HARD_CODE_PASSWORD","help":{"text":"Hard coded password found \nAt HibernateUtil.java:[lines 47-327] \nIn class org.owasp.benchmark.helpers.HibernateUtil \nIn method new org.owasp.benchmark.helpers.HibernateUtil(boolean) \nAt HibernateUtil.java:[line 74] \nCalled method java.sql.DriverManager.getConnection(String, String, String) \nHard coded parameter number (in reverse order) is 1 \nValue .","markdown":"Hard coded password found \nAt HibernateUtil.java:[lines 47-327] \nIn class org.owasp.benchmark.helpers.HibernateUtil \nIn method new org.owasp.benchmark.helpers.HibernateUtil(boolean) \nAt HibernateUtil.java:[line 74] \nCalled method java.sql.DriverManager.getConnection(String, String, String) \nHard coded parameter number (in reverse order) is 1 \nValue ."},"name":"HARD CODE PASSWORD","properties":{"tags":["Scan"],"precision":"high"},"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"Hard coded password found ."},"helpUri":"https://slscan.io?q=HARD_CODE_PASSWORD","shortDescription":{"text":"Hard coded password found \nAt HibernateUtil.java:[lines 47-327] \nIn class org.owasp.benchmark.helpers.HibernateUtil \nIn method new org.owasp.benchmark.helpers.HibernateUtil(boolean) \nAt HibernateUtil.java:[line 74] \nCalled method java.sql.DriverManager.getConnection(String, String, String) \nHard coded parameter number (in reverse order) is 1 \nValue ."}},{"id":"SQL_INJECTION_HIBERNATE","help":{"text":"This use of org/hibernate/Session.createQuery(Ljava/lang/String;)Lorg/hibernate/Query; can be vulnerable to SQL/HQL injection (with Hibernate) \nAt HibernateUtil.java:[lines 47-327] \nIn class org.owasp.benchmark.helpers.HibernateUtil \nIn method org.owasp.benchmark.helpers.HibernateUtil.checkData(String) \nAt HibernateUtil.java:[line 302] \nSink method org/hibernate/Session.createQuery(Ljava/lang/String;)Lorg/hibernate/Query; \nSink parameter 0 \nUnknown source org/owasp/benchmark/helpers/HibernateUtil.checkData(Ljava/lang/String;)V parameter 0 \nMethod usage not detected.","markdown":"This use of org/hibernate/Session.createQuery(Ljava/lang/String;)Lorg/hibernate/Query; can be vulnerable to SQL/HQL injection (with Hibernate) \nAt HibernateUtil.java:[lines 47-327] \nIn class org.owasp.benchmark.helpers.HibernateUtil \nIn method org.owasp.benchmark.helpers.HibernateUtil.checkData(String) \nAt HibernateUtil.java:[line 302] \nSink method org/hibernate/Session.createQuery(Ljava/lang/String;)Lorg/hibernate/Query; \nSink parameter 0 \nUnknown source org/owasp/benchmark/helpers/HibernateUtil.checkData(Ljava/lang/String;)V parameter 0 \nMethod usage not detected."},"name":"SQL INJECTION HIBERNATE","properties":{"tags":["Scan"],"precision":"high"},"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"This use of org/hibernate/Session.createQuery(Ljava/lang/String;)Lorg/hibernate/Query; can be vulnerable to SQL/HQL injection (with Hibernate) ."},"helpUri":"https://slscan.io?q=SQL_INJECTION_HIBERNATE","shortDescription":{"text":"This use of org/hibernate/Session.createQuery(Ljava/lang/String;)Lorg/hibernate/Query; can be vulnerable to SQL/HQL injection (with Hibernate) \nAt HibernateUtil.java:[lines 47-327] \nIn class org.owasp.benchmark.helpers.HibernateUtil \nIn method org.owasp.benchmark.helpers.HibernateUtil.checkData(String) \nAt HibernateUtil.java:[line 302] \nSink method org/hibernate/Session.createQuery(Ljava/lang/String;)Lorg/hibernate/Query; \nSink parameter 0 \nUnknown source org/owasp/benchmark/helpers/HibernateUtil.checkData(Ljava/lang/String;)V parameter 0 \nMethod usage not detected."}},{"id":"PATH_TRAVERSAL_IN","help":{"text":"This API (java/io/File.(Ljava/lang/String;)V) reads a file whose location might be specified by user input \nAt LDAPServer.java:[lines 50-347] \nIn class org.owasp.benchmark.helpers.LDAPServer \nIn method new org.owasp.benchmark.helpers.LDAPServer() \nAt LDAPServer.java:[line 55] \nSink method java/io/File.(Ljava/lang/String;)V \nSink parameter 0 \nUnknown source java/io/File.getParent()Ljava/lang/String; \nAt LDAPServer.java:[line 55].","markdown":"This API (java/io/File.(Ljava/lang/String;)V) reads a file whose location might be specified by user input \nAt LDAPServer.java:[lines 50-347] \nIn class org.owasp.benchmark.helpers.LDAPServer \nIn method new org.owasp.benchmark.helpers.LDAPServer() \nAt LDAPServer.java:[line 55] \nSink method java/io/File.(Ljava/lang/String;)V \nSink parameter 0 \nUnknown source java/io/File.getParent()Ljava/lang/String; \nAt LDAPServer.java:[line 55]."},"name":"PATH TRAVERSAL IN","properties":{"tags":["Scan"],"precision":"high"},"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"This API (java/io/File.(Ljava/lang/String;)V) reads a file whose location might be specified by user input ."},"helpUri":"https://slscan.io?q=PATH_TRAVERSAL_IN","shortDescription":{"text":"This API (java/io/File.(Ljava/lang/String;)V) reads a file whose location might be specified by user input \nAt LDAPServer.java:[lines 50-347] \nIn class org.owasp.benchmark.helpers.LDAPServer \nIn method new org.owasp.benchmark.helpers.LDAPServer() \nAt LDAPServer.java:[line 55] \nSink method java/io/File.(Ljava/lang/String;)V \nSink parameter 0 \nUnknown source java/io/File.getParent()Ljava/lang/String; \nAt LDAPServer.java:[line 55]."}},{"id":"OVERLY_PERMISSIVE_FILE_PERMISSION","help":{"text":"Overly permissive file permission can lead to privilege escalation or information leakage. \nAt Utils.java:[lines 83-771] \nIn class org.owasp.benchmark.helpers.Utils \nIn method org.owasp.benchmark.helpers.Utils.() \nAt Utils.java:[line 175].","markdown":"Overly permissive file permission can lead to privilege escalation or information leakage. \nAt Utils.java:[lines 83-771] \nIn class org.owasp.benchmark.helpers.Utils \nIn method org.owasp.benchmark.helpers.Utils.() \nAt Utils.java:[line 175]."},"name":"OVERLY PERMISSIVE FILE PERMISSION","properties":{"tags":["Scan"],"precision":"high"},"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"Overly permissive file permission can lead to privilege escalation or information leakage. ."},"helpUri":"https://slscan.io?q=OVERLY_PERMISSIVE_FILE_PERMISSION","shortDescription":{"text":"Overly permissive file permission can lead to privilege escalation or information leakage"}},{"id":"XXE_DOCUMENT","help":{"text":"The use of DocumentBuilder.parse(...) (DocumentBuilder) is vulnerable to XML External Entity attacks \nAt Utils.java:[lines 83-771] \nIn class org.owasp.benchmark.helpers.Utils \nIn method org.owasp.benchmark.helpers.Utils.parseHttpFile(File) \nAt Utils.java:[line 565] \nValue DocumentBuilder.parse(...).","markdown":"The use of DocumentBuilder.parse(...) (DocumentBuilder) is vulnerable to XML External Entity attacks \nAt Utils.java:[lines 83-771] \nIn class org.owasp.benchmark.helpers.Utils \nIn method org.owasp.benchmark.helpers.Utils.parseHttpFile(File) \nAt Utils.java:[line 565] \nValue DocumentBuilder.parse(...)."},"name":"Xxe Document","properties":{"tags":["Scan"],"precision":"high"},"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"The use of DocumentBuilder.parse(...) (DocumentBuilder) is vulnerable to XML External Entity attacks ."},"helpUri":"https://slscan.io?q=XXE_DOCUMENT","shortDescription":{"text":"The use of DocumentBuilder.parse(...) (DocumentBuilder) is vulnerable to XML External Entity attacks \nAt Utils.java:[lines 83-771] \nIn class org.owasp.benchmark.helpers.Utils \nIn method org.owasp.benchmark.helpers.Utils.parseHttpFile(File) \nAt Utils.java:[line 565] \nValue DocumentBuilder.parse(...)."}},{"id":"HTTPONLY_COOKIE","help":{"text":"Cookie without the HttpOnly flag could be read by a malicious script in the browser \nAt BenchmarkTest00001.java:[lines 28-104] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00001 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00001.doGet(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00001.java:[line 36].","markdown":"Cookie without the HttpOnly flag could be read by a malicious script in the browser \nAt BenchmarkTest00001.java:[lines 28-104] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00001 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00001.doGet(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00001.java:[line 36]."},"name":"Httponly Cookie","properties":{"tags":["Scan"],"precision":"high"},"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"Cookie without the HttpOnly flag could be read by a malicious script in the browser ."},"helpUri":"https://slscan.io?q=HTTPONLY_COOKIE","shortDescription":{"text":"Cookie without the HttpOnly flag could be read by a malicious script in the browser \nAt BenchmarkTest00001.java:[lines 28-104] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00001 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00001.doGet(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00001.java:[line 36]."}},{"id":"PATH_TRAVERSAL_OUT","help":{"text":"This API (java/io/FileOutputStream.(Ljava/lang/String;Z)V) writes to a file whose location might be specified by user input \nAt BenchmarkTest00002.java:[lines 28-91] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00002 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00002.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00002.java:[line 72] \nSink method java/io/FileOutputStream.(Ljava/lang/String;Z)V \nSink parameter 1 \nTainted source javax/servlet/http/Cookie.getValue()Ljava/lang/String; \nTainted source java/net/URLDecoder.decode(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; \nUnknown source org/owasp/benchmark/helpers/Utils.TESTFILES_DIR \nAt BenchmarkTest00002.java:[line 60] \nAt BenchmarkTest00002.java:[line 70].","markdown":"This API (java/io/FileOutputStream.(Ljava/lang/String;Z)V) writes to a file whose location might be specified by user input \nAt BenchmarkTest00002.java:[lines 28-91] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00002 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00002.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00002.java:[line 72] \nSink method java/io/FileOutputStream.(Ljava/lang/String;Z)V \nSink parameter 1 \nTainted source javax/servlet/http/Cookie.getValue()Ljava/lang/String; \nTainted source java/net/URLDecoder.decode(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; \nUnknown source org/owasp/benchmark/helpers/Utils.TESTFILES_DIR \nAt BenchmarkTest00002.java:[line 60] \nAt BenchmarkTest00002.java:[line 70]."},"name":"PATH TRAVERSAL OUT","properties":{"tags":["Scan"],"precision":"high"},"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"This API (java/io/FileOutputStream.(Ljava/lang/String;Z)V) writes to a file whose location might be specified by user input ."},"helpUri":"https://slscan.io?q=PATH_TRAVERSAL_OUT","shortDescription":{"text":"This API (java/io/FileOutputStream.(Ljava/lang/String;Z)V) writes to a file whose location might be specified by user input \nAt BenchmarkTest00002.java:[lines 28-91] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00002 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00002.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00002.java:[line 72] \nSink method java/io/FileOutputStream.(Ljava/lang/String;Z)V \nSink parameter 1 \nTainted source javax/servlet/http/Cookie.getValue()Ljava/lang/String; \nTainted source java/net/URLDecoder.decode(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; \nUnknown source org/owasp/benchmark/helpers/Utils.TESTFILES_DIR \nAt BenchmarkTest00002.java:[line 60] \nAt BenchmarkTest00002.java:[line 70]."}},{"id":"TRUST_BOUNDARY_VIOLATION","help":{"text":"The application mixes trusted and untrusted data in session attributes. \nAt BenchmarkTest00004.java:[lines 28-74] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00004 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00004.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00004.java:[line 67] \nSink method javax/servlet/http/HttpSession.setAttribute(Ljava/lang/String;Ljava/lang/Object;)V \nSink parameter 1 \nTainted source javax/servlet/http/Cookie.getValue()Ljava/lang/String; \nTainted source java/net/URLDecoder.decode(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; \nAt BenchmarkTest00004.java:[line 60].","markdown":"The application mixes trusted and untrusted data in session attributes. \nAt BenchmarkTest00004.java:[lines 28-74] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00004 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00004.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00004.java:[line 67] \nSink method javax/servlet/http/HttpSession.setAttribute(Ljava/lang/String;Ljava/lang/Object;)V \nSink parameter 1 \nTainted source javax/servlet/http/Cookie.getValue()Ljava/lang/String; \nTainted source java/net/URLDecoder.decode(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; \nAt BenchmarkTest00004.java:[line 60]."},"name":"TRUST BOUNDARY VIOLATION","properties":{"tags":["Scan"],"precision":"high"},"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"The application mixes trusted and untrusted data in session attributes. ."},"helpUri":"https://slscan.io?q=TRUST_BOUNDARY_VIOLATION","shortDescription":{"text":"The application mixes trusted and untrusted data in session attributes"}},{"id":"CIPHER_INTEGRITY","help":{"text":"The cipher does not provide data integrity \nAt BenchmarkTest00005.java:[lines 28-121] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00005 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00005.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00005.java:[line 63].","markdown":"The cipher does not provide data integrity \nAt BenchmarkTest00005.java:[lines 28-121] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00005 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00005.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00005.java:[line 63]."},"name":"Cipher Integrity","properties":{"tags":["Scan"],"precision":"high"},"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"The cipher does not provide data integrity ."},"helpUri":"https://slscan.io?q=CIPHER_INTEGRITY","shortDescription":{"text":"The cipher does not provide data integrity \nAt BenchmarkTest00005.java:[lines 28-121] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00005 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00005.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00005.java:[line 63]."}},{"id":"DES_USAGE","help":{"text":"DES should be replaced with AES \nAt BenchmarkTest00005.java:[lines 28-121] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00005 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00005.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00005.java:[line 63] \nSink method javax/crypto/Cipher.getInstance(Ljava/lang/String;)Ljavax/crypto/Cipher; \nSink parameter 0.","markdown":"DES should be replaced with AES \nAt BenchmarkTest00005.java:[lines 28-121] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00005 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00005.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00005.java:[line 63] \nSink method javax/crypto/Cipher.getInstance(Ljava/lang/String;)Ljavax/crypto/Cipher; \nSink parameter 0."},"name":"Des Usage","properties":{"tags":["Scan"],"precision":"high"},"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"DES should be replaced with AES ."},"helpUri":"https://slscan.io?q=DES_USAGE","shortDescription":{"text":"DES should be replaced with AES \nAt BenchmarkTest00005.java:[lines 28-121] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00005 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00005.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00005.java:[line 63] \nSink method javax/crypto/Cipher.getInstance(Ljava/lang/String;)Ljavax/crypto/Cipher; \nSink parameter 0."}},{"id":"PADDING_ORACLE","help":{"text":"The cipher is susceptible to padding oracle attacks \nAt BenchmarkTest00005.java:[lines 28-121] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00005 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00005.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00005.java:[line 63].","markdown":"The cipher is susceptible to padding oracle attacks \nAt BenchmarkTest00005.java:[lines 28-121] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00005 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00005.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00005.java:[line 63]."},"name":"Padding Oracle","properties":{"tags":["Scan"],"precision":"high"},"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"The cipher is susceptible to padding oracle attacks ."},"helpUri":"https://slscan.io?q=PADDING_ORACLE","shortDescription":{"text":"The cipher is susceptible to padding oracle attacks \nAt BenchmarkTest00005.java:[lines 28-121] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00005 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00005.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00005.java:[line 63]."}},{"id":"STATIC_IV","help":{"text":"The initialization vector (IV) is not properly generated \nAt BenchmarkTest00005.java:[lines 28-121] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00005 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00005.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00005.java:[line 67].","markdown":"The initialization vector (IV) is not properly generated \nAt BenchmarkTest00005.java:[lines 28-121] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00005 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00005.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00005.java:[line 67]."},"name":"Static Iv","properties":{"tags":["Scan"],"precision":"high"},"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"The initialization vector (IV) is not properly generated ."},"helpUri":"https://slscan.io?q=STATIC_IV","shortDescription":{"text":"The initialization vector (IV) is not properly generated \nAt BenchmarkTest00005.java:[lines 28-121] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00005 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00005.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00005.java:[line 67]."}},{"id":"COMMAND_INJECTION","help":{"text":"This usage of java/lang/ProcessBuilder.command(Ljava/util/List;)Ljava/lang/ProcessBuilder; can be vulnerable to Command Injection \nAt BenchmarkTest00006.java:[lines 28-76] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00006 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00006.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00006.java:[line 66] \nSink method java/lang/ProcessBuilder.command(Ljava/util/List;)Ljava/lang/ProcessBuilder; \nSink parameter 0 \nTainted source javax/servlet/http/HttpServletRequest.getHeader(Ljava/lang/String;)Ljava/lang/String; \nTainted source java/net/URLDecoder.decode(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; \nAt BenchmarkTest00006.java:[line 46] \nAt BenchmarkTest00006.java:[line 50] \nAt BenchmarkTest00006.java:[line 62].","markdown":"This usage of java/lang/ProcessBuilder.command(Ljava/util/List;)Ljava/lang/ProcessBuilder; can be vulnerable to Command Injection \nAt BenchmarkTest00006.java:[lines 28-76] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00006 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00006.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00006.java:[line 66] \nSink method java/lang/ProcessBuilder.command(Ljava/util/List;)Ljava/lang/ProcessBuilder; \nSink parameter 0 \nTainted source javax/servlet/http/HttpServletRequest.getHeader(Ljava/lang/String;)Ljava/lang/String; \nTainted source java/net/URLDecoder.decode(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; \nAt BenchmarkTest00006.java:[line 46] \nAt BenchmarkTest00006.java:[line 50] \nAt BenchmarkTest00006.java:[line 62]."},"name":"Command Injection","properties":{"tags":["Scan"],"precision":"high"},"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"This usage of java/lang/ProcessBuilder.command(Ljava/util/List;)Ljava/lang/ProcessBuilder; can be vulnerable to Command Injection ."},"helpUri":"https://slscan.io?q=COMMAND_INJECTION","shortDescription":{"text":"This usage of java/lang/ProcessBuilder.command(Ljava/util/List;)Ljava/lang/ProcessBuilder; can be vulnerable to Command Injection \nAt BenchmarkTest00006.java:[lines 28-76] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00006 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00006.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00006.java:[line 66] \nSink method java/lang/ProcessBuilder.command(Ljava/util/List;)Ljava/lang/ProcessBuilder; \nSink parameter 0 \nTainted source javax/servlet/http/HttpServletRequest.getHeader(Ljava/lang/String;)Ljava/lang/String; \nTainted source java/net/URLDecoder.decode(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; \nAt BenchmarkTest00006.java:[line 46] \nAt BenchmarkTest00006.java:[line 50] \nAt BenchmarkTest00006.java:[line 62]."}},{"id":"SQL_INJECTION_JDBC","help":{"text":"This use of java/sql/Connection.prepareCall(Ljava/lang/String;)Ljava/sql/CallableStatement; can be vulnerable to SQL injection (with JDBC) \nAt BenchmarkTest00008.java:[lines 28-67] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00008 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00008.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00008.java:[line 57] \nSink method java/sql/Connection.prepareCall(Ljava/lang/String;)Ljava/sql/CallableStatement; \nSink parameter 0 \nTainted source javax/servlet/http/HttpServletRequest.getHeader(Ljava/lang/String;)Ljava/lang/String; \nTainted source java/net/URLDecoder.decode(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; \nAt BenchmarkTest00008.java:[line 46] \nAt BenchmarkTest00008.java:[line 50] \nAt BenchmarkTest00008.java:[line 52].","markdown":"This use of java/sql/Connection.prepareCall(Ljava/lang/String;)Ljava/sql/CallableStatement; can be vulnerable to SQL injection (with JDBC) \nAt BenchmarkTest00008.java:[lines 28-67] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00008 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00008.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00008.java:[line 57] \nSink method java/sql/Connection.prepareCall(Ljava/lang/String;)Ljava/sql/CallableStatement; \nSink parameter 0 \nTainted source javax/servlet/http/HttpServletRequest.getHeader(Ljava/lang/String;)Ljava/lang/String; \nTainted source java/net/URLDecoder.decode(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; \nAt BenchmarkTest00008.java:[line 46] \nAt BenchmarkTest00008.java:[line 50] \nAt BenchmarkTest00008.java:[line 52]."},"name":"SQL INJECTION JDBC","properties":{"tags":["Scan"],"precision":"high"},"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"This use of java/sql/Connection.prepareCall(Ljava/lang/String;)Ljava/sql/CallableStatement; can be vulnerable to SQL injection (with JDBC) ."},"helpUri":"https://slscan.io?q=SQL_INJECTION_JDBC","shortDescription":{"text":"This use of java/sql/Connection.prepareCall(Ljava/lang/String;)Ljava/sql/CallableStatement; can be vulnerable to SQL injection (with JDBC) \nAt BenchmarkTest00008.java:[lines 28-67] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00008 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00008.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00008.java:[line 57] \nSink method java/sql/Connection.prepareCall(Ljava/lang/String;)Ljava/sql/CallableStatement; \nSink parameter 0 \nTainted source javax/servlet/http/HttpServletRequest.getHeader(Ljava/lang/String;)Ljava/lang/String; \nTainted source java/net/URLDecoder.decode(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; \nAt BenchmarkTest00008.java:[line 46] \nAt BenchmarkTest00008.java:[line 50] \nAt BenchmarkTest00008.java:[line 52]."}},{"id":"LDAP_INJECTION","help":{"text":"This use of javax/naming/directory/InitialDirContext.search(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;Ljavax/naming/directory/SearchControls;)Ljavax/naming/NamingEnumeration; can be vulnerable to LDAP injection \nAt BenchmarkTest00012.java:[lines 28-105] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00012 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00012.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00012.java:[line 68] \nSink method javax/naming/directory/InitialDirContext.search(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;Ljavax/naming/directory/SearchControls;)Ljavax/naming/NamingEnumeration; \nSink parameter 2 \nTainted source javax/servlet/http/HttpServletRequest.getHeaders(Ljava/lang/String;)Ljava/util/Enumeration; \nTainted source java/net/URLDecoder.decode(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; \nTainted source java/util/Enumeration.nextElement()Ljava/lang/Object; \nAt BenchmarkTest00012.java:[line 45] \nAt BenchmarkTest00012.java:[line 48] \nAt BenchmarkTest00012.java:[line 52] \nAt BenchmarkTest00012.java:[line 60].","markdown":"This use of javax/naming/directory/InitialDirContext.search(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;Ljavax/naming/directory/SearchControls;)Ljavax/naming/NamingEnumeration; can be vulnerable to LDAP injection \nAt BenchmarkTest00012.java:[lines 28-105] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00012 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00012.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00012.java:[line 68] \nSink method javax/naming/directory/InitialDirContext.search(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;Ljavax/naming/directory/SearchControls;)Ljavax/naming/NamingEnumeration; \nSink parameter 2 \nTainted source javax/servlet/http/HttpServletRequest.getHeaders(Ljava/lang/String;)Ljava/util/Enumeration; \nTainted source java/net/URLDecoder.decode(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; \nTainted source java/util/Enumeration.nextElement()Ljava/lang/Object; \nAt BenchmarkTest00012.java:[line 45] \nAt BenchmarkTest00012.java:[line 48] \nAt BenchmarkTest00012.java:[line 52] \nAt BenchmarkTest00012.java:[line 60]."},"name":"Ldap Injection","properties":{"tags":["Scan"],"precision":"high"},"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"This use of javax/naming/directory/InitialDirContext.search(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;Ljavax/naming/directory/SearchControls;)Ljavax/naming/NamingEnumeration; can be vulnerable to LDAP injection ."},"helpUri":"https://slscan.io?q=LDAP_INJECTION","shortDescription":{"text":"This use of javax/naming/directory/InitialDirContext.search(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;Ljavax/naming/directory/SearchControls;)Ljavax/naming/NamingEnumeration; can be vulnerable to LDAP injection \nAt BenchmarkTest00012.java:[lines 28-105] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00012 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00012.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00012.java:[line 68] \nSink method javax/naming/directory/InitialDirContext.search(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;Ljavax/naming/directory/SearchControls;)Ljavax/naming/NamingEnumeration; \nSink parameter 2 \nTainted source javax/servlet/http/HttpServletRequest.getHeaders(Ljava/lang/String;)Ljava/util/Enumeration; \nTainted source java/net/URLDecoder.decode(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; \nTainted source java/util/Enumeration.nextElement()Ljava/lang/Object; \nAt BenchmarkTest00012.java:[line 45] \nAt BenchmarkTest00012.java:[line 48] \nAt BenchmarkTest00012.java:[line 52] \nAt BenchmarkTest00012.java:[line 60]."}},{"id":"HTTP_RESPONSE_SPLITTING","help":{"text":"This use of javax/servlet/http/Cookie.(Ljava/lang/String;Ljava/lang/String;)V might be used to include CRLF characters into HTTP headers \nAt BenchmarkTest00016.java:[lines 28-82] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00016 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00016.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00016.java:[line 69] \nSink method javax/servlet/http/Cookie.(Ljava/lang/String;Ljava/lang/String;)V \nSink parameter 0 \nTainted source javax/servlet/http/HttpServletRequest.getHeaders(Ljava/lang/String;)Ljava/util/Enumeration; \nTainted source java/util/Enumeration.nextElement()Ljava/lang/Object; \nTainted source java/net/URLDecoder.decode(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; \nAt BenchmarkTest00016.java:[line 45] \nAt BenchmarkTest00016.java:[line 48] \nAt BenchmarkTest00016.java:[line 52] \nAt BenchmarkTest00016.java:[line 66].","markdown":"This use of javax/servlet/http/Cookie.(Ljava/lang/String;Ljava/lang/String;)V might be used to include CRLF characters into HTTP headers \nAt BenchmarkTest00016.java:[lines 28-82] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00016 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00016.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00016.java:[line 69] \nSink method javax/servlet/http/Cookie.(Ljava/lang/String;Ljava/lang/String;)V \nSink parameter 0 \nTainted source javax/servlet/http/HttpServletRequest.getHeaders(Ljava/lang/String;)Ljava/util/Enumeration; \nTainted source java/util/Enumeration.nextElement()Ljava/lang/Object; \nTainted source java/net/URLDecoder.decode(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; \nAt BenchmarkTest00016.java:[line 45] \nAt BenchmarkTest00016.java:[line 48] \nAt BenchmarkTest00016.java:[line 52] \nAt BenchmarkTest00016.java:[line 66]."},"name":"HTTP RESPONSE SPLITTING","properties":{"tags":["Scan"],"precision":"high"},"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"This use of javax/servlet/http/Cookie.(Ljava/lang/String;Ljava/lang/String;)V might be used to include CRLF characters into HTTP headers ."},"helpUri":"https://slscan.io?q=HTTP_RESPONSE_SPLITTING","shortDescription":{"text":"This use of javax/servlet/http/Cookie.(Ljava/lang/String;Ljava/lang/String;)V might be used to include CRLF characters into HTTP headers \nAt BenchmarkTest00016.java:[lines 28-82] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00016 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00016.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00016.java:[line 69] \nSink method javax/servlet/http/Cookie.(Ljava/lang/String;Ljava/lang/String;)V \nSink parameter 0 \nTainted source javax/servlet/http/HttpServletRequest.getHeaders(Ljava/lang/String;)Ljava/util/Enumeration; \nTainted source java/util/Enumeration.nextElement()Ljava/lang/Object; \nTainted source java/net/URLDecoder.decode(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; \nAt BenchmarkTest00016.java:[line 45] \nAt BenchmarkTest00016.java:[line 48] \nAt BenchmarkTest00016.java:[line 52] \nAt BenchmarkTest00016.java:[line 66]."}},{"id":"PREDICTABLE_RANDOM","help":{"text":"This random generator (java.util.Random) is predictable \nAt BenchmarkTest00023.java:[lines 28-95] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00023 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00023.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00023.java:[line 47] \nValue java.util.Random.","markdown":"This random generator (java.util.Random) is predictable \nAt BenchmarkTest00023.java:[lines 28-95] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00023 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00023.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00023.java:[line 47] \nValue java.util.Random."},"name":"Predictable Random","properties":{"tags":["Scan"],"precision":"high"},"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"This random generator (java.util.Random) is predictable ."},"helpUri":"https://slscan.io?q=PREDICTABLE_RANDOM","shortDescription":{"text":"This random generator (java.util.Random) is predictable \nAt BenchmarkTest00023.java:[lines 28-95] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00023 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00023.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00023.java:[line 47] \nValue java.util.Random."}},{"id":"SQL_INJECTION_SPRING_JDBC","help":{"text":"This use of org/springframework/jdbc/core/JdbcTemplate.queryForObject(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object; can be vulnerable to SQL injection (with Spring JDBC) \nAt BenchmarkTest00025.java:[lines 28-70] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00025 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00025.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00025.java:[line 53] \nSink method org/springframework/jdbc/core/JdbcTemplate.queryForObject(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object; \nSink parameter 1 \nTainted source javax/servlet/http/HttpServletRequest.getParameter(Ljava/lang/String;)Ljava/lang/String; \nAt BenchmarkTest00025.java:[line 44] \nAt BenchmarkTest00025.java:[line 47].","markdown":"This use of org/springframework/jdbc/core/JdbcTemplate.queryForObject(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object; can be vulnerable to SQL injection (with Spring JDBC) \nAt BenchmarkTest00025.java:[lines 28-70] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00025 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00025.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00025.java:[line 53] \nSink method org/springframework/jdbc/core/JdbcTemplate.queryForObject(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object; \nSink parameter 1 \nTainted source javax/servlet/http/HttpServletRequest.getParameter(Ljava/lang/String;)Ljava/lang/String; \nAt BenchmarkTest00025.java:[line 44] \nAt BenchmarkTest00025.java:[line 47]."},"name":"SQL INJECTION SPRING JDBC","properties":{"tags":["Scan"],"precision":"high"},"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"This use of org/springframework/jdbc/core/JdbcTemplate.queryForObject(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object; can be vulnerable to SQL injection (with Spring JDBC) ."},"helpUri":"https://slscan.io?q=SQL_INJECTION_SPRING_JDBC","shortDescription":{"text":"This use of org/springframework/jdbc/core/JdbcTemplate.queryForObject(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object; can be vulnerable to SQL injection (with Spring JDBC) \nAt BenchmarkTest00025.java:[lines 28-70] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00025 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00025.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00025.java:[line 53] \nSink method org/springframework/jdbc/core/JdbcTemplate.queryForObject(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object; \nSink parameter 1 \nTainted source javax/servlet/http/HttpServletRequest.getParameter(Ljava/lang/String;)Ljava/lang/String; \nAt BenchmarkTest00025.java:[line 44] \nAt BenchmarkTest00025.java:[line 47]."}},{"id":"WEAK_MESSAGE_DIGEST_MD5","help":{"text":"This API MD5 (MDX) is not a recommended cryptographic hash function \nAt BenchmarkTest00046.java:[lines 28-97] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00046 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00046.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00046.java:[line 50] \nValue MD5.","markdown":"This API MD5 (MDX) is not a recommended cryptographic hash function \nAt BenchmarkTest00046.java:[lines 28-97] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00046 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00046.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00046.java:[line 50] \nValue MD5."},"name":"WEAK MESSAGE DIGEST MD5","properties":{"tags":["Scan"],"precision":"high"},"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"This API MD5 (MDX) is not a recommended cryptographic hash function ."},"helpUri":"https://slscan.io?q=WEAK_MESSAGE_DIGEST_MD5","shortDescription":{"text":"This API MD5 (MDX) is not a recommended cryptographic hash function \nAt BenchmarkTest00046.java:[lines 28-97] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00046 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00046.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00046.java:[line 50] \nValue MD5."}},{"id":"WEAK_MESSAGE_DIGEST_SHA1","help":{"text":"This API SHA1 (SHA-1) is not a recommended cryptographic hash function \nAt BenchmarkTest00070.java:[lines 28-125] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00070 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00070.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00070.java:[line 73] \nValue SHA1.","markdown":"This API SHA1 (SHA-1) is not a recommended cryptographic hash function \nAt BenchmarkTest00070.java:[lines 28-125] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00070 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00070.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00070.java:[line 73] \nValue SHA1."},"name":"WEAK MESSAGE DIGEST SHA1","properties":{"tags":["Scan"],"precision":"high"},"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"This API SHA1 (SHA-1) is not a recommended cryptographic hash function ."},"helpUri":"https://slscan.io?q=WEAK_MESSAGE_DIGEST_SHA1","shortDescription":{"text":"This API SHA1 (SHA-1) is not a recommended cryptographic hash function \nAt BenchmarkTest00070.java:[lines 28-125] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00070 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00070.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00070.java:[line 73] \nValue SHA1."}},{"id":"INSECURE_COOKIE","help":{"text":"Cookie without the secure flag could be sent in clear text if a HTTP URL is visited \nAt BenchmarkTest00087.java:[lines 28-102] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00087 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00087.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00087.java:[line 89].","markdown":"Cookie without the secure flag could be sent in clear text if a HTTP URL is visited \nAt BenchmarkTest00087.java:[lines 28-102] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00087 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00087.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00087.java:[line 89]."},"name":"Insecure Cookie","properties":{"tags":["Scan"],"precision":"high"},"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"Cookie without the secure flag could be sent in clear text if a HTTP URL is visited ."},"helpUri":"https://slscan.io?q=INSECURE_COOKIE","shortDescription":{"text":"Cookie without the secure flag could be sent in clear text if a HTTP URL is visited \nAt BenchmarkTest00087.java:[lines 28-102] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00087 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00087.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00087.java:[line 89]."}},{"id":"XPATH_INJECTION","help":{"text":"This use of javax/xml/xpath/XPath.compile(Ljava/lang/String;)Ljavax/xml/xpath/XPathExpression; can be vulnerable to XPath Injection \nAt BenchmarkTest00116.java:[lines 28-109] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00116 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00116.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00116.java:[line 90] \nSink method javax/xml/xpath/XPath.compile(Ljava/lang/String;)Ljavax/xml/xpath/XPathExpression; \nSink parameter 0 \nTainted source javax/servlet/http/Cookie.getValue()Ljava/lang/String; \nTainted source java/net/URLDecoder.decode(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; \nAt BenchmarkTest00116.java:[line 59] \nAt BenchmarkTest00116.java:[line 68] \nAt BenchmarkTest00116.java:[line 69] \nAt BenchmarkTest00116.java:[line 71] \nAt BenchmarkTest00116.java:[line 87].","markdown":"This use of javax/xml/xpath/XPath.compile(Ljava/lang/String;)Ljavax/xml/xpath/XPathExpression; can be vulnerable to XPath Injection \nAt BenchmarkTest00116.java:[lines 28-109] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00116 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00116.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00116.java:[line 90] \nSink method javax/xml/xpath/XPath.compile(Ljava/lang/String;)Ljavax/xml/xpath/XPathExpression; \nSink parameter 0 \nTainted source javax/servlet/http/Cookie.getValue()Ljava/lang/String; \nTainted source java/net/URLDecoder.decode(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; \nAt BenchmarkTest00116.java:[line 59] \nAt BenchmarkTest00116.java:[line 68] \nAt BenchmarkTest00116.java:[line 69] \nAt BenchmarkTest00116.java:[line 71] \nAt BenchmarkTest00116.java:[line 87]."},"name":"Xpath Injection","properties":{"tags":["Scan"],"precision":"high"},"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"This use of javax/xml/xpath/XPath.compile(Ljava/lang/String;)Ljavax/xml/xpath/XPathExpression; can be vulnerable to XPath Injection ."},"helpUri":"https://slscan.io?q=XPATH_INJECTION","shortDescription":{"text":"This use of javax/xml/xpath/XPath.compile(Ljava/lang/String;)Ljavax/xml/xpath/XPathExpression; can be vulnerable to XPath Injection \nAt BenchmarkTest00116.java:[lines 28-109] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00116 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00116.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00116.java:[line 90] \nSink method javax/xml/xpath/XPath.compile(Ljava/lang/String;)Ljavax/xml/xpath/XPathExpression; \nSink parameter 0 \nTainted source javax/servlet/http/Cookie.getValue()Ljava/lang/String; \nTainted source java/net/URLDecoder.decode(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; \nAt BenchmarkTest00116.java:[line 59] \nAt BenchmarkTest00116.java:[line 68] \nAt BenchmarkTest00116.java:[line 69] \nAt BenchmarkTest00116.java:[line 71] \nAt BenchmarkTest00116.java:[line 87]."}},{"id":"PT_ABSOLUTE_PATH_TRAVERSAL","help":{"text":"Absolute path traversal in org.owasp.benchmark.testcode.BenchmarkTest00359.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00359.java:[lines 28-68] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00359 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00359.doPost(HttpServletRequest, HttpServletResponse) \nCalled method new java.io.File(String) \nParameter \"BenchmarkTest00359\" \nValue generated at BenchmarkTest00359.java:[line 43] \nLocal variable named param \nAt BenchmarkTest00359.java:[line 53].","markdown":"Absolute path traversal in org.owasp.benchmark.testcode.BenchmarkTest00359.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00359.java:[lines 28-68] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00359 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00359.doPost(HttpServletRequest, HttpServletResponse) \nCalled method new java.io.File(String) \nParameter \"BenchmarkTest00359\" \nValue generated at BenchmarkTest00359.java:[line 43] \nLocal variable named param \nAt BenchmarkTest00359.java:[line 53]."},"name":"PT ABSOLUTE PATH TRAVERSAL","properties":{"tags":["Scan"],"precision":"high"},"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"Absolute path traversal in org.owasp.benchmark.testcode.BenchmarkTest00359.doPost(HttpServletRequest, HttpServletResponse) ."},"helpUri":"https://slscan.io?q=PT_ABSOLUTE_PATH_TRAVERSAL","shortDescription":{"text":"Absolute path traversal in org.owasp.benchmark.testcode.BenchmarkTest00359.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00359.java:[lines 28-68] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00359 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00359.doPost(HttpServletRequest, HttpServletResponse) \nCalled method new java.io.File(String) \nParameter \"BenchmarkTest00359\" \nValue generated at BenchmarkTest00359.java:[line 43] \nLocal variable named param \nAt BenchmarkTest00359.java:[line 53]."}},{"id":"PT_RELATIVE_PATH_TRAVERSAL","help":{"text":"Relative path traversal in org.owasp.benchmark.testcode.BenchmarkTest00361.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00361.java:[lines 28-95] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00361 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00361.doPost(HttpServletRequest, HttpServletResponse) \nCalled method new java.io.FileInputStream(String) \nParameter \"BenchmarkTest00361\" \nValue generated at BenchmarkTest00361.java:[line 43] \nLocal variable named fileName \nAt BenchmarkTest00361.java:[line 72].","markdown":"Relative path traversal in org.owasp.benchmark.testcode.BenchmarkTest00361.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00361.java:[lines 28-95] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00361 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00361.doPost(HttpServletRequest, HttpServletResponse) \nCalled method new java.io.FileInputStream(String) \nParameter \"BenchmarkTest00361\" \nValue generated at BenchmarkTest00361.java:[line 43] \nLocal variable named fileName \nAt BenchmarkTest00361.java:[line 72]."},"name":"PT RELATIVE PATH TRAVERSAL","properties":{"tags":["Scan"],"precision":"high"},"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"Relative path traversal in org.owasp.benchmark.testcode.BenchmarkTest00361.doPost(HttpServletRequest, HttpServletResponse) ."},"helpUri":"https://slscan.io?q=PT_RELATIVE_PATH_TRAVERSAL","shortDescription":{"text":"Relative path traversal in org.owasp.benchmark.testcode.BenchmarkTest00361.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00361.java:[lines 28-95] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00361 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00361.doPost(HttpServletRequest, HttpServletResponse) \nCalled method new java.io.FileInputStream(String) \nParameter \"BenchmarkTest00361\" \nValue generated at BenchmarkTest00361.java:[line 43] \nLocal variable named fileName \nAt BenchmarkTest00361.java:[line 72]."}},{"id":"XSS_REQUEST_PARAMETER_TO_SERVLET_WRITER","help":{"text":"HTTP parameter written to Servlet output in org.owasp.benchmark.testcode.BenchmarkTest00380.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00380.java:[lines 28-69] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00380 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00380.doPost(HttpServletRequest, HttpServletResponse) \nParameter \"BenchmarkTest00380\" \nValue generated at BenchmarkTest00380.java:[line 43] \nLocal variable named bar \nAt BenchmarkTest00380.java:[line 68].","markdown":"HTTP parameter written to Servlet output in org.owasp.benchmark.testcode.BenchmarkTest00380.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00380.java:[lines 28-69] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00380 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00380.doPost(HttpServletRequest, HttpServletResponse) \nParameter \"BenchmarkTest00380\" \nValue generated at BenchmarkTest00380.java:[line 43] \nLocal variable named bar \nAt BenchmarkTest00380.java:[line 68]."},"name":"XSS REQUEST PARAMETER TO SERVLET WRITER","properties":{"tags":["Scan"],"precision":"high"},"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"HTTP parameter written to Servlet output in org.owasp.benchmark.testcode.BenchmarkTest00380.doPost(HttpServletRequest, HttpServletResponse) ."},"helpUri":"https://slscan.io?q=XSS_REQUEST_PARAMETER_TO_SERVLET_WRITER","shortDescription":{"text":"HTTP parameter written to Servlet output in org.owasp.benchmark.testcode.BenchmarkTest00380.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00380.java:[lines 28-69] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00380 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00380.doPost(HttpServletRequest, HttpServletResponse) \nParameter \"BenchmarkTest00380\" \nValue generated at BenchmarkTest00380.java:[line 43] \nLocal variable named bar \nAt BenchmarkTest00380.java:[line 68]."}},{"id":"HRS_REQUEST_PARAMETER_TO_COOKIE","help":{"text":"HTTP cookie formed from untrusted input in org.owasp.benchmark.testcode.BenchmarkTest00403.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00403.java:[lines 28-81] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00403 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00403.doPost(HttpServletRequest, HttpServletResponse) \nParameter \"BenchmarkTest00403\" \nValue generated at BenchmarkTest00403.java:[line 43] \nLocal variable named str \nAt BenchmarkTest00403.java:[line 68].","markdown":"HTTP cookie formed from untrusted input in org.owasp.benchmark.testcode.BenchmarkTest00403.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00403.java:[lines 28-81] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00403 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00403.doPost(HttpServletRequest, HttpServletResponse) \nParameter \"BenchmarkTest00403\" \nValue generated at BenchmarkTest00403.java:[line 43] \nLocal variable named str \nAt BenchmarkTest00403.java:[line 68]."},"name":"HRS REQUEST PARAMETER TO COOKIE","properties":{"tags":["Scan"],"precision":"high"},"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"HTTP cookie formed from untrusted input in org.owasp.benchmark.testcode.BenchmarkTest00403.doPost(HttpServletRequest, HttpServletResponse) ."},"helpUri":"https://slscan.io?q=HRS_REQUEST_PARAMETER_TO_COOKIE","shortDescription":{"text":"HTTP cookie formed from untrusted input in org.owasp.benchmark.testcode.BenchmarkTest00403.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00403.java:[lines 28-81] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00403 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00403.doPost(HttpServletRequest, HttpServletResponse) \nParameter \"BenchmarkTest00403\" \nValue generated at BenchmarkTest00403.java:[line 43] \nLocal variable named str \nAt BenchmarkTest00403.java:[line 68]."}},{"id":"XXE_DTD_TRANSFORM_FACTORY","help":{"text":"The use of TransformerFactory.newInstance(...) (TransformerFactory) is vulnerable to XML External Entity attacks \nAt NoisyCricket.java:[lines 46-207] \nIn class org.owasp.benchmark.tools.NoisyCricket \nIn method org.owasp.benchmark.tools.NoisyCricket.main(String[]) \nAt NoisyCricket.java:[line 89] \nValue TransformerFactory.newInstance(...).","markdown":"The use of TransformerFactory.newInstance(...) (TransformerFactory) is vulnerable to XML External Entity attacks \nAt NoisyCricket.java:[lines 46-207] \nIn class org.owasp.benchmark.tools.NoisyCricket \nIn method org.owasp.benchmark.tools.NoisyCricket.main(String[]) \nAt NoisyCricket.java:[line 89] \nValue TransformerFactory.newInstance(...)."},"name":"XXE DTD TRANSFORM FACTORY","properties":{"tags":["Scan"],"precision":"high"},"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"The use of TransformerFactory.newInstance(...) (TransformerFactory) is vulnerable to XML External Entity attacks ."},"helpUri":"https://slscan.io?q=XXE_DTD_TRANSFORM_FACTORY","shortDescription":{"text":"The use of TransformerFactory.newInstance(...) (TransformerFactory) is vulnerable to XML External Entity attacks \nAt NoisyCricket.java:[lines 46-207] \nIn class org.owasp.benchmark.tools.NoisyCricket \nIn method org.owasp.benchmark.tools.NoisyCricket.main(String[]) \nAt NoisyCricket.java:[line 89] \nValue TransformerFactory.newInstance(...)."}},{"id":"XXE_XSLT_TRANSFORM_FACTORY","help":{"text":"The use of TransformerFactory.newInstance(...) is vulnerable to XSLT External Entity attacks \nAt NoisyCricket.java:[lines 46-207] \nIn class org.owasp.benchmark.tools.NoisyCricket \nIn method org.owasp.benchmark.tools.NoisyCricket.main(String[]) \nAt NoisyCricket.java:[line 89] \nValue TransformerFactory.newInstance(...).","markdown":"The use of TransformerFactory.newInstance(...) is vulnerable to XSLT External Entity attacks \nAt NoisyCricket.java:[lines 46-207] \nIn class org.owasp.benchmark.tools.NoisyCricket \nIn method org.owasp.benchmark.tools.NoisyCricket.main(String[]) \nAt NoisyCricket.java:[line 89] \nValue TransformerFactory.newInstance(...)."},"name":"XXE XSLT TRANSFORM FACTORY","properties":{"tags":["Scan"],"precision":"high"},"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"The use of TransformerFactory.newInstance(...) is vulnerable to XSLT External Entity attacks ."},"helpUri":"https://slscan.io?q=XXE_XSLT_TRANSFORM_FACTORY","shortDescription":{"text":"The use of TransformerFactory.newInstance(...) is vulnerable to XSLT External Entity attacks \nAt NoisyCricket.java:[lines 46-207] \nIn class org.owasp.benchmark.tools.NoisyCricket \nIn method org.owasp.benchmark.tools.NoisyCricket.main(String[]) \nAt NoisyCricket.java:[line 89] \nValue TransformerFactory.newInstance(...)."}},{"id":"HTTP_PARAMETER_POLLUTION","help":{"text":"Concatenating user-controlled input into a URL \nAt ServletTestCaseRequest.java:[lines 56-141] \nIn class org.owasp.benchmark.tools.ServletTestCaseRequest \nIn method org.owasp.benchmark.tools.ServletTestCaseRequest.createRequestInstance(String) \nAt ServletTestCaseRequest.java:[line 101] \nSink method org/apache/http/client/methods/HttpGet.(Ljava/lang/String;)V \nSink parameter 0 \nUnknown source org/owasp/benchmark/tools/ServletTestCaseRequest.createRequestInstance(Ljava/lang/String;)Lorg/apache/http/client/methods/HttpRequestBase; parameter 0 \nMethod usage not detected.","markdown":"Concatenating user-controlled input into a URL \nAt ServletTestCaseRequest.java:[lines 56-141] \nIn class org.owasp.benchmark.tools.ServletTestCaseRequest \nIn method org.owasp.benchmark.tools.ServletTestCaseRequest.createRequestInstance(String) \nAt ServletTestCaseRequest.java:[line 101] \nSink method org/apache/http/client/methods/HttpGet.(Ljava/lang/String;)V \nSink parameter 0 \nUnknown source org/owasp/benchmark/tools/ServletTestCaseRequest.createRequestInstance(Ljava/lang/String;)Lorg/apache/http/client/methods/HttpRequestBase; parameter 0 \nMethod usage not detected."},"name":"HTTP PARAMETER POLLUTION","properties":{"tags":["Scan"],"precision":"high"},"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"Concatenating user-controlled input into a URL ."},"helpUri":"https://slscan.io?q=HTTP_PARAMETER_POLLUTION","shortDescription":{"text":"Concatenating user-controlled input into a URL \nAt ServletTestCaseRequest.java:[lines 56-141] \nIn class org.owasp.benchmark.tools.ServletTestCaseRequest \nIn method org.owasp.benchmark.tools.ServletTestCaseRequest.createRequestInstance(String) \nAt ServletTestCaseRequest.java:[line 101] \nSink method org/apache/http/client/methods/HttpGet.(Ljava/lang/String;)V \nSink parameter 0 \nUnknown source org/owasp/benchmark/tools/ServletTestCaseRequest.createRequestInstance(Ljava/lang/String;)Lorg/apache/http/client/methods/HttpRequestBase; parameter 0 \nMethod usage not detected."}}],"version":"1.0.0-scan","fullName":"Class File Analyzer"}},"conversion":{"tool":{"driver":{"name":"@ShiftLeft/sast-scan"}},"invocation":{"arguments":["-jar","/opt/spotbugs/lib/spotbugs.jar","-textui","-include","/usr/local/src/lib/../spotbugs/include.xml","-exclude","/usr/local/src/lib/../spotbugs/exclude.xml","-noClassOk","-auxclasspathFromFile","/tmp/tmp4zco9gfm","-sourcepath","/app","-quiet","-medium","-xml:withMessages","-effort:max","-nested:false","-output","/app/reports/class-report.xml","/app"],"executionSuccessful":true,"commandLine":"-jar /opt/spotbugs/lib/spotbugs.jar -textui -include /usr/local/src/lib/../spotbugs/include.xml -exclude /usr/local/src/lib/../spotbugs/exclude.xml -noClassOk -auxclasspathFromFile /tmp/tmp4zco9gfm -sourcepath /app -quiet -medium -xml:withMessages -effort:max -nested:false -output /app/reports/class-report.xml /app","endTimeUtc":"1970-01-01T01:01:01Z","workingDirectory":{"uri":"file:///somepath"}}},"invocations":[{"executionSuccessful":true,"endTimeUtc":"1970-01-01T01:01:01Z","workingDirectory":{"uri":"file://somepath"}}],"properties":{"metrics":{"total":0,"critical":0,"high":0,"medium":0,"low":0}},"results":[{"message":{"markdown":"","text":"Cookie without the HttpOnly flag could be read by a malicious script in the browser \nAt BenchmarkTest00001.java:[lines 28-104] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00001 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00001.doGet(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00001.java:[line 36]."},"level":"error","locations":[{"physicalLocation":{"region":{"snippet":{"text":" javax.servlet.http.Cookie userCookie =\n"},"startLine":0},"artifactLocation":{"uri":"file:///somepath/src/main/java/org/owasp/benchmark/testcode/BenchmarkTest00001.java"},"contextRegion":{"snippet":{"text":" response.setContentType(\"text/html;charset=UTF-8\");\n javax.servlet.http.Cookie userCookie =\n"},"endLine":0,"startLine":0}}}],"properties":{"issue_confidence":"MEDIUM","issue_severity":"HIGH","issue_tags":{}},"baselineState":"new","partialFingerprints":{"scanPrimaryLocationHash":"0000000000000000","scanFileHash":"0000000000000000"},"ruleId":"HTTPONLY_COOKIE","ruleIndex":7},{"message":{"markdown":"","text":"This API (java/io/File.(Ljava/lang/String;)V) reads a file whose location might be specified by user input \nAt BenchmarkTest00002.java:[lines 28-104] \nIn class org.owasp.benchmark.testcode.BenchmarkTest00002 \nIn method org.owasp.benchmark.testcode.BenchmarkTest00002.doPost(HttpServletRequest, HttpServletResponse) \nAt BenchmarkTest00002.java:[line 71] \nSink method java/io/File.(Ljava/lang/String;)V \nSink parameter 0 \nTainted source javax/servlet/http/Cookie.getValue()Ljava/lang/String; \nTainted source java/net/URLDecoder.decode(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; \nUnknown source org/owasp/benchmark/helpers/Utils.TESTFILES_DIR \nAt BenchmarkTest00002.java:[line 60] \nAt BenchmarkTest00002.java:[line 70]."},"level":"error","locations":[{"physicalLocation":{"region":{"snippet":{"text":" fis = new java.io.FileInputStream(new java.io.File(fileName));\n"},"startLine":0},"artifactLocation":{"uri":"file:///somepath/src/main/java/org/owasp/benchmark/testcode/BenchmarkTest00002.java"},"contextRegion":{"snippet":{"text":" fileName = org.owasp.benchmark.helpers.Utils.TESTFILES_DIR + param;\n fis = new java.io.FileInputStream(new java.io.File(fileName));\n"},"endLine":0,"startLine":0}}}],"properties":{"issue_confidence":"MEDIUM","issue_severity":"CRITICAL","issue_tags":{}},"baselineState":"new","partialFingerprints":{"scanPrimaryLocationHash":"0000000000000000","scanFileHash":"0000000000000000"},"ruleId":"PATH_TRAVERSAL_IN","ruleIndex":4}],"automationDetails":{"description":{"text":"Static Analysis Security Test results using @ShiftLeft/sast-scan"},"guid":"00000000-0000-0000-0000-000000000000"},"versionControlProvenance":[{"branch":"sast-scripts","repositoryUri":"https://github.com/OWASP-Benchmark/BenchmarkJava","revisionId":"0000000000000000000000000000000000000000"}]} +{"tool":{"driver":{"name":"Java Source Analyzer","version":"1.0.0-scan","fullName":"Java Source Analyzer"}},"conversion":{"tool":{"driver":{"name":"@ShiftLeft/sast-scan"}},"invocation":{"arguments":["pmd","-no-cache","--failOnViolation","false","-language","java","-d","/app","-r","/app/reports/source-java-report.csv","-f","csv","-R","/usr/local/src/lib/../rules-pmd.xml"],"executionSuccessful":true,"commandLine":"pmd -no-cache --failOnViolation false -language java -d /app -r /app/reports/source-java-report.csv -f csv -R /usr/local/src/lib/../rules-pmd.xml","endTimeUtc":"1970-01-01T01:01:01Z","workingDirectory":{"uri":"file:///somepath"}}},"invocations":[{"executionSuccessful":true,"endTimeUtc":"1970-01-01T01:01:01Z","workingDirectory":{"uri":"file:///somepath"}}],"properties":{"metrics":{"total":0,"critical":0,"high":0,"medium":0,"low":0}},"results":[],"automationDetails":{"description":{"text":"Static Analysis Security Test results using @ShiftLeft/sast-scan"},"guid":"00000000-0000-0000-0000-000000000000"},"versionControlProvenance":[{"branch":"sast-scripts","repositoryUri":"https://github.com/OWASP-Benchmark/BenchmarkJava","revisionId":"0000000000000000000000000000000000000000"}]} diff --git a/plugin/src/test/resources/testfiles/Benchmark_1.2-sonar-Java-Plugin-v3.14-1234.xml b/plugin/src/test/resources/testfiles/Benchmark_1.2-sonar-Java-Plugin-v3.14-1234.xml new file mode 100644 index 00000000..3c19a5b0 --- /dev/null +++ b/plugin/src/test/resources/testfiles/Benchmark_1.2-sonar-Java-Plugin-v3.14-1234.xml @@ -0,0 +1,51 @@ +12345 + + Java + java + + + 1234 + OWASP Benchmark Project + OWASP Benchmark Project + ABC + 00000000-0000-0000-0000-000000000000 + org.owasp:benchmark + + + cwe + owasp-a1 + sans-top25-insecure + security + OPEN + 42min + 42 + CRITICAL + 9470 + 1970-01-01T01:01:01-0100 + 42 minutes + Make sure "args" is properly sanitized before use in this OS command. + org.owasp:benchmark + 1970-01-01T01:01:01-0100 + org.owasp:benchmark:src/main/java/org/owasp/benchmark/testcode/BenchmarkTest00001.java + squid:S2076 + 00000000-0000-0000-0000-000000000000 + + + cert + cwe + owasp-a6 + security + OPEN + 42min + 42 + CRITICAL + 11349 + 1970-01-01T01:01:01-0100 + 42 minutes + Use a cryptographically strong random number generator (RNG) like "java.security.SecureRandom" in place of this PRNG + org.owasp:benchmark + 1970-01-01T01:01:01-0100 + org.owasp:benchmark:src/main/java/org/owasp/benchmark/testcode/BenchmarkTest00002.java + squid:S2245 + 00000000-0000-0000-0000-000000000000 + diff --git a/plugin/src/test/resources/testfiles/Benchmark_1.2-sonarqube-v9.1.0.47736.json b/plugin/src/test/resources/testfiles/Benchmark_1.2-sonarqube-v9.1.0.47736.json new file mode 100644 index 00000000..01e74850 --- /dev/null +++ b/plugin/src/test/resources/testfiles/Benchmark_1.2-sonarqube-v9.1.0.47736.json @@ -0,0 +1,52 @@ +{ + "issues": [ + { + "key": "AXv-ikHUnNrc2VzNo8Sp", + "rule": "java:S5542", + "severity": "CRITICAL", + "component": "benchmark:src/main/java/org/owasp/benchmark/testcode/BenchmarkTest00001.java", + "project": "benchmark", + "line": 0, + "hash": "00000000000000000000000000000000", + "textRange": { + "startLine": 0, + "endLine": 0, + "startOffset": 0, + "endOffset": 0 + }, + "flows": [], + "status": "OPEN", + "message": "Use secure mode and padding scheme.", + "effort": "45min", + "debt": "45min", + "author": "someone@somewhere.com", + "tags": [ + "cwe", + "owasp-a3", + "owasp-a6", + "owasp-m5", + "privacy", + "sans-top25-porous" + ], + "creationDate": "1970-01-01T01:01:01+0000", + "updateDate": "1970-01-01T01:01:01+0000", + "type": "VULNERABILITY", + "scope": "MAIN" + } + ], + "hotspots": [ + { + "key": "AXv-ikHwnNrc2VzNo8T3", + "component": "benchmark:src/main/java/org/owasp/benchmark/testcode/BenchmarkTest00002.java", + "project": "benchmark", + "securityCategory": "sql-injection", + "vulnerabilityProbability": "HIGH", + "status": "TO_REVIEW", + "line": 0, + "message": "Make sure using a dynamically formatted SQL query is safe here.", + "author": "someone@somewhere.com", + "creationDate": "1970-01-01T01:01:01+0000", + "updateDate": "1970-01-01T01:01:01+0000" + } + ] +} diff --git a/plugin/src/test/resources/testfiles/Benchmark_1.2-spotbugs-v4.1.4-104.xml b/plugin/src/test/resources/testfiles/Benchmark_1.2-spotbugs-v4.1.4-104.xml new file mode 100644 index 00000000..0f77e049 --- /dev/null +++ b/plugin/src/test/resources/testfiles/Benchmark_1.2-spotbugs-v4.1.4-104.xml @@ -0,0 +1,87 @@ + + + + /somepath/Benchmark//target/classes + /root/.m2/repository/javax/javaee-api/7.0/javaee-api-7.0.jar + /root/.m2/repository/com/sun/mail/javax.mail/1.5.0/javax.mail-1.5.0.jar + /somepath/Benchmark//src/main/java + /somepath/Benchmark//target/generated-sources/annotations + /somepath/Benchmark//target + + + Nonconstant string passed to execute or addBatch method on an SQL statement + org.owasp.benchmark.testcode.BenchmarkTest00001.doPost(HttpServletRequest, HttpServletResponse) passes a nonconstant String to an execute or addBatch method on an SQL statement + + + At BenchmarkTest00001.java:[lines 30-71] + + In class org.owasp.benchmark.testcode.BenchmarkTest00001 + + + + In method org.owasp.benchmark.testcode.BenchmarkTest00001.doPost(HttpServletRequest, HttpServletResponse) + + + At BenchmarkTest00001.java:[line 60] + + + + Relative path traversal in servlet + Relative path traversal in org.owasp.benchmark.testcode.BenchmarkTest00002.doPost(HttpServletRequest, HttpServletResponse) + + + At BenchmarkTest00002.java:[lines 30-96] + + In class org.owasp.benchmark.testcode.BenchmarkTest00002 + + + + In method org.owasp.benchmark.testcode.BenchmarkTest00002.doPost(HttpServletRequest, HttpServletResponse) + + + + Called method new java.io.FileInputStream(String) + + + Parameter "BenchmarkTest00002" + + + Value generated at BenchmarkTest00002.java:[line 43] + + + Local variable named fileName + + + At BenchmarkTest00002.java:[line 74] + + + + Bad practice + + + Malicious code vulnerability + + + Performance + + + Correctness + + + Dodgy code + + + Security + + + Experimental + + + Multithreaded correctness + + + Internationalization + + + + diff --git a/plugin/src/test/resources/testfiles/Benchmark_1.2-visualcodegrepper-v2.2.0.xml b/plugin/src/test/resources/testfiles/Benchmark_1.2-visualcodegrepper-v2.2.0.xml new file mode 100644 index 00000000..2dda9dae --- /dev/null +++ b/plugin/src/test/resources/testfiles/Benchmark_1.2-visualcodegrepper-v2.2.0.xml @@ -0,0 +1,25 @@ + + + + 1 + Critical + Potential SQL Injection + Lorem Ipsum + C:\somepath\benchmark\src\main\java\org\owasp\benchmark\testcode\BenchmarkTest00001.java + 1 + someEvilCode() + False + LawnGreen + + + 2 + High + Potential XSS + Lorem Ipsum + C:\somepath\benchmark\src\main\java\org\owasp\benchmark\testcode\BenchmarkTest00002.java + 1 + someEvilCode() + False + LawnGreen + + diff --git a/plugin/src/test/resources/testfiles/Benchmark_1.2-w3af-v1.7.6.xml b/plugin/src/test/resources/testfiles/Benchmark_1.2-w3af-v1.7.6.xml new file mode 100644 index 00000000..57a06064 --- /dev/null +++ b/plugin/src/test/resources/testfiles/Benchmark_1.2-w3af-v1.7.6.xml @@ -0,0 +1,93 @@ + + + w3af - Web Application Attack and Audit Framework + Version: 1.7.6 + Revision: 27b1516a3f - 04 Apr 2017 20:45 + Branch: master + Local changes: Yes + Author: Andres Riancho and the w3af team. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Description + Long Description + Fix Guidance + 10 + + + + + + + + + GET https://localhost:8443/benchmark/xss-01/BenchmarkTest00001? + +

+ + + + HTTP/1.1 200 OK + +
+ + Body + + + + + + Description + Long Description + Fix Guidance + 10 + + + + + + + + + GET https://localhost:8443/benchmark/xss-01/BenchmarkTest00001? + +
+ + + + HTTP/1.1 200 OK + +
+ + Body + + + + + diff --git a/plugin/src/test/resources/testfiles/Benchmark_1.2-wapiti-v3.0.5.json b/plugin/src/test/resources/testfiles/Benchmark_1.2-wapiti-v3.0.5.json new file mode 100644 index 00000000..f63cc841 --- /dev/null +++ b/plugin/src/test/resources/testfiles/Benchmark_1.2-wapiti-v3.0.5.json @@ -0,0 +1,253 @@ +{ + "classifications": { + "Backup file": { + "desc": "It may be possible to find backup files of scripts on the webserver that the web-admin put here to save a previous version or backup files that are automatically generated by the software editor used (like for example Emacs). These copies may reveal interesting information like source code or credentials.", + "sol": "The webadmin must manually delete the backup files or remove it from the web root. He should also reconfigure its editor to deactivate automatic backups.", + "ref": { + "OWASP: Review Old Backup and Unreferenced Files for Sensitive Information": "https://owasp.org/www-project-web-security-testing-guide/stable/4-Web_Application_Security_Testing/02-Configuration_and_Deployment_Management_Testing/04-Review_Old_Backup_and_Unreferenced_Files_for_Sensitive_Information.html", + "CWE-530: Exposure of Backup File to an Unauthorized Control Sphere": "https://cwe.mitre.org/data/definitions/530.html" + } + }, + "Weak credentials": { + "desc": "The web application is using either default credentials or weak passwords that can be found in well-known passwords lists.", + "sol": "Do not ship or deploy with any default credentials, particularly for admin users. Implement weak-password checks, such as testing new or changed passwords against a list of the top 10000 worst passwords.", + "ref": { + "CWE-798: Use of Hard-coded Credentials": "https://cwe.mitre.org/data/definitions/798.html", + "CWE-521: Weak Password Requirements": "https://cwe.mitre.org/data/definitions/521.html" + } + }, + "CRLF Injection": { + "desc": "The term CRLF refers to Carriage Return (ASCII 13, \\r) Line Feed (ASCII 10, \\n). A CRLF Injection attack occurs when a user manages to submit a CRLF into an application. This is most commonly done by modifying an HTTP parameter or URL.", + "sol": "Check the submitted parameters and do not allow CRLF to be injected when it is not expected.", + "ref": { + "OWASP: CRLF Injection": "https://owasp.org/www-community/vulnerabilities/CRLF_Injection", + "Acunetix: What Are CRLF Injection Attacks": "https://www.acunetix.com/websitesecurity/crlf-injection/", + "CWE-93: Improper Neutralization of CRLF Sequences ('CRLF Injection')": "https://cwe.mitre.org/data/definitions/93.html" + } + }, + "Content Security Policy Configuration": { + "desc": "Content Security Policy (CSP) is an added layer of security that helps to detect and mitigate certain types of attacks, including Cross Site Scripting (XSS) and data injection attacks.", + "sol": "Configuring Content Security Policy involves adding the Content-Security-Policy HTTP header to a web page and giving it values to control what resources the user agent is allowed to load for that page.", + "ref": { + "Mozilla: Content Security Policy (CSP)": "https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP", + "OWASP: Content Security Policy Cheat Sheet": "https://cheatsheetseries.owasp.org/cheatsheets/Content_Security_Policy_Cheat_Sheet.html", + "OWASP: How to do Content Security Policy (PDF)": "https://owasp.org/www-pdf-archive/2019-02-22_-_How_do_I_Content_Security_Policy_-_Print.pdf" + } + }, + "Cross Site Request Forgery": { + "desc": "Cross-Site Request Forgery (CSRF) is an attack that forces an end user to execute unwanted actions on a web application in which they're currently authenticated.", + "sol": "Check if your framework has built-in CSRF protection and use it. If framework does not have built-in CSRF protection add CSRF tokens to all state changing requests (requests that cause actions on the site) and validate them on backend.", + "ref": { + "OWASP: Testing for Cross Site Request Forgery": "https://owasp.org/www-project-web-security-testing-guide/stable/4-Web_Application_Security_Testing/06-Session_Management_Testing/05-Testing_for_Cross_Site_Request_Forgery.html", + "OWASP: Cross-Site Request Forgery Prevention Cheat Sheet": "https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html", + "CWE-352: Cross-Site Request Forgery (CSRF)": "https://cwe.mitre.org/data/definitions/352.html" + } + }, + "Potentially dangerous file": { + "desc": "A file with potential vulnerabilities has been found on the website.", + "sol": "Make sure the script is up-to-date and restrict access to it if possible.", + "ref": { + "Mitre: Search details of a CVE": "https://cve.mitre.org/cve/search_cve_list.html" + } + }, + "Command execution": { + "desc": "This attack consists in executing system commands on the server. The attacker tries to inject this commands in the request parameters.", + "sol": "Prefer working without user input when using file system calls.", + "ref": { + "OWASP: Command Injection": "https://owasp.org/www-community/attacks/Command_Injection", + "CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')": "https://cwe.mitre.org/data/definitions/78.html" + } + }, + "Path Traversal": { + "desc": "This attack is known as Path or Directory Traversal. Its aim is the access to files and directories that are stored outside the web root folder. The attacker tries to explore the directories stored in the web server. The attacker uses some techniques, for instance, the manipulation of variables that reference files with 'dot-dot-slash (../)' sequences and its variations to move up to root directory to navigate through the file system.", + "sol": "Prefer working without user input when using file system calls. Use indexes rather than actual portions of file names when templating or using language files (eg: value 5 from the user submission = Czechoslovakian, rather than expecting the user to return 'Czechoslovakian'). Ensure the user cannot supply all parts of the path - surround it with your path code. Validate the user's input by only accepting known good - do not sanitize the data. Use chrooted jails and code access policies to restrict where the files can be obtained or saved to.", + "ref": { + "OWASP: Path Traversal": "https://owasp.org/www-community/attacks/Path_Traversal", + "Acunetix: What is a Directory Traversal attack?": "https://www.acunetix.com/websitesecurity/directory-traversal/", + "CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')": "https://cwe.mitre.org/data/definitions/22.html" + } + }, + "Fingerprint web application framework": { + "desc": "The version of a web application framework can be identified due to the presence of its specific fingerprints.", + "sol": "This is only for informational purposes.", + "ref": { + "OWASP: Fingerprint Web Application Framework": "https://owasp.org/www-project-web-security-testing-guide/stable/4-Web_Application_Security_Testing/01-Information_Gathering/08-Fingerprint_Web_Application_Framework.html" + } + }, + "Fingerprint web server": { + "desc": "The version of a web server can be identified due to the presence of its specific fingerprints.", + "sol": "This is only for informational purposes.", + "ref": { + "OWASP: Fingerprint Web Server": "https://owasp.org/www-project-web-security-testing-guide/stable/4-Web_Application_Security_Testing/01-Information_Gathering/02-Fingerprint_Web_Server.html" + } + }, + "Htaccess Bypass": { + "desc": "Htaccess files are used to restrict access to some files or HTTP method. In some case it may be possible to bypass this restriction and access the files.", + "sol": "Make sure every HTTP method is forbidden if the credentials are bad.", + "ref": { + "A common Apache .htaccess misconfiguration": "http://blog.teusink.net/2009/07/common-apache-htaccess-misconfiguration.html", + "CWE-538: Insertion of Sensitive Information into Externally-Accessible File or Directory": "https://cwe.mitre.org/data/definitions/538.html" + } + }, + "HTTP Secure Headers": { + "desc": "HTTP security headers tell the browser how to behave when handling the website's content.", + "sol": "Use the recommendations for hardening your HTTP Security Headers.", + "ref": { + "Netsparker: HTTP Security Headers: An Easy Way to Harden Your Web Applications": "https://www.netsparker.com/blog/web-security/http-security-headers/", + "KeyCDN: Hardening Your HTTP Security Headers": "https://www.keycdn.com/blog/http-security-headers", + "OWASP: HTTP SECURITY HEADERS (Protection For Browsers) (PDF)": "https://owasp.org/www-chapter-ghana/assets/slides/HTTP_Header_Security.pdf" + } + }, + "HttpOnly Flag cookie": { + "desc": "HttpOnly is an additional flag included in a Set-Cookie HTTP response header. Using the HttpOnly flag when generating a cookie helps mitigate the risk of client side script accessing the protected cookie (if the browser supports it).", + "sol": "While creation of the cookie, make sure to set the HttpOnly Flag to True.", + "ref": { + "OWASP: Testing for Cookies Attributes": "https://owasp.org/www-project-web-security-testing-guide/stable/4-Web_Application_Security_Testing/06-Session_Management_Testing/02-Testing_for_Cookies_Attributes.html", + "OWASP: HttpOnly": "https://owasp.org/www-community/HttpOnly" + } + }, + "Open Redirect": { + "desc": "Unvalidated redirects and forwards are possible when a web application accepts untrusted input that could cause the web application to redirect the request to a URL contained within untrusted input. By modifying untrusted URL input to a malicious site, an attacker may successfully launch a phishing scam and steal user credentials.", + "sol": "Force all redirects to first go through a page notifying users that they are going off of your site, and have them click a link to confirm.", + "ref": { + "Unvalidated Redirects and Forwards Cheat Sheet": "https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html", + "Acunetix: What Are Open Redirects?": "https://www.acunetix.com/blog/web-security-zone/what-are-open-redirects/", + "CWE-601: URL Redirection to Untrusted Site ('Open Redirect')": "https://cwe.mitre.org/data/definitions/601.html" + } + }, + "Secure Flag cookie": { + "desc": "The secure flag is an option that can be set by the application server when sending a new cookie to the user within an HTTP Response. The purpose of the secure flag is to prevent cookies from being observed by unauthorized parties due to the transmission of a the cookie in clear text.", + "sol": "When generating the cookie, make sure to set the Secure Flag to True.", + "ref": { + "OWASP: Testing for Cookies Attributes": "https://owasp.org/www-project-web-security-testing-guide/stable/4-Web_Application_Security_Testing/06-Session_Management_Testing/02-Testing_for_Cookies_Attributes.html", + "OWASP: Secure Cookie Attribute": "https://owasp.org/www-community/controls/SecureCookieAttribute" + } + }, + "SQL Injection": { + "desc": "SQL injection vulnerabilities allow an attacker to alter the queries executed on the backend database. An attacker may then be able to extract or modify information stored in the database or even escalate his privileges on the system.", + "sol": "To protect against SQL injection, user input must not directly be embedded in SQL statements. Instead, user input must be escaped or filtered or parameterized statements must be used.", + "ref": { + "OWASP: SQL Injection": "https://owasp.org/www-community/attacks/SQL_Injection", + "Wikipedia: SQL injection": "https://en.wikipedia.org/wiki/SQL_injection", + "CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')": "https://cwe.mitre.org/data/definitions/89.html" + } + }, + "Server Side Request Forgery": { + "desc": "The target application may have functionality for importing data from a URL, publishing data to a URL or otherwise reading data from a URL that can be tampered with.", + "sol": "Every URI received by the web application should be checked, especially scheme and hostname. A whitelist should be used.", + "ref": { + "OWASP: Server Side Request Forgery": "https://owasp.org/www-community/attacks/Server_Side_Request_Forgery", + "Acunetix: What is Server Side Request Forgery (SSRF)?": "https://www.acunetix.com/blog/articles/server-side-request-forgery-vulnerability/", + "What is the Server Side Request Forgery Vulnerability & How to Prevent It?": "https://www.netsparker.com/blog/web-security/server-side-request-forgery-vulnerability-ssrf/", + "CWE-918: Server-Side Request Forgery (SSRF)": "https://cwe.mitre.org/data/definitions/918.html" + } + }, + "Blind SQL Injection": { + "desc": "Blind SQL injection is a technique that exploits a vulnerability occurring in the database of an application. This kind of vulnerability is harder to detect than basic SQL injections because no error message will be displayed on the webpage.", + "sol": "To protect against SQL injection, user input must not directly be embedded in SQL statements. Instead, user input must be escaped or filtered or parameterized statements must be used.", + "ref": { + "OWASP: Blind SQL Injection": "https://owasp.org/www-community/attacks/Blind_SQL_Injection", + "Wikipedia: SQL injection": "https://en.wikipedia.org/wiki/SQL_injection", + "CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')": "https://cwe.mitre.org/data/definitions/89.html" + } + }, + "Cross Site Scripting": { + "desc": "Cross-site scripting (XSS) is a type of computer security vulnerability typically found in web applications which allow code injection by malicious web users into the web pages viewed by other users. Examples of such code include HTML code and client-side scripts.", + "sol": "The best way to protect a web application from XSS attacks is ensure that the application performs validation of all headers, cookies, query strings, form fields, and hidden fields. Encoding user supplied output in the server side can also defeat XSS vulnerabilities by preventing inserted scripts from being transmitted to users in an executable form. Applications can gain significant protection from javascript based attacks by converting the following characters in all generated output to the appropriate HTML entity encoding:<, >, &, ', (, ), #, %, ; , +, -", + "ref": { + "OWASP: Cross Site Scripting (XSS)": "https://owasp.org/www-community/attacks/xss/", + "Wikipedia: Cross-site scripting": "https://en.wikipedia.org/wiki/Cross-site_scripting", + "CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')": "https://cwe.mitre.org/data/definitions/79.html" + } + }, + "XML External Entity": { + "desc": "An XML External Entity attack is a type of attack against an application that parses XML input. This attack occurs when XML input containing a reference to an external entity is processed by a weakly configured XML parser. This attack may lead to the disclosure of confidential data, denial of service, server side request forgery, port scanning from the perspective of the machine where the parser is located, and other system impacts.", + "sol": "The safest way to prevent XXE is always to disable DTDs (External Entities) completely.", + "ref": { + "OWASP: XML External Entity (XXE) Processing": "https://owasp.org/www-community/vulnerabilities/XML_External_Entity_(XXE)_Processing", + "PortSwigger: What is XML external entity injection?": "https://portswigger.net/web-security/xxe", + "CWE-611: Improper Restriction of XML External Entity Reference": "https://cwe.mitre.org/data/definitions/611.html", + "OWASP: XML External Entity Prevention Cheat Sheet": "https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html" + } + }, + "Internal Server Error": { + "desc": "An error occurred on the server's side, preventing it to process the request. It may be the sign of a vulnerability.", + "sol": "More information about the error should be found in the server logs.", + "ref": { + "Wikipedia: List of 5xx HTTP status codes": "https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#5xx_Server_Error", + "OWASP: Improper Error Handling": "https://owasp.org/www-community/Improper_Error_Handling" + } + }, + "Resource consumption": { + "desc": "It took an abnormal time to the server to respond to a query. An attacker might leverage this kind of weakness to overload the server.", + "sol": "The involved script is maybe using the server resources (CPU, memory, network, file access...) in a non-efficient way.", + "ref": { + "CWE-405: Asymmetric Resource Consumption (Amplification)": "https://cwe.mitre.org/data/definitions/405.html", + "CWE-400: Uncontrolled Resource Consumption": "https://cwe.mitre.org/data/definitions/400.html" + } + }, + "Fingerprint web technology": { + "desc": "The use of a web technology can be deducted due to the presence of its specific fingerprints.", + "sol": "This is only for informational purposes.", + "ref": { + "OWASP: Fingerprint Web Server": "https://owasp.org/www-project-web-security-testing-guide/stable/4-Web_Application_Security_Testing/01-Information_Gathering/02-Fingerprint_Web_Server.html", + "OWASP: Fingerprint Web Application Framework": "https://owasp.org/www-project-web-security-testing-guide/stable/4-Web_Application_Security_Testing/01-Information_Gathering/08-Fingerprint_Web_Application_Framework.html" + } + } + }, + "vulnerabilities": { + "Backup file": [], + "Weak credentials": [], + "CRLF Injection": [], + "Content Security Policy Configuration": [], + "Cross Site Request Forgery": [], + "Potentially dangerous file": [], + "Command execution": [ + { + "method": "GET", + "path": "/benchmark/cmdi-00/BenchmarkTest00001", + "info": "Blind command execution via injection in the parameter BenchmarkTest00001", + "level": 4, + "parameter": "BenchmarkTest00001", + "http_request": "GET /benchmark/cmdi-00/BenchmarkTest00001?username=alice&password=Letm3in_&BenchmarkTest00001=a%60sleep%2060%60 HTTP/1.1\nHost: localhost:8443\nReferer: https://localhost:8443/benchmark/cmdi-00/BenchmarkTest00001.html?BenchmarkTest00001=SafeText", + "curl_command": "curl \"https://localhost:8443/benchmark/cmdi-00/BenchmarkTest00001?username=alice&password=Letm3in_&BenchmarkTest00001=a%60sleep%2060%60\" -e \"https://localhost:8443/benchmark/cmdi-00/BenchmarkTest00001.html?BenchmarkTest00001=SafeText\"" + } + ], + "Path Traversal": [ + { + "method": "GET", + "path": "/benchmark/pathtraver-00/BenchmarkTest00002", + "info": "Unix local file disclosure vulnerability via injection in the parameter BenchmarkTest00002", + "level": 4, + "parameter": "BenchmarkTest00002", + "http_request": "GET /benchmark/pathtraver-00/BenchmarkTest00002?username=alice&password=Letm3in_&BenchmarkTest00002=..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fetc%2Fservices HTTP/1.1\nHost: localhost:8443\nReferer: https://localhost:8443/benchmark/pathtraver-00/BenchmarkTest00002.html?BenchmarkTest00002=SafeText", + "curl_command": "curl \"https://localhost:8443/benchmark/pathtraver-00/BenchmarkTest00002?username=alice&password=Letm3in_&BenchmarkTest00002=..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fetc%2Fservices\" -e \"https://localhost:8443/benchmark/pathtraver-00/BenchmarkTest00002.html?BenchmarkTest00002=SafeText\"" + } + ], + "Fingerprint web application framework": [], + "Fingerprint web server": [], + "Htaccess Bypass": [], + "HTTP Secure Headers": [], + "HttpOnly Flag cookie": [], + "Open Redirect": [], + "Secure Flag cookie": [], + "SQL Injection": [], + "Server Side Request Forgery": [], + "Blind SQL Injection": [], + "Cross Site Scripting": [], + "XML External Entity": [] + }, + "anomalies": { + "Internal Server Error": [], + "Resource consumption": [] + }, + "additionals": { + "Fingerprint web technology": [] + }, + "infos": { + "target": "https://localhost:8443/benchmark/", + "date": "Thu, 01 Jan 1970 01:01:01 +0000", + "version": "Wapiti 3.0.5", + "scope": "folder" + } +} diff --git a/plugin/src/test/resources/testfiles/Benchmark_1.2_HCL-IAST.hcl b/plugin/src/test/resources/testfiles/Benchmark_1.2_HCL-IAST.hcl new file mode 100644 index 00000000..c35c29c0 --- /dev/null +++ b/plugin/src/test/resources/testfiles/Benchmark_1.2_HCL-IAST.hcl @@ -0,0 +1,5 @@ +01:23:45.666 [main] INFO lorem.ipsum:dolor - doing the magic +01:23:45.777 [https-jsse-nio-127.0.0.1-8443-exec-3] DEBUG utils.TaintTracker:enterAction - [checking URL: /benchmark/pathtraver-01/BenchmarkTest00001 queryString: ] +01:23:45.888 [Distributor Thread] DEBUG utils.distributor.Distributor:writeVulnerabilityToFile - {"agent-version":"some-agent","issue-group":[{"id":"-000000000","issue-type":{"ref":"PathTraversal"},"variant-group":[{"id":"1","request":{"uri":"/benchmark/pathtraver-01/BenchmarkTest00001","method":"POST","queryString":""}}]}]} +01:23:45.999[https-jsse-nio-127.0.0.1-8443-exec-6] DEBUG utils.TaintTracker:enterAction - [checking URL: /benchmark/sqli-01/BenchmarkTest00002 queryString: ] +01:23:46.000 [Distributor Thread] DEBUG utils.distributor.Distributor:writeVulnerabilityToFile - {"agent-version":"some-agent","issue-group":[{"id":"-000000000","issue-type":{"ref":"Injection.SQL"},"variant-group":[{"id":"1","request":{"uri":"/benchmark/sqli-01/BenchmarkTest00002","method":"POST","queryString":""}}]}]} diff --git a/plugin/src/test/resources/testfiles/README.md b/plugin/src/test/resources/testfiles/README.md new file mode 100644 index 00000000..e3199d17 --- /dev/null +++ b/plugin/src/test/resources/testfiles/README.md @@ -0,0 +1,8 @@ +# Testfiles + +This directory only contains fake result files to check if the corresponding reader: + +- is capable of reading the result file structure +- is the only reader that reports itself as matching + +Do NOT paste real data here (especially for commercial tools).