diff --git a/README.md b/README.md index 9290f330..6cffc441 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Public documentation for the Benchmark is on the OWASP site at expectedCWE = new HashSet(); + Set expectedCWE = new HashSet(); for (int i : expectedResults.keySet()) { List list = expectedResults.get(i); for (TestCaseResult t : list) { @@ -733,7 +733,7 @@ private static void printExtraCWE( } } - Set actualCWE = new HashSet(); + Set actualCWE = new HashSet(); for (int i : actualResults.keySet()) { List list = actualResults.get(i); if (list != null) { @@ -743,8 +743,8 @@ private static void printExtraCWE( } } - Set extras = difference(actualCWE, expectedCWE); - for (int cwe : extras) { + Set extras = difference(actualCWE, expectedCWE); + for (CweNumber cwe : extras) { System.out.println("Extra: " + cwe); } } @@ -958,20 +958,21 @@ private static boolean compare(TestCaseResult exp, List actList, // System.out.println( " Evidence: " + act.getCWE() + " " + act.getEvidence() + "[" + // act.getConfidence() + "]"); - int actualCWE = act.getCWE(); - int expectedCWE = exp.getCWE(); + CweNumber actualCWE = act.getCWE(); + CweNumber expectedCWE = exp.getCWE(); - boolean match = actualCWE == expectedCWE; + boolean match = actualCWE.equals(expectedCWE); // Special case: many tools report CWE 89 (sqli) for Hibernate Injection (hqli) rather // than actual CWE of 564 So we accept either - if (!match && (expectedCWE == 564)) { - match = (actualCWE == 89); + if (!match && (CweNumber.HIBERNATE_INJECTION.equals(expectedCWE))) { + match = CweNumber.SQL_INJECTION.equals(actualCWE); } // special hack since IBM/Veracode don't distinguish different kinds of weak algorithm if (tool.startsWith("AppScan") || tool.startsWith("Vera")) { - if (expectedCWE == 328 && actualCWE == 327) { + if (CweNumber.WEAK_HASH_ALGO.equals(expectedCWE) + && CweNumber.WEAK_CRYPTO_ALGO.equals(actualCWE)) { match = true; } } @@ -1040,7 +1041,7 @@ private static TestSuiteResults readExpectedResults(File file) { tcr.setTestCaseName(parts[0]); tcr.setCategory(parts[1]); tcr.setReal(Boolean.parseBoolean(parts[2])); - tcr.setCWE(Integer.parseInt(parts[3])); + tcr.setCWE(CweNumber.lookup(Integer.parseInt(parts[3]))); String tcname = parts[0].substring(TESTCASENAME.length()); tcr.setNumber(Integer.parseInt(tcname)); diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/CweNumber.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/CweNumber.java index 03ff0a63..a3e98800 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/CweNumber.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/CweNumber.java @@ -17,149 +17,545 @@ */ package org.owasp.benchmarkutils.score; -public class CweNumber { +public enum CweNumber { /** To be used when the CWE reported is one we don't care about in any test suite */ - public static int DONTCARE = 0000; + DONTCARE(0), + + /** CWE-16: CWE CATEGORY: Configuration */ + CATEGORY_CONFIGURATION(16), + + /** CWE-20: Improper Input Validation */ + IMPROPER_INPUT_VALIDAITON(20), /** CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal') */ - public static int PATH_TRAVERSAL = 22; + PATH_TRAVERSAL(22), + + /** CWE-73: External Control of File Name or Path */ + EXTERNAL_FILE_OR_PATH_CONTROL(73), + + /** + * CWE-74: Improper Neutralization of Special Elements in Output Used by a Downstream Component + * ('Injection') + */ + GENERAL_INJECTION(74), + + /** + * CWE-77: Improper Neutralization of Special Elements used in a Command ('Command Injection') + */ + COMMAND_INJECTION(77), /** * CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command * Injection') */ - public static int COMMAND_INJECTION = 78; + OS_COMMAND_INJECTION(78), /** * CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') */ - public static int XSS = 79; + XSS(79), + + /** CWE-83: Improper Neutralization of Script in Attributes in a Web Page */ + IMPROPER_NEUTRALIZATION_OF_ATTRIBUTES(83), + + /** + * CWE-88: Improper Neutralization of Argument Delimiters in a Command ('Argument Injection') + */ + ARGUMENT_INJECTION(88), /** * CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection') */ - public static int SQL_INJECTION = 89; + SQL_INJECTION(89), /** * CWE-90: Improper Neutralization of Special Elements used in an LDAP Query ('LDAP Injection') */ - public static int LDAP_INJECTION = 90; + LDAP_INJECTION(90), + + /** CWE-91: XML Injection (aka Blind XPath Injection) */ + BLIND_XPATH_INJECTION(91), + + /** CWE-93: Improper Neutralization of CRLF Sequences ('CRLF Injection') */ + CRLF_INJECTION(93), + + /** + * CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code ('Eval + * Injection') + */ + EVAL_INJECTION(95), + + /** CWE-99: Improper Control of Resource Identifiers ('Resource Injection') */ + RESOURCE_INJECTION(99), + + /** CWE-112: Missing XML Validation */ + MISSING_XML_VALIDATION(112), /** * CWE-113: Improper Neutralization of CRLF Sequences in HTTP Headers ('HTTP Response * Splitting') */ - public static int HTTP_RESPONSE_SPLITTING = 113; + HTTP_RESPONSE_SPLITTING(113), + + /** CWE-117: Improper Output Neutralization for Logs */ + MISSING_LOG_OUTPUT_NEUTRALIZATION(117), + + /** CWE-120: Buffer Copy without Checking Size of Input ('Classic Buffer Overflow') */ + CLASSIC_BUFFER_OVERFLOW(120), /** CWE-134: Use of Externally-Controlled Format String */ - public static int EXTERNALLY_CONTROLLED_STRING = 134; + EXTERNALLY_CONTROLLED_STRING(134), + + /** CWE-180: Incorrect Behavior Order: Validate Before Canonicalize */ + INCORRECT_BEHAVIOUR_ORDER(180), + + /** CWE-182: Collapse of Data into Unsafe Value */ + COLLAPSE_DATA_IN_UNSAFE_VALUE(182), + + /** CWE-190: Integer Overflow or Wraparound */ + INTEGER_OVERFLOW_WRAPAROUND(190), + + /** CWE-200: Exposure of Sensitive Information to an Unauthorized Actor */ + EXPOSURE_SENSITIVE_TO_UNAUTHORIZED_USER(200), + + /** CWE-205: Observable Behavioral Discrepancy */ + OBSERVABLE_BEHAVIORAL_DISCREPANCY(205), + + /** CWE-209: Generation of Error Message Containing Sensitive Information */ + ERROR_MESSAGE_WITH_SENSITIVE_INFO(209), + + /** CWE-215: Insertion of Sensitive Information Into Debugging Code */ + SENSITIVE_INFO_IN_DEBUG_MODE(215), + + /** CWE-235: Improper Handling of Extra Parameters */ + IMPROPER_HANDLING_OF_PARAMETERS(235), + + /** CWE-244: Improper Clearing of Heap Memory Before Release ('Heap Inspection') */ + HEAP_INSPECTION(244), + + /** CWE-248: Uncaught Exception */ + UNCAUGHT_EXCEPTION(248), + + /** CWE-250: Execution with Unnecessary Privileges */ + TOO_PRIVILIGED_EXECUTION(250), + + /** CWE-252: Unchecked Return Value */ + UNCHECKED_RETURN_VALUE(252), + + /** CWE-259: Use of Hard-coded Password */ + HARDCODED_PASSWORD(259), /** CWE-284: Improper Access Control */ - public static int IMPROPER_ACCESS_CONTROL = 284; + IMPROPER_ACCESS_CONTROL(284), + + /** CWE-285: Improper Authorization */ + IMPROPER_AUTHORIZATION(285), + + /** CWE-293: Using Referer Field for Authentication */ + REFERER_FIELD_IN_AUTHENTICATION(293), + + /** CWE-295: Improper Certificate Validation */ + IMPROPER_CERTIFICATE_VALIDATION(295), + + /** CWE-311: Missing Encryption of Sensitive Data */ + UNENCRYPTED_SENSITIVE_DATA(311), + + /** CWE-315: Cleartext Storage of Sensitive Information in a Cookie */ + UNENCRYPTED_SENSITIVE_INFO_STORED_IN_COOKIE(315), + + /** CWE-319: Cleartext Transmission of Sensitive Information */ + CLEARTEXT_TRANSMISSION_OF_SENSITIVE_INFO(319), + + /** CWE-320: CWE CATEGORY: Key Management Errors */ + CATEGORY_KEY_MANAGEMENT_ERROR(320), + + /** CWE-325: Missing Cryptographic Step */ + MISSING_CRYPTOGRAPHIC_STEP(325), /** CWE-327: Use of a Broken or Risky Cryptographic Algorithm */ - public static int WEAK_CRYPTO_ALGO = 327; + WEAK_CRYPTO_ALGO(327), /** CWE-328: Use of Weak Hash */ - public static int WEAK_HASH_ALGO = 328; + WEAK_HASH_ALGO(328), /** CWE-329: Generation of Predictable IV with CBC Mode */ - public static int STATIC_CRYPTO_INIT = 329; + STATIC_CRYPTO_INIT(329), /** CWE-330: Use of Insufficiently Random Values */ - public static int WEAK_RANDOM = 330; + WEAK_RANDOM(330), + + /** CWE-332: Insufficient Entropy in PRNG */ + INSUFFICIENT_ENTRUPY_IN_PNRG(332), + + /** CWE-345: Insufficient Verification of Data Authenticity */ + INSUFFICIENT_DATA_AUTHENTICITY_VERIFICATION(345), + + /** CWE-346: Origin Validation Error */ + ORIGIN_VALIDATION_ERROR(346), /** CWE-352: Cross-Site Request Forgery (CSRF) */ - public static int CSRF = 352; + CSRF(352), + + /** CWE-353: Missing Support for Integrity Check */ + MISSING_SUPPORT_FOR_INTEGRITY_CHECK(353), + + /** CWE-359: Exposure of Private Personal Information to an Unauthorized Actor */ + EXPOSURE_PRIVATE_TO_UNAUTHORIZED_USER(359), + + /** + * CWE-362: Concurrent Execution using Shared Resource with Improper Synchronization ('Race + * Condition') + */ + RACE_CONDITION(362), + + /** CWE-369: Divide By Zero */ + DIVISION_BY_ZERO(369), + + /** CWE-374: Passing Mutable Objects to an Untrusted Method */ + PASS_MUTABLE_OBJECT_TO_UNTRUSTED_MODULE(374), + + /** CWE-379: Creation of Temporary File in Directory with Insecure Permissions */ + TEMPORARY_FILE_WITH_INSECURE_PERMISSIONS(379), /** CWE-382: J2EE Bad Practices: Use of System.exit() */ - public static int SYSTEM_EXIT = 382; + SYSTEM_EXIT(382), + + /** CWE-390: Detection of Error Condition Without Action */ + DETECTING_ERROR_WITHOUT_ACTION(390), + + /** CWE-391: Unchecked Error Condition */ + UNCHECKED_ERROR_CONDITION(391), /** CWE-395: Use of NullPointerException Catch to Detect NULL Pointer Dereference */ - public static int CATCHING_NULL_POINTER_EXCEPTION = 395; + CATCHING_NULL_POINTER_EXCEPTION(395), /** CWE-396: Declaration of Catch for Generic Exception */ - public static int CATCH_GENERIC_EXCEPTION = 396; + CATCH_GENERIC_EXCEPTION(396), /** CWE-397: Declaration of Throws for Generic Exception */ - public static int THROW_GENERIC_EXCEPTION = 397; + THROW_GENERIC_EXCEPTION(397), + + /** CWE-398: CWE CATEGORY: 7PK - Code Quality */ + CATEGORY_CODE_QUALITY(398), + + /** CWE-400: Uncontrolled Resource Consumption */ + UNCONTROLLED_RESOURCE_CONSUMPTION(400), + + /** CWE-404: Improper Resource Shutdown or Release */ + UNRELEASED_RESOURCE(404), + + /** CWE-434: Unrestricted Upload of File with Dangerous Type */ + UNRESTRICTED_FILE_UPLOAD(434), + + /** CWE-436: Interpretation Conflict */ + INTERPRETATION_CONFLICT(436), + + /** CWE-440: Expected Behavior Violation */ + EXPECTED_BEHAVIOUR_VIOLATION(440), + + /** CWE-451: User Interface (UI) Misrepresentation of Critical Information */ + MISREPRESENTATION_OF_CRITICAL_INFO(451), + + /** CWE-459: Incomplete Cleanup */ + INCOMPLETE_CLEANUP(459), + + /** + * CWE-470: Use of Externally-Controlled Input to Select Classes or Code ('Unsafe Reflection') + */ + UNSAFE_REFLECTION(470), + + /** CWE-472: External Control of Assumed-Immutable Web Parameter */ + EXTERNAL_CONTROL_OF_WEB_PARAM(472), + + /** CWE-474: Use of Function with Inconsistent Implementations */ + FUNCTION_WITH_INCONSISTENT_IMPLEMENTATION(474), + + /** CWE-476: NULL Pointer Dereference */ + NULL_POINTER_DEREFERENCE(476), + + /** CWE-477: Use of Obsolete Function */ + OBSOLETE_FUNCTION_USAGE(477), /** CWE-478: Missing Default Case in Switch Statement */ - public static int MISSING_DEFAULT_CASE = 478; + MISSING_DEFAULT_CASE(478), + + /** CWE-482: Comparing instead of Assigning */ + COMPARING_INSTEAD_OF_ASSIGNING(482), /** CWE-483: Incorrect Block Delimitation */ - public static int INCORRECT_BLOCK_DELIMITATION = 483; + INCORRECT_BLOCK_DELIMITATION(483), /** CWE-484: Omitted Break Statement in Switch */ - public static int OMITTED_BREAK = 484; + OMITTED_BREAK(484), + + /** CWE-486: Comparison of Classes by Name */ + COMPARISON_BY_CLASS_NAME(486), + + /** CWE-489: Active Debug Code */ + ACTIVE_DEBUG_CODE(489), /** CWE-493: Critical Public Variable Without Final Modifier */ - public static int PUBLIC_VAR_WITHOUT_FINAL = 493; + PUBLIC_VAR_WITHOUT_FINAL(493), + + /** CWE-494: Download of Code Without Integrity Check */ + MISSING_INTEGRITY_CHECK_FOR_DOWNLOADED_CODE(494), + + /** CWE-497: Exposure of Sensitive System Information to an Unauthorized Control Sphere */ + EXPOSE_SYSTEM_INFO_TO_UNAUTHORIZED_CONTROL(497), + + /** CWE-499: Serializable Class Containing Sensitive Data */ + SERIALIZABLE_CLASS_WITH_SENSITIVE_DATA(499), /** CWE-500: Public Static Field Not Marked Final */ - public static int PUBLIC_STATIC_NOT_FINAL = 500; + PUBLIC_STATIC_NOT_FINAL(500), /** CWE-501: Trust Boundary Violation */ - public static int TRUST_BOUNDARY_VIOLATION = 501; + TRUST_BOUNDARY_VIOLATION(501), /** CWE-502: Deserialization of Untrusted Data */ - public static int INSECURE_DESERIALIZATION = 502; + INSECURE_DESERIALIZATION(502), + + /** CWE-521: Weak Password Requirements */ + WEAK_PASSWORD_REQUIREMENTS(521), + + /** CWE-522: Insufficiently Protected Credentials */ + INSUFFICIENTLY_RPOTECTED_CREDENTIALS(522), /** CWE-523: Unprotected Transport of Credentials */ - public static int UNPROTECTED_CREDENTIALS_TRANSPORT = 523; + UNPROTECTED_CREDENTIALS_TRANSPORT(523), + + /** CWE-525: Use of Web Browser Cache Containing Sensitive Information */ + SENSITIVE_INFORMATION_IN_BROWSER_CACHE(525), + + /** CWE-530: Exposure of Backup File to an Unauthorized Control Sphere */ + EXPOSE_BACKUP_TO_UNAUTHORIZED_TARGET(530), /** CWE-532: Insertion of Sensitive Information into Log File */ - public static int SENSITIVE_LOGFILE = 532; + SENSITIVE_LOGFILE(532), + + /** CWE-538: Insertion of Sensitive Information into Externally-Accessible File or Directory */ + SENSITIVE_INFO_IN_EXTERNAL_ACCESSIBLE_SPACE(538), + + /** CWE-539: Use of Persistent Cookies Containing Sensitive Information */ + PERSISTENT_COOKIE_CONTAINS_SENSITIVE_INFO(539), + + /** CWE-541: Inclusion of Sensitive Information in an Include File */ + SENSITIVE_INFORMATION_IN_INCLUDED_FILE(541), + + /** CWE-547: Use of Hard-coded, Security-relevant Constants */ + HARDCODED_SECURITY_RELEVANT_CONSTANTS(547), + + /** CWE-561: Dead Code */ + DEAD_CODE(561), + + /** CWE-563: Assignment to Variable without Use */ + UNUSED_VAR_ASSIGNMENT(563), /** CWE-564: SQL Injection: Hibernate */ - public static int HIBERNATE_INJECTION = 564; + HIBERNATE_INJECTION(564), + + /** CWE-565: Reliance on Cookies without Validation and Integrity Checking */ + MISSING_COOKIE_VALIDATION(565), + + /** CWE-567: Unsynchronized Access to Shared Data in a Multithreaded Context */ + UNSYNCHRONIZED_ACCESS_TO_SHARED_DATA(567), + + /** CWE-570: Expression is Always False */ + EXPRESSION_ALWAYS_FALSE(570), + + /** CWE-571: Expression is Always True */ + EXPRESSION_ALWAYS_TRUE(571), /** CWE-572: Call to Thread run() instead of start() */ - public static int THREAD_WRONG_CALL = 572; + THREAD_WRONG_CALL(572), - /** CWE-580: clone() Method Without super.clone() */ - public static int CLONE_WITHOUT_SUPER_CLONE = 580; + /** CWE-579: J2EE Bad Practices: Non-serializable Object Stored in Session */ + NON_SERIALIZABLE_OBJECT_IN_SESSION(579), - /** CWE-563: Assignment to Variable without Use */ - public static int UNUSED_VAR_ASSIGNMENT = 563; + /** CWE-580: clone() Method Without super.clone() */ + CLONE_WITHOUT_SUPER_CLONE(580), /** CWE-581: Object Model Violation: Just One of Equals and Hashcode Defined */ - public static int OBJECT_MODEL_VIOLATION = 581; + OBJECT_MODEL_VIOLATION(581), + + /** CWE-582: Array Declared Public, Final, and Static */ + STATIC_FINAL_ARRAY_IS_PUBLIC(582), /** CWE-583: finalize() Method Declared Public */ - public static int FINALIZE_DECLARED_PUBLIC = 583; + FINALIZE_DECLARED_PUBLIC(583), /** CWE-584: Return Inside Finally Block */ - public static int RETURN_INSIDE_FINALLY = 584; + RETURN_INSIDE_FINALLY(584), + + /** CWE-594: J2EE Framework: Saving Unserializable Objects to Disk */ + SAVING_UNSERIALIZABLE_OBJECT_TO_DISK(594), /** CWE-595: Comparison of Object References Instead of Object Contents */ - public static int OBJECT_REFERENCE_COMPARISON = 595; + OBJECT_REFERENCE_COMPARISON(595), + + /** CWE-600: Uncaught Exception in Servlet */ + UNCAUGHT_EXCEPTION_IN_SERVLET(600), + + /** CWE-601: URL Redirection to Untrusted Site ('Open Redirect') */ + OPEN_REDIRECT(601), + + /** CWE-606: Unchecked Input for Loop Condition */ + UNCHECKED_INPUT_FOR_LOOP_CONDITION(606), + + /** CWE-607: Public Static Final Field References Mutable Object */ + PUBLIC_STATIC_FINAL_MUTABLE_OBJECT(607), /** CWE-611: Improper Restriction of XML External Entity Reference */ - public static int XXE = 611; + XXE(611), + + /** CWE-613: Insufficient Session Expiration */ + INSUFFICIENT_SESSION_EXPIRATION(613), /** CWE-614: Sensitive Cookie in HTTPS Session Without 'Secure' Attribute */ - public static int INSECURE_COOKIE = 614; + INSECURE_COOKIE(614), /** CWE-643: Improper Neutralization of Data within XPath Expressions ('XPath Injection') */ - public static int XPATH_INJECTION = 643; + XPATH_INJECTION(643), /** * CWE-649: Reliance on Obfuscation or Encryption of Security-Relevant Inputs without Integrity * Checking */ - public static int OBFUSCATION = 649; + OBFUSCATION(649), + + /** CWE-650: Trusting HTTP Permission Methods on the Server Side */ + TRUSTING_SERVER_HTTP(650), + + /** CWE-652: Improper Neutralization of Data within XQuery Expressions ('XQuery Injection') */ + XQUERY_INJECTION(652), + + /** CWE-676: Use of Potentially Dangerous Function */ + USE_POTENTIALLY_DANGEROUS_FUNCTION(676), + + /** CWE-681: Incorrect Conversion between Numeric Types */ + INCORRECT_NUMERIC_TYPE_CONVERSION(681), + + /** CWE-693: Protection Mechanism Failure */ + PROTECTION_MECHANISM_FAILURE(693), + + /** CWE-703: Improper Check or Handling of Exceptional Conditions */ + IMPROPER_CHECK_FOR_EXCEPTION_CONDITIONS(703), + + /** CWE-732: Incorrect Permission Assignment for Critical Resource */ + INCORRECT_PERMISSIONS_FOR_CRITICAL_RESOURCE(732), /** CWE-754: Improper Check for Unusual or Exceptional Conditions */ - public static int IMPROPER_CHECK_FOR_CONDITIONS = 754; + IMPROPER_CHECK_FOR_CONDITIONS(754), + + /** CWE-760: Use of a One-Way Hash with a Predictable Salt */ + ONE_WAY_HASH_WITH_PREDICTABLE_SALT(760), + + /** CWE-759: Use of a One-Way Hash without a Salt */ + UNSALTED_ONE_WAY_HASH(759), + + /** CWE-772: Missing Release of Resource after Effective Lifetime */ + MISSING_RELEASE_OF_RESOURCE(772), + + /** + * CWE-776: Improper Restriction of Recursive Entity References in DTDs ('XML Entity Expansion') + */ + XML_ENTITY_EXPANSION(776), + + /** CWE-778: Insufficient Logging */ + INSUFFICIENT_LOGGING(778), + + /** CWE-780: Use of RSA Algorithm without OAEP */ + RSA_MISSING_PADDING(780), /** CWE-783: Operator Precedence Logic Error */ - public static int OPERATOR_PRECEDENCE_LOGIC = 783; + OPERATOR_PRECEDENCE_LOGIC(783), + + /** + * CWE-784: Reliance on Cookies without Validation and Integrity Checking in a Security Decision + */ + RELIANCE_ON_UNCHECKED_COOKIE(784), + + /** CWE-789: Memory Allocation with Excessive Size Value */ + EXCESSIVE_SIZE_MEMORY_ALLOCATION(789), + + /** CWE-798: Use of Hard-coded Credentials */ + HARDCODED_CREDENTIALS(798), + + /** CWE-807: Reliance on Untrusted Inputs in a Security Decision */ + RELIANCE_IN_UNTRUSTED_INPUT(807), + + /** CWE-829: Inclusion of Functionality from Untrusted Control Sphere */ + INCLUDE_CODE_FROM_UNTRUSTED_SOURCE(829), /** CWE-835: Loop with Unreachable Exit Condition ('Infinite Loop') */ - public static int LOOP_WITH_UNREACHABLE_EXIT = 835; + LOOP_WITH_UNREACHABLE_EXIT(835), + + /** CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes */ + IMPROPER_CHECK_FOR_MODIFICATION(915), + + /** CWE-918: Server-Side Request Forgery (SSRF) */ + SERVER_SIDE_REQUEST_FORGERY(918), + + /** CWE CATEGORY: OWASP Top Ten 2013 Category A5 - Security Misconfiguration */ + CATEGORY_OWASP_2013_A5(933), + + /** + * CWE-937: CWE CATEGORY: OWASP Top Ten 2013 Category A9 - Using Components with Known + * Vulnerabilities + */ + CATEGORY_OWASP_2013_A9(937), + + /** CWE-943: Improper Neutralization of Special Elements in Data Query Logic */ + IMPROPER_DATA_QUERY_NEUTRALIZATION(943), /** CWE-1004: Sensitive Cookie Without 'HttpOnly' Flag */ - public static int COOKIE_WITHOUT_HTTPONLY = 1004; + COOKIE_WITHOUT_HTTPONLY(1004), + + /** CWE-1021: Improper Restriction of Rendered UI Layers or Frames */ + IMPROPER_RESTRICTION_OF_UI_LAYERS(1021), + + /** CWE-1275: Sensitive Cookie with Improper SameSite Attribute */ + SENSITIVE_COOKIE_WITH_IMPROPER_SAMESITE_ATTR(1275); + + int number; + + CweNumber(int number) { + this.number = number; + } + + public static CweNumber lookup(int searchFor) { + for (CweNumber entry : CweNumber.class.getEnumConstants()) { + if (entry.number == searchFor) { + return entry; + } + } + + System.out.println( + "WARN: " + callerClass() + " requested unmapped CWE number " + searchFor + "."); + + return DONTCARE; + } + + private static String callerClass() { + return simpleName(Thread.currentThread().getStackTrace()[3].getClassName()); + } + + private static String simpleName(String fullClassName) { + return fullClassName.substring(fullClassName.lastIndexOf('.') + 1); + } + + public static CweNumber lookup(String searchFor) { + try { + return lookup(Integer.parseInt(searchFor)); + } catch (NumberFormatException n) { + System.out.println( + "ERROR: Failed to parse CWE number '" + + searchFor + + "' provided by " + + callerClass() + + "."); + return CweNumber.DONTCARE; + } + } } diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/TestCaseResult.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/TestCaseResult.java index 94e51254..b3961c0d 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/TestCaseResult.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/TestCaseResult.java @@ -27,7 +27,7 @@ public class TestCaseResult { private int number = 0; private boolean real = false; private boolean result = false; - private int CWE = 0; + private CweNumber CWE = CweNumber.DONTCARE; private String category = null; private String evidence = null; private int confidence = 0; @@ -84,11 +84,11 @@ public void setPassed(boolean result) { this.result = result; } - public int getCWE() { + public CweNumber getCWE() { return CWE; } - public void setCWE(int cwe) { + public void setCWE(CweNumber cwe) { this.CWE = cwe; } 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 87b25063..4ee5f071 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 @@ -159,10 +159,8 @@ private TestCaseResult parseAcunetixVulnerability(Node vuln) throws Exception { Node vulnId = getNamedChild("cwe", classification); if (vulnId != null) { String cweNum = vulnId.getTextContent(); - int cwe = cweLookup(cweNum); - tcr.setCWE(cwe); - // System.out.println("Found CWE: " + cwe + " in test case: " + - // tcr.getNumber()); + tcr.setCWE(cweLookup(cweNum)); + tcr.setConfidence( Integer.parseInt(getNamedChild("certainty", vuln).getTextContent())); return tcr; @@ -198,8 +196,7 @@ private TestCaseResult parseAcunetixReportItem(Node flaw) throws Exception { Node vulnId = getNamedChild("CWE", flaw); if (vulnId != null) { String cweNum = getAttributeValue("id", vulnId); - int cwe = cweLookup(cweNum); - tcr.setCWE(cwe); + tcr.setCWE(cweLookup(cweNum)); } // String conf = getNamedChild( "Severity", flaw ).getTextContent(); @@ -230,40 +227,12 @@ private TestCaseResult parseAcunetixReportItem(Node flaw) throws Exception { return null; } - private int cweLookup(String cweNum) { + private CweNumber cweLookup(String cweNum) { if (cweNum == null || cweNum.isEmpty()) { System.out.println("ERROR: No CWE number supplied"); - return 0000; - } - switch (cweNum) { - case "22": - return CweNumber.PATH_TRAVERSAL; - case "78": - return CweNumber.COMMAND_INJECTION; - case "79": - return CweNumber.XSS; - case "89": - return CweNumber.SQL_INJECTION; - case "614": - return CweNumber.INSECURE_COOKIE; - - // switch left in case we ever need to map a reported cwe to the one expected by - // Benchmark - // case "ldap-injection" : return 90; // 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 "xpath-injection" : return 643; // xpath injection - // 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 "trust-boundary-violation" : return 501; // trust boundary - // case "xxe" : return 611; // xml entity + return CweNumber.DONTCARE; } - // Add any 'new' CWEs ever found to switch above so we know they are mapped properly. - System.out.println("INFO: Found following CWE which we haven't seen before: " + cweNum); - return Integer.parseInt(cweNum); + return CweNumber.lookup(cweNum); } } 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 c856196c..665aa8d1 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,6 +21,7 @@ import java.util.List; import java.util.Map; 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; @@ -147,8 +148,10 @@ private TestCaseResult parseAppScanDynamicVulnerability( TestCaseResult tcr = new TestCaseResult(); String cwekey = getAttributeValue("IssueTypeID", issue); Integer cwe = cweMap.get(cwekey); - if (cwe == null) return null; - tcr.setCWE(translate(cwe)); + if (cwe == null) { + return null; + } + tcr.setCWE(CweNumber.lookup(cwe)); tcr.setCategory(cwekey); tcr.setEvidence(cwekey); @@ -173,36 +176,4 @@ private TestCaseResult parseAppScanDynamicVulnerability( return null; } - - private int translate(int id) { - switch (id) { - // //case "Build Misconfiguration" : return 00; - // case "Command Injection" : return 78; - // case "Cookie Security" : return 614; - // case "Cross-Site Scripting" : return 79; - // //case "Dead Code" : return 00; - // //case "Denial of Service" : return 00; - // case "Header Manipulation" : return 113; - // case "Insecure Randomness" : return 330; - // //case "J2EE Bad Practices" : return 00; - // case "LDAP Injection" : return 90; - // //case "Missing Check against Null" : return 00; - // //case "Null Dereference" : return 00; - // case "Password Management" : return 00; - // case "Path Manipulation" : return 22; - // //case "Poor Error Handling" : return 00; - // //case "Poor Logging Practice" : return 00; - // //case "Poor Style" : return 00; - // //case "Resource Injection" : return 00; - // case "SQL Injection" : return 89; - // //case "System Information Leak" : return 00; - // case "Trust Boundary Violation" : return 501; - // //case "Unreleased Resource" : return 00; - // //case "Unsafe Reflection" : return 00; - // case "Weak Cryptographic Hash" : return 328; - // case "Weak Encryption" : return 327; - // case "XPath Injection" : return 643; - } - return id; - } } 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 315b7ee9..c8507397 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 @@ -143,7 +143,7 @@ private String parseTime(String message) { } } */ - private int cweLookup(String vtype) { + private CweNumber cweLookup(String vtype) { switch (vtype) { // case "Vulnerability.AppDOS" : return 00; // case "Vulnerability.Authentication.Entity" : return 00; @@ -160,7 +160,7 @@ private int cweLookup(String vtype) { case "Vulnerability.Injection.LDAP": return CweNumber.LDAP_INJECTION; case "Vulnerability.Injection.OS": - return CweNumber.COMMAND_INJECTION; + return CweNumber.OS_COMMAND_INJECTION; case "Vulnerability.Injection.SQL": return CweNumber.SQL_INJECTION; case "Vulnerability.Injection.XPath": @@ -178,7 +178,7 @@ private int cweLookup(String vtype) { case "Vulnerability.Validation.Required": return CweNumber.TRUST_BOUNDARY_VIOLATION; } - return 0; + return CweNumber.DONTCARE; } /** 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 f7c9674f..68ebf9cb 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 @@ -25,6 +25,7 @@ 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; @@ -144,7 +145,7 @@ private TestCaseResult parseArachniIssue(Node flaw) throws URISyntaxException { TestCaseResult tcr = new TestCaseResult(); Node rule = getNamedChild("cwe", flaw); if (rule != null) { - tcr.setCWE(cweLookup(rule.getTextContent())); + tcr.setCWE(CweNumber.lookup(rule.getTextContent())); } String cat = getNamedChild("name", flaw).getTextContent(); @@ -178,8 +179,4 @@ private TestCaseResult parseArachniIssue(Node flaw) throws URISyntaxException { } return null; } - - private int cweLookup(String orig) { - return Integer.parseInt(orig); - } } 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 a6e34b8a..7f9a0932 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 @@ -21,6 +21,7 @@ import org.json.JSONException; 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; @@ -100,7 +101,7 @@ private TestCaseResult parseBurpJSONFinding(JSONObject finding) { String testNumber = filename.substring(BenchmarkScore.TESTCASENAME.length()); tcr.setNumber(Integer.parseInt(testNumber)); int rule = issue.getInt("type_index"); - int cwe = BurpReader.cweLookup(new Integer(rule).toString()); + CweNumber cwe = BurpReader.cweLookup(new Integer(rule).toString()); tcr.setCWE(cwe); // tcr.setEvidence( issue.getString("description") ); // Sometimes descriptions // aren't provided, so comment out. 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 e64b827b..6487f285 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 @@ -108,10 +108,10 @@ private TestCaseResult parseBurpVulnerability(Node issue) { // 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 // that are currently relevant in the Benchmark. - static int cweLookup(String id) { + static CweNumber cweLookup(String id) { switch (id) { case "1048832": - return CweNumber.COMMAND_INJECTION; + return CweNumber.OS_COMMAND_INJECTION; case "1049088": return CweNumber.SQL_INJECTION; case "1049344": @@ -130,46 +130,40 @@ static int cweLookup(String id) { return CweNumber.XSS; case "2098944": return CweNumber.CSRF; - case "3146240": - return 918; // External service interaction (DNS) - case "4194560": - return CweNumber.DONTCARE; // Referer Dependent Response - case "4194576": - return CweNumber.DONTCARE; // X-Forwarded-For header dependency - case "4197376": - return 20; // Input returned in response (reflected) - case "4197632": - return 20; // Suspicious input transformation (reflected) + case "3146240": // External service interaction (DNS) + return CweNumber.SERVER_SIDE_REQUEST_FORGERY; + case "4194560": // Referer Dependent Response + return CweNumber.DONTCARE; + case "4194576": // X-Forwarded-For header dependency + return CweNumber.DONTCARE; + case "4197376": // Input returned in response (reflected) + case "4197632": // Suspicious input transformation (reflected) + return CweNumber.IMPROPER_INPUT_VALIDAITON; case "5243392": return CweNumber.INSECURE_COOKIE; - case "5244416": - return 9998; // Cookie without HttpOnly flag set - There is no CWE defined for this - // weakness - case "5245344": - return 1021; // Clickjacking - case "5245360": - return 16; // Browser cross-site scripting filter disabled - case "5245952": - return CweNumber - .DONTCARE; // Ajax request header manipulation (DOM-based) - Map to nothing - // right - case "5247488": - return CweNumber - .DONTCARE; // DOM Trust Boundary Violation - Map to nothing right now. - case "6291968": - return 200; // Information Disclosure - Email Address Disclosed - case "6292736": - return 200; // Information Disclosure - Credit Card # Disclosed - case "7340288": - return 525; // Information Exposure Through Browser Caching-Cacheable HTTPS Response - case "8389120": - return CweNumber.DONTCARE; // HTML doesn't specify character set - Map to nothing. - case "8389632": - return CweNumber.DONTCARE; // Incorrect Content Type - Map to nothing right now. - case "8389888": - return 16; // Content type is not specified + case "5244416": // Cookie without HttpOnly flag set + return CweNumber.COOKIE_WITHOUT_HTTPONLY; + case "5245344": // Clickjacking + return CweNumber.IMPROPER_RESTRICTION_OF_UI_LAYERS; + case "5245360": // Browser cross-site scripting filter disabled + return CweNumber.CATEGORY_CONFIGURATION; + case "5245952": // Ajax request header manipulation (DOM-based) - Map to nothing right + return CweNumber.DONTCARE; + case "5247488": // DOM Trust Boundary Violation - Map to nothing right now. + return CweNumber.DONTCARE; + case "6291968": // Information Disclosure - Email Address Disclosed + case "6292736": // Information Disclosure - Credit Card # Disclosed + return CweNumber.EXPOSURE_SENSITIVE_TO_UNAUTHORIZED_USER; + case "7340288": // Information Exposure Throug Browser Caching-Cacheable HTTPS Response + return CweNumber.SENSITIVE_INFORMATION_IN_BROWSER_CACHE; + case "8389120": // HTML doesn't specify character set - Map to nothing. + return CweNumber.DONTCARE; + case "8389632": // Incorrect Content Type - Map to nothing right now. + return CweNumber.DONTCARE; + case "8389888": // Content type is not specified + return CweNumber.CATEGORY_CONFIGURATION; } // end switch(id) System.out.println("Unknown Burp rule id: " + id); - return -1; + return CweNumber.DONTCARE; } } 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 f5478ce9..846c59ae 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 @@ -82,8 +82,7 @@ private TestCaseResult parseCASTAIPIssue(Node flaw) throws Exception { // Get CWE # violation = violation.substring(violation.indexOf("CWE-") + "CWE-".length()); violation = violation.substring(0, violation.indexOf(')')); - int cwe = cweLookup(violation); - tcr.setCWE(cwe); + tcr.setCWE(cweLookup(violation)); // Get Benchmark test case #. If it's not in a Benchmark test case, return null String filename = getAttributeValue("name", flaw); @@ -99,47 +98,11 @@ private TestCaseResult parseCASTAIPIssue(Node flaw) throws Exception { return null; } - private int cweLookup(String name) { + private CweNumber cweLookup(String name) { if (name == null || name.isEmpty()) { - return 0000; + return CweNumber.DONTCARE; } - switch (name.trim()) { - case "614": - return CweNumber.INSECURE_COOKIE; - case "78": - return CweNumber.COMMAND_INJECTION; - case "79": - return CweNumber.XSS; - case "89": - return CweNumber.SQL_INJECTION; - case "90": - 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": - 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 CweNumber.TRUST_BOUNDARY_VIOLATION; - // case "xxe" : return 611; // xml entity - case "134": - 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 + "'"); - } - return 0000; + + return CweNumber.lookup(name.trim()); } } 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 024972bc..594548cd 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 @@ -57,12 +57,7 @@ public TestSuiteResults parse(ResultFile resultFile) throws Exception { JSONObject query = queries.getJSONObject(i); // cwe - int cwe = query.getJSONObject("Metadata").getInt("CweId"); - try { - cwe = translate(cwe); - } catch (NumberFormatException ex) { - System.out.println("flaw: " + query); - } + CweNumber cwe = translate(query.getJSONObject("Metadata").getInt("CweId")); // category String category = query.getJSONObject("Metadata").getString("QueryName"); @@ -116,22 +111,23 @@ private boolean isIrrelevant(String name) { || name.equals("Unprotected_Cookie"); } - private int translate(int cwe) { + private CweNumber translate(int cwe) { switch (cwe) { case 77: case 15: - return CweNumber.COMMAND_INJECTION; + return CweNumber.OS_COMMAND_INJECTION; case 36: case 23: return CweNumber.PATH_TRAVERSAL; case 338: return CweNumber.WEAK_RANDOM; } - return cwe; + + return CweNumber.lookup(cwe); } private TestCaseResult parseCheckmarxFindings( - int cwe, String category, String evidence, JSONObject result) { + CweNumber cwe, String category, String evidence, JSONObject result) { try { TestCaseResult tcr = new TestCaseResult(); tcr.setCWE(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 2ffc5b38..b39c5db4 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 @@ -22,6 +22,7 @@ import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVRecord; 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; @@ -68,7 +69,7 @@ public TestSuiteResults parse(ResultFile resultFile) throws Exception { Integer.parseInt( testCase.substring( testCase.length() - BenchmarkScore.TESTIDLENGTH))); - if (tcr.getCWE() != 0) { + if (!CweNumber.DONTCARE.equals(tcr.getCWE())) { tr.put(tcr); } } @@ -77,103 +78,101 @@ public TestSuiteResults parse(ResultFile resultFile) throws Exception { return tr; } - private int cweLookup(String checkerKey) { + private CweNumber cweLookup(String checkerKey) { // checkerKey = checkerKey.replace("-SECOND-ORDER", ""); switch (checkerKey) { case "App_DOS_Database_Connections": - return 400; // App_DOS_Database_Connections + return CweNumber.UNCONTROLLED_RESOURCE_CONSUMPTION; // App_DOS_Database_Connections case "Blind_SQL_Injection": - return 89; // sql injection + return CweNumber.SQL_INJECTION; case "Click_Jacking": - return 693; // Click_Jacking + return CweNumber.PROTECTION_MECHANISM_FAILURE; case "Command_Injection": - return 78; // Command_Injection + return CweNumber.OS_COMMAND_INJECTION; case "CORS": - return 346; // CORS + return CweNumber.ORIGIN_VALIDATION_ERROR; case "CSRF": - return 352; // CSRF + return CweNumber.CSRF; case "Debug_Mode_Enabled": - return 215; // Debug_Mode_Enabled + return CweNumber.SENSITIVE_INFO_IN_DEBUG_MODE; case "Deserialize_Vulnerability": - return 502; // Deserialize_Vulnerability + return CweNumber.INSECURE_DESERIALIZATION; case "Failed_Login_Without_Audit": - return 778; // Failed_Login_Without_Audit + return CweNumber.INSUFFICIENT_LOGGING; case "File_Upload_To_Unprotected_Directory": - return 434; // File_Upload_To_Unprotected_Directory + return CweNumber.UNRESTRICTED_FILE_UPLOAD; case "Improper_HTTP_Get_Usage": - return 650; // Improper_HTTP_Get_Usage + return CweNumber.TRUSTING_SERVER_HTTP; case "Insecure_Cookie": case "Session_Id_Disclosure": // CxIAST does not define but it is same as // Insecure_Cookie YE - return 614; // Insecure_Cookie + return CweNumber.INSECURE_COOKIE; case "Insecure_Outgoing_Communication": - return 311; // Insecure_Outgoing_Communication + return CweNumber.UNENCRYPTED_SENSITIVE_DATA; case "Insufficient_Session_Expiration": - return 613; // Insufficient_Session_Expiration + return CweNumber.INSUFFICIENT_SESSION_EXPIRATION; case "LDAP_Injection": - return 90; // LDAP_Injection + return CweNumber.LDAP_INJECTION; case "Least_Privilege_Violation": - return 250; // Least_Privilege_Violation + return CweNumber.TOO_PRIVILIGED_EXECUTION; case "Log_Forging": - return 117; + return CweNumber.MISSING_LOG_OUTPUT_NEUTRALIZATION; case "Missing_X_Content_Type_Options_Header": - return 693; + return CweNumber.PROTECTION_MECHANISM_FAILURE; case "Missing_X_XSS_Protection_Header": - return 693; + return CweNumber.PROTECTION_MECHANISM_FAILURE; case "NoSQL_Injection": - return 943; + return CweNumber.IMPROPER_DATA_QUERY_NEUTRALIZATION; case "Open_Redirect": - return 601; + return CweNumber.OPEN_REDIRECT; case "Parameter_Pollution": - return 235; + return CweNumber.IMPROPER_HANDLING_OF_PARAMETERS; case "Parameter_Tampering": - return 99; + return CweNumber.RESOURCE_INJECTION; case "Path_Traversal": - return 22; + return CweNumber.PATH_TRAVERSAL; case "Second_Order_Command_Injection": - return 77; + return CweNumber.COMMAND_INJECTION; case "Second_Order_LDAP_Injection": - return 90; + return CweNumber.LDAP_INJECTION; case "Second_Order_Path_Traversal": - return 22; + return CweNumber.PATH_TRAVERSAL; case "Second_Order_SQL_Injection": - return 89; + return CweNumber.SQL_INJECTION; case "Second_Order_XPath_Injection": - return 643; + return CweNumber.XPATH_INJECTION; case "Sensitive_Data_Exposure_Credit_Card": - return 311; case "Sensitive_Data_Exposure_Email": - return 311; case "Sensitive_Data_Exposure_Long_Number": - return 311; + return CweNumber.UNENCRYPTED_SENSITIVE_DATA; case "SQL_Injection": - return 89; + return CweNumber.SQL_INJECTION; case "Stored_XSS": - return 79; + return CweNumber.XSS; case "Successful_Login_Without_Audit": - return 778; + return CweNumber.INSUFFICIENT_LOGGING; case "Trust_Boundary_Violation": - return 501; + return CweNumber.TRUST_BOUNDARY_VIOLATION; case "Weak_Cryptography": - return 327; + return CweNumber.WEAK_CRYPTO_ALGO; case "Weak_DB_Password": - return 521; + return CweNumber.WEAK_PASSWORD_REQUIREMENTS; case "Weak_Hashing": - return 328; + return CweNumber.WEAK_HASH_ALGO; case "Weak_Random": - return 330; + return CweNumber.WEAK_RANDOM; case "XPath_Injection": - return 643; + return CweNumber.XPATH_INJECTION; case "XSS": - return 79; + return CweNumber.XSS; case "XXE": - return 611; + return CweNumber.XXE; default: System.out.println( "WARNING: Unmapped Vulnerability category detected: " + checkerKey); } - return 0; + return CweNumber.DONTCARE; } } 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 9ad9e1ac..81b3417d 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 @@ -21,8 +21,8 @@ import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; -import org.owasp.benchmarkutils.score.CweNumber; 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; @@ -217,17 +217,18 @@ private TestCaseResult parseCheckmarxVulnerability(Node query, Node result) { return null; } - private int translate(int cwe) { + private CweNumber translate(int cwe) { switch (cwe) { case 77: case 15: - return CweNumber.COMMAND_INJECTION; + return CweNumber.OS_COMMAND_INJECTION; case 36: case 23: return CweNumber.PATH_TRAVERSAL; case 338: return CweNumber.WEAK_RANDOM; } - return cwe; + + return CweNumber.lookup(cwe); } } diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/CodeQLReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/CodeQLReader.java index af3b61fb..00330ffb 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/CodeQLReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/CodeQLReader.java @@ -22,6 +22,7 @@ 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; @@ -177,8 +178,7 @@ private TestCaseResult parseLGTMFinding( "WARNING: Unexpectedly found more than one location for finding against rule: " + ruleId); } - int cwe = mapCWE(ruleId, cweForRule); - tcr.setCWE(cwe); + tcr.setCWE(mapCWE(cweForRule)); // tcr.setCategory( props.getString( "subcategoryShortDescription" ) ); // // Couldn't find any Category info in results file tcr.setEvidence(finding.getJSONObject("message").getString("text")); @@ -190,75 +190,18 @@ private TestCaseResult parseLGTMFinding( return null; } - private int mapCWE(String ruleName, Integer cweNumber) { - - switch (cweNumber) { - // These are properly mapped by default - case 22: // java/path-injection and zipslip - case 78: // java & js/command-line-injection - case 79: // java/xss & js/reflected-xss - case 89: // java & js/sql-injection and similar sqli rules - case 90: // java/ldap-injection - case 327: // java/weak-cryptographic-algorithm - case 611: // java & js/xxe - case 614: // java/insecure-cookie - case 643: // java/xml/xpath-injection - return cweNumber.intValue(); // Return CWE as is - - // These rules we care about, but have to map to the CWE we expect - case 335: // java/predictable-seed - This mapping improves the tool's score - return 330; // Weak Random - - /* - * These rules exist in the java-code-scanning.qls query set, but we don't see findings - * for them in Benchmark currently. They are left here in case we do see them in the - * future to make it easier to support them. - // These rules we care about, but have to map to the CWE we expect - case 338: // java/jhipster-prng - return 330; // Weak Random - case 347: // java/missing-jwt-signature-check - TODO - Does this affect score? - return 327; // Weak Crypto - - // These rules we don't care about now, but we return their CWE value anyway in case - // we care in the future - case 94: // java/insecure-bean-validation and many others - case 190: // java/implicit-cast-in-compound-assignment - case 197: // java/tainted-numeric-cast - case 297: // java/unsafe-hostname-verification - case 300: // java/maven/non-https-url - case 315: // java/cleartext-storage-in-cookie - case 352: // java/spring-disabled-csrf-protection - case 502: // java/unsafe-deserialization - case 601: // java/unvalidated-url-redirection - case 732: // java/world-writable-file-read - case 807: // java/tainted-permissions-check - case 917: // java/ognl-injection - case 918: // java/ssrf - case 1104: // java/maven/dependency-upon-bintray - */ - - case 113: // java/http-response-splitting - case 117: // js/log-injection - case 134: // java/tainted-format-string - case 209: // java/stack-trace-exposure - case 404: // java/database-resource-leak - case 477: // java/deprecated-call - case 485: // java/abstract-to-concrete-cast - case 561: // java/unused-parameter - case 563: // js/useless-assignment-to-local - case 570: // java/constant-comparison - case 685: // java/unused-format-argument - case 730: // js/regex-injection (i.e., DOS) - case 776: // js/xml-bomb (i.e., XEE, as opposed to XXE, which is already mapped above - case 843: // js/type-confusion-through-parameter-tampering - return cweNumber.intValue(); // Return CWE as is - default: - System.out.println( - "CodeQL parser encountered new unmapped vulnerability type: " - + cweNumber - + " for rule: " - + ruleName); + /** + * Maps detected CWE number to one that BenchmarkScore expects. + * + * @param cweNumber reported CWE number + * @return fixed (or same) CWE number + */ + private CweNumber mapCWE(Integer cweNumber) { + // java/predictable-seed - This mapping improves the tool's score + if (cweNumber == 335) { + return CweNumber.WEAK_RANDOM; } - return 0; // Not mapped to anything + + return CweNumber.lookup(cweNumber); } } diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ContrastAssessReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ContrastAssessReader.java index 1b840268..0efb6dcc 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ContrastAssessReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ContrastAssessReader.java @@ -131,7 +131,8 @@ private void parseContrastNodeFinding(TestSuiteResults tr, String line) throws E tcr.setCWE(cweLookup(elements[0])); tcr.setCategory(elements[0]); - if (tcr.getCWE() != 0 && elements[1].contains(BenchmarkScore.TESTCASENAME)) { + if (!CweNumber.DONTCARE.equals(tcr.getCWE()) + && elements[1].contains(BenchmarkScore.TESTCASENAME)) { String testNumber = elements[1].substring( elements[1].lastIndexOf('/') @@ -165,16 +166,20 @@ private void parseContrastJavaFinding(TestSuiteResults tr, String json) throws E try { JSONObject obj = new JSONObject(json); String ruleId = obj.getString("ruleId"); - int cweNum = cweLookup(ruleId); - if (CweNumber.DONTCARE == cweNum) + CweNumber cweNum = cweLookup(ruleId); + + if (CweNumber.DONTCARE == cweNum) { return; // Don't bother parsing finding types we don't care about + } + tcr.setCWE(cweNum); tcr.setCategory(ruleId); JSONObject request = obj.getJSONObject("request"); String uri = request.getString("uri"); - if (tcr.getCWE() != 0 && uri.contains(BenchmarkScore.TESTCASENAME)) { + if (!CweNumber.DONTCARE.equals(tcr.getCWE()) + && uri.contains(BenchmarkScore.TESTCASENAME)) { // Normal uri's look like: "uri":"/benchmark/cmdi-00/BenchmarkTest00215", but for // web services, they can look like: // "uri":"/benchmark/rest/xxe-00/BenchmarkTest03915/send" @@ -206,7 +211,7 @@ private void parseContrastJavaFinding(TestSuiteResults tr, String json) throws E } } - static int cweLookup(String rule) { + static CweNumber cweLookup(String rule) { switch (rule) { case "autocomplete-missing": // Not sure the CWE for this. @@ -217,7 +222,7 @@ static int cweLookup(String rule) { return CweNumber.DONTCARE; case "unsafe-code-execution": // Note: This is technically CWE 95 'Eval Injection' case "cmd-injection": - return CweNumber.COMMAND_INJECTION; + return CweNumber.OS_COMMAND_INJECTION; case "cookie-flags-missing": return CweNumber.INSECURE_COOKIE; case "crypto-bad-ciphers": @@ -271,7 +276,7 @@ static int cweLookup(String rule) { System.out.println("WARNING: Contrast-Unrecognized finding type: " + rule); } - return 0; + return CweNumber.DONTCARE; } private String calculateTime(String firstLine, String lastLine) { diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ContrastScanReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ContrastScanReader.java index 28382264..d60cf2d0 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ContrastScanReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ContrastScanReader.java @@ -26,6 +26,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; 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; @@ -106,9 +107,9 @@ public TestSuiteResults parse(ResultFile resultFile) throws Exception { // TODO: This should use SARIF format, but that doesn't work yet, per above comment. for (Report.Run run : report.runs) { for (Report.Run.Result result : run.results) { - int cwe = ContrastAssessReader.cweLookup(result.rule); + CweNumber cwe = ContrastAssessReader.cweLookup(result.rule); - if (cwe <= 0) { + if (CweNumber.DONTCARE.equals(cwe)) { continue; } 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 ee008bee..84ad462c 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 @@ -20,6 +20,7 @@ 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; @@ -78,8 +79,7 @@ private TestCaseResult parseCoverityFinding(JSONObject finding, int version) { if (cweNumber == null || cweNumber.equals("none")) { return null; } - int cwe = fixCWE(cweNumber); - tcr.setCWE(cwe); + tcr.setCWE(fixCWE(cweNumber)); tcr.setCategory(props.getString("subcategoryShortDescription")); tcr.setEvidence(props.getString("subcategoryLongDescription")); return tcr; @@ -104,8 +104,7 @@ private TestCaseResult parseCoverityFinding(JSONObject finding, int version) { return null; } String cweNumber = finding.getString("cweNumber"); - int cwe = fixCWE(cweNumber); - tcr.setCWE(cwe); + tcr.setCWE(fixCWE(cweNumber)); tcr.setCategory(finding.getString("categoryDescription")); tcr.setEvidence(finding.getString("longDescription")); return tcr; @@ -177,10 +176,12 @@ private TestCaseResult parseCoverityFindingV2(JSONObject finding) { } else if (checker_name.equals("ldap_injection")) { cwe_string = "90"; } - int cwe = fixCWE(cwe_string); - if (cwe <= 0) { + CweNumber cwe = fixCWE(cwe_string); + + if (CweNumber.DONTCARE.equals(cwe)) { return null; } + tcr.setCWE(cwe); tcr.setCategory(checker_name); tcr.setEvidence(subcategory); @@ -192,11 +193,17 @@ private TestCaseResult parseCoverityFindingV2(JSONObject finding) { return null; } - private int fixCWE(String cweNumber) { + private CweNumber fixCWE(String cweNumber) { int cwe = Integer.parseInt(cweNumber); - if (cwe == 94) cwe = 643; - if (cwe == 36) cwe = 22; - if (cwe == 23) cwe = 22; - return cwe; + + switch (cwe) { + case 23: + case 36: + return CweNumber.PATH_TRAVERSAL; + case 94: + return CweNumber.XPATH_INJECTION; + } + + return CweNumber.lookup(cwe); } } 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 1728f6aa..bc9d0937 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 @@ -24,6 +24,7 @@ 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; @@ -97,9 +98,9 @@ private TestCaseResult parseCrashtestIssue(Node testcase) throws URISyntaxExcept String testCaseType = testcase.getAttributes().getNamedItem("classname").getNodeValue(); - int cwe = cweLookup(testCaseType); + CweNumber cwe = cweLookup(testCaseType); tcr.setCWE(cwe); - if (cwe != -1) { + if (CweNumber.DONTCARE.equals(cwe)) { String message = failure.getAttributes().getNamedItem("message").getNodeValue(); // Parse testcase # from URL: @@ -173,27 +174,26 @@ private TestCaseResult parseCrashtestIssue(Node testcase) throws URISyntaxExcept * name="XML External Entity (XXE) (2740)"/> * * @param the Crashtest classname - * @return CWE number or -1 if we don't care about this test type + * @return CWE Number */ - private int cweLookup(String classname) { - + private CweNumber cweLookup(String classname) { switch (classname) { case "commandinjection.crashtest.cloud": - return 78; + return CweNumber.OS_COMMAND_INJECTION; case "sqlinjection.crashtest.cloud": - return 89; + return CweNumber.SQL_INJECTION; case "xss.crashtest.cloud": - return 79; + return CweNumber.XSS; case "xxe.crashtest.cloud": - return 611; + return CweNumber.XXE; case "portscan.crashtest.cloud": case "ssl.crashtest.cloud": - return -1; + return CweNumber.DONTCARE; default: System.out.println("Unrecognized Crashtest rule: " + classname); - return -1; + return CweNumber.DONTCARE; } } } 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 60aa100b..2a04ce87 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 @@ -22,6 +22,7 @@ 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; @@ -77,7 +78,7 @@ private TestCaseResult parseFaastFinding(JSONObject finding) { if (url.contains(BenchmarkScore.TESTCASENAME)) { tcr.setNumber(Integer.parseInt(testNumber)); - tcr.setCWE(cwe); + tcr.setCWE(CweNumber.lookup(cwe)); tcr.setCategory(category); return 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 73a340d6..63984146 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 @@ -21,6 +21,7 @@ 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; @@ -118,7 +119,7 @@ private TestCaseResult parseFindBugsBug(Node n) { return null; } - private int figureCWE(TestCaseResult tcr, Node cwenode, Node catnode) { + private CweNumber figureCWE(TestCaseResult tcr, Node cwenode, Node catnode) { String cwe = null; if (cwenode != null) { cwe = cwenode.getNodeValue(); @@ -140,7 +141,7 @@ private int figureCWE(TestCaseResult tcr, Node cwenode, Node catnode) { else if (cwe.equals("326")) { cwe = "327"; } - return Integer.parseInt(cwe); + return CweNumber.lookup(cwe); } // This is a fallback mapping for unsupported/old versions of the Find Security Bugs plugin @@ -149,109 +150,100 @@ else if (cwe.equals("326")) { switch (cat) { // Cookies case "SECIC": - return 614; // insecure cookie use + return CweNumber.INSECURE_COOKIE; case "SECCU": - return 00; // servlet cookie + return CweNumber.DONTCARE; case "SECHOC": - return 00; // HTTP Only not set on cookie - Information Leak / Disclosure - // (CWE-200)?? + return CweNumber.COOKIE_WITHOUT_HTTPONLY; // Injections case "SECSQLIHIB": - return 564; // Hibernate Injection, child of SQL Injection + return CweNumber.HIBERNATE_INJECTION; case "SECSQLIJDO": - return 89; case "SECSQLIJPA": - return 89; case "SECSQLISPRJDBC": - return 89; case "SECSQLIJDBC": - return 89; + return CweNumber.SQL_INJECTION; // LDAP injection case "SECLDAPI": - return 90; // LDAP injection + return CweNumber.LDAP_INJECTION; // XPath injection case "SECXPI": - return 643; // XPATH injection + return CweNumber.XPATH_INJECTION; // Command injection case "SECCI": - return 78; // command injection + return CweNumber.OS_COMMAND_INJECTION; // Weak random case "SECPR": - return 330; // weak random + return CweNumber.WEAK_RANDOM; // Weak encryption - case "SECDU": - return 327; // weak encryption DES - case "CIPINT": - return 327; // weak encryption - cipher with no integrity - case "PADORA": - return 327; // padding oracle -- FIXME: probably wrong + case "SECDU": // weak encryption DES + return CweNumber.WEAK_CRYPTO_ALGO; + case "CIPINT": // weak encryption - cipher with no integrity + return CweNumber.WEAK_CRYPTO_ALGO; + case "PADORA": // padding oracle -- FIXME: probably wrong + return CweNumber.WEAK_CRYPTO_ALGO; case "STAIV": - return 329; // static initialization vector for crypto + return CweNumber.STATIC_CRYPTO_INIT; // Weak hash case "SECWMD": - return 328; // weak hash + return CweNumber.WEAK_HASH_ALGO; // Path traversal case "SECPTO": - return 22; // path traversal case "SECPTI": - return 22; // path traversal + return CweNumber.PATH_TRAVERSAL; // XSS case "SECXRW": - return 79; // XSS case "SECXSS1": - return 79; // XSS case "SECXSS2": - return 79; // XSS + return CweNumber.XSS; // XXE case "SECXXEDOC": - return 611; // XXE case "SECXXEREAD": - return 611; // XXE case "SECXXESAX": - return 611; // XXE + return CweNumber.XXE; // Input sources - case "SECSP": - return 00; // servlet parameter - not a vuln - case "SECSH": - return 00; // servlet header - not a vuln - case "SECSHR": - return 00; // Use of Request Header -- spoofable - case "SECSSQ": - return 00; // servlet query - not a vuln + case "SECSP": // servlet parameter - not a vuln + return CweNumber.DONTCARE; + case "SECSH": // servlet header - not a vuln + return CweNumber.DONTCARE; + case "SECSHR": // Use of Request Header -- spoofable + return CweNumber.DONTCARE; + case "SECSSQ": // servlet query - not a vuln + return CweNumber.DONTCARE; // Technology detection - case "SECSC": - return 00; // found Spring endpoint - not a vuln - case "SECJRS": - return 00; // JAX-RS Endpoint + case "SECSC": // found Spring endpoint - not a vuln + return CweNumber.DONTCARE; + case "SECJRS": // JAX-RS Endpoint + return CweNumber.DONTCARE; // Configuration - case "SECOPFP": - return 00; // Overly Permissive File Permissions + case "SECOPFP": // Overly Permissive File Permissions + return CweNumber.DONTCARE; // Other case "SECHPP": - return 235; // HTTP Parameter Polution - case "SECUNI": - return 00; // Improper Unicode - case "SECWF": - return 00; // Weak Filename Utils - i.e., not filtering out Null bytes in file names + return CweNumber.IMPROPER_HANDLING_OF_PARAMETERS; + case "SECUNI": // Improper Unicode + return CweNumber.DONTCARE; + case "SECWF": // Weak Filename Utils - i.e., not filtering out Null bytes in file names + return CweNumber.DONTCARE; default: System.out.println("Unknown vuln category for FindBugs: " + cat); } - return 0; + return CweNumber.DONTCARE; } } diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/FortifyReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/FortifyReader.java index c1ff3410..94886ccb 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/FortifyReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/FortifyReader.java @@ -225,21 +225,22 @@ private TestCaseResult parseFortifyVulnerability(Node vuln) { return null; } - private int cweLookup(String vtype, String subtype, Node unifiedNode) { - + private CweNumber cweLookup(String vtype, String subtype, Node unifiedNode) { switch (vtype) { case "Access Control": return CweNumber.IMPROPER_ACCESS_CONTROL; case "Command Injection": - return CweNumber.COMMAND_INJECTION; + return CweNumber.OS_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)) + if ("Cookie not Sent Over SSL".equals(subtype)) { return CweNumber.INSECURE_COOKIE; - else return 00; + } else { + return CweNumber.DONTCARE; + } } case "Cross-Site Request Forgery": @@ -251,41 +252,36 @@ private int cweLookup(String vtype, String subtype, Node unifiedNode) { // Not a type of XSS weakness we are testing for. Causes False Positives // for Fortify. case "Poor Validation": - return 83; + return CweNumber.IMPROPER_NEUTRALIZATION_OF_ATTRIBUTES; } - return 79; + return CweNumber.XSS; } case "Dead Code": - return 00; + return CweNumber.DONTCARE; case "Denial of Service": - return 400; + return CweNumber.UNCONTROLLED_RESOURCE_CONSUMPTION; case "Dynamic Code Evaluation": - return 95; + return CweNumber.EVAL_INJECTION; case "Header Manipulation": - return 113; + return CweNumber.HTTP_RESPONSE_SPLITTING; case "Hidden Field": - return 472; + return CweNumber.EXTERNAL_CONTROL_OF_WEB_PARAM; case "Insecure Randomness": - return 330; + return CweNumber.WEAK_RANDOM; case "Key Management": - return 320; - + return CweNumber.CATEGORY_KEY_MANAGEMENT_ERROR; case "LDAP Injection": - return 90; - + return CweNumber.LDAP_INJECTION; case "Mass Assignment": - return 915; - + return CweNumber.IMPROPER_CHECK_FOR_MODIFICATION; case "Missing Check against Null": case "Missing Check for Null Parameter": - return 476; - + return CweNumber.NULL_POINTER_DEREFERENCE; case "Missing XML Validation": - return 112; - + return CweNumber.MISSING_XML_VALIDATION; case "Null Dereference": - return 476; + return CweNumber.NULL_POINTER_DEREFERENCE; // Fortify reports weak randomness issues under Obsolete by ESAPI, rather than in // the Insecure Randomness category if it thinks you are using ESAPI. However, its @@ -310,71 +306,64 @@ private int cweLookup(String vtype, String subtype, Node unifiedNode) { // generates random #'s using the java.util.Random or // java.security.SecureRandom classes. e.g., nextWHATEVER(). (methodName != null && methodName.startsWith("next"))) { - return 330; + return CweNumber.WEAK_RANDOM; } } - return 00; // If neither of these, then don't care + return CweNumber.DONTCARE; // If neither of these, then don't care } case "Password Management": - return 00; + return CweNumber.DONTCARE; case "Path Manipulation": - return 22; - + return CweNumber.PATH_TRAVERSAL; case "Poor Error Handling": - return 703; + return CweNumber.IMPROPER_CHECK_FOR_EXCEPTION_CONDITIONS; case "Poor Logging Practice": - return 478; + return CweNumber.MISSING_DEFAULT_CASE; case "Privacy Violation": - return 359; + return CweNumber.EXPOSURE_PRIVATE_TO_UNAUTHORIZED_USER; case "Resource Injection": - return 99; - + return CweNumber.RESOURCE_INJECTION; case "SQL Injection": return CweNumber.SQL_INJECTION; case "System Information Leak": - return 209; + return CweNumber.ERROR_MESSAGE_WITH_SENSITIVE_INFO; case "Trust Boundary Violation": - return 501; + return CweNumber.TRUST_BOUNDARY_VIOLATION; case "Unchecked Return Value": - return 252; + return CweNumber.UNCHECKED_RETURN_VALUE; case "Unreleased Resource": - return 404; + return CweNumber.UNRELEASED_RESOURCE; case "Unsafe Reflection": - return 470; - + return CweNumber.UNSAFE_REFLECTION; case "Weak Cryptographic Hash": - return 328; - + return CweNumber.WEAK_HASH_ALGO; case "Weak Encryption": { switch (subtype) { // These 2 are not types of Encryption weakness we are testing for. // Cause False Positives for Fortify. case "Missing Required Step": - return 325; + return CweNumber.MISSING_CRYPTOGRAPHIC_STEP; case "Inadequate RSA Padding": - return 780; + return CweNumber.RSA_MISSING_PADDING; // TODO: Assuming this Fortify rule is valid, we might need to fix // Benchmark itself to eliminate unintended vulns. case "Insecure Mode of Operation": - return 0; // Disable so it doesn't count against Fortify. + return CweNumber + .DONTCARE; // Disable so it doesn't count against Fortify. } - return 327; + return CweNumber.WEAK_CRYPTO_ALGO; } case "XPath Injection": - return 643; - + return CweNumber.XPATH_INJECTION; case "XQuery Injection": - return 652; - + return CweNumber.XQUERY_INJECTION; case "XML Entity Expansion Injection": - return 776; - + return CweNumber.XML_ENTITY_EXPANSION; case "XML External Entity Injection": - return 611; - + return CweNumber.XXE; // Things we don't care about case "Build Misconfiguration": case "Code Correctness": @@ -386,13 +375,13 @@ private int cweLookup(String vtype, String subtype, Node unifiedNode) { case "Portability Flaw": case "Race Condition": case "Redundant Null Check": - return 00; + return CweNumber.DONTCARE; default: System.out.println( "Fortify parser encountered unknown vulnerability type: " + vtype); } // end switch - return 0; + return CweNumber.DONTCARE; } } 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 9ab8dcf0..5cba9ccd 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 @@ -27,6 +27,7 @@ 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; @@ -73,10 +74,10 @@ public TestSuiteResults parse(ResultFile resultFile) throws Exception { for (Node finding : findingList) { String findingName = getNamedChild("Name", finding).getTextContent(); - int findingCWE = - Integer.parseInt(getNamedChild("CWE", finding).getTextContent()); + CweNumber findingCWE = + CweNumber.lookup(getNamedChild("CWE", finding).getTextContent()); - if (findingCWE != 0) { + if (!CweNumber.DONTCARE.equals(findingCWE)) { int testNumber = extractTestNumber(targetURL); if (testNumber != -1) { TestCaseResult tcr = new TestCaseResult(); diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/HCLAppScanIASTReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/HCLAppScanIASTReader.java index 30080be2..d5eb563f 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/HCLAppScanIASTReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/HCLAppScanIASTReader.java @@ -101,7 +101,7 @@ private void parseFindings(TestSuiteResults tr, String json) throws Exception { if (uri.contains(BenchmarkScore.TESTCASENAME)) { tcr.setNumber(testNumber(uri)); - if (tcr.getCWE() != 0) { + if (!CweNumber.DONTCARE.equals(tcr.getCWE())) { // System.out.println( tcr.getNumber() + "\t" + tcr.getCWE() + "\t" + // tcr.getCategory() ); tr.put(tcr); @@ -113,14 +113,14 @@ private void parseFindings(TestSuiteResults tr, String json) throws Exception { } } - private int cweLookup(String rule) { + private CweNumber cweLookup(String rule) { switch (rule) { case "SessionManagement.Cookies": return CweNumber.INSECURE_COOKIE; case "Injection.SQL": return CweNumber.SQL_INJECTION; case "Injection.OS": - return CweNumber.COMMAND_INJECTION; + return CweNumber.OS_COMMAND_INJECTION; case "Injection.LDAP": return CweNumber.LDAP_INJECTION; case "CrossSiteScripting.Reflected": @@ -140,7 +140,7 @@ private int cweLookup(String rule) { default: System.out.println("WARNING: HCL AppScan IAST-Unrecognized finding type: " + rule); } - return 0; + return CweNumber.DONTCARE; } private String calculateTime(String firstLine, String lastLine) { diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/HCLAppScanSourceReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/HCLAppScanSourceReader.java index cef83386..d543414e 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/HCLAppScanSourceReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/HCLAppScanSourceReader.java @@ -76,7 +76,7 @@ public TestSuiteResults parse(ResultFile resultFile) throws Exception { getNamedChild("ref", getNamedChild("issue-type", vulnerability)) .getTextContent(); - int vtype = cweLookup(issueType); + CweNumber vtype = cweLookup(issueType); // System.out.println("Vuln type: " + issueType + " has CWE of: " + vtype); // Then get the filename containing the vuln. And if not in a test case, skip it. @@ -154,7 +154,7 @@ else if (methodSig == null) return hours + ":" + mins + ":" + secs; } */ - private int cweLookup(String vtype) { + private CweNumber cweLookup(String vtype) { switch (vtype) { // case "AppDOS" : return 00; // case "Authentication.Entity" : return 00; @@ -176,7 +176,7 @@ private int cweLookup(String vtype) { case "Injection.LDAP": return CweNumber.LDAP_INJECTION; case "Injection.OS": - return CweNumber.COMMAND_INJECTION; + return CweNumber.OS_COMMAND_INJECTION; case "Injection.SQL": return CweNumber.SQL_INJECTION; case "Injection.XPath": @@ -184,7 +184,7 @@ private int cweLookup(String vtype) { // case "Malicious.DynamicCode" : return 00; // case "Malicious.DynamicCode.Execution" : return 00; case "OpenSource": - return 00; // Known vuln in open source lib. + return CweNumber.DONTCARE; // Known vuln in open source lib. case "PathTraversal": return CweNumber.PATH_TRAVERSAL; // case "Quality.TestCode" : return 00; @@ -199,6 +199,6 @@ private int cweLookup(String vtype) { System.out.println( "WARNING: HCL AppScan Source-Unrecognized finding type: " + vtype); } - return 0; + return CweNumber.DONTCARE; } } diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/HCLAppScanStandardReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/HCLAppScanStandardReader.java index decde5d7..787748f6 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/HCLAppScanStandardReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/HCLAppScanStandardReader.java @@ -116,7 +116,7 @@ private TestCaseResult TestCaseLookup(String issueType, String url) { String testArea = urlElements[urlElements.length - 2].split("-")[0]; // .split strips off the -## - int vtype = cweLookup(issueType, testArea); + CweNumber vtype = cweLookup(issueType, testArea); // Then get the filename containing the vuln. And if not in a test case, skip it. // Parse out test number from: @@ -192,17 +192,22 @@ private List variantLookup( return testCaseElementsFromVariants; } - 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. - if ("xpathi".equals(testArea) && cwe == 89) cwe = 643; // CWE for XPath injection - if ("ldapi".equals(testArea) && cwe == 89) cwe = 90; // CWE for LDAP injection + private CweNumber cweLookup(String vtype, String testArea) { + CweNumber cwe = cweLookup(vtype); // Do the standard CWE lookup + if (CweNumber.SQL_INJECTION.equals(cwe)) { + // Then map some to other CWEs based on the test area being processed. + if ("xpathi".equals(testArea)) { + return CweNumber.XPATH_INJECTION; + } + if ("ldapi".equals(testArea)) { + return CweNumber.LDAP_INJECTION; + } + } return cwe; } - private int cweLookup(String vtype) { + private CweNumber cweLookup(String vtype) { switch (vtype) { case "attDirectoryFound": case "attDirOptions": @@ -214,7 +219,7 @@ private int cweLookup(String vtype) { case "attCommandInjectionAdns": case "attCommandInjectionUnixTws": case "attFileParamPipe": - return CweNumber.COMMAND_INJECTION; + return CweNumber.OS_COMMAND_INJECTION; case "attCrossSiteScripting": return CweNumber.XSS; @@ -273,6 +278,6 @@ private int cweLookup(String vtype) { System.out.println( "WARNING: HCL AppScan Standard-Unrecognized finding type: " + vtype); } - return 0; + return CweNumber.DONTCARE; } } diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/HdivReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/HdivReader.java index 966203f5..42797a4d 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/HdivReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/HdivReader.java @@ -29,6 +29,7 @@ import java.util.List; import java.util.Set; 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; @@ -134,7 +135,7 @@ private void process(final TestSuiteResults tr, String testNumber, final List Parse error: " + line); } - if (tcr.getCWE() != 0) { + if (!CweNumber.DONTCARE.equals(tcr.getCWE())) { tr.put(tcr); } } catch (Exception e) { 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 0a89b8ac..76932789 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 @@ -92,7 +92,7 @@ private TestCaseResult parseTestCaseResult(JSONObject finding) { return null; } - private int figureCwe(JSONObject vuln) { + private CweNumber figureCwe(JSONObject vuln) { String details = vuln.getString("details"); String cwe = fetchCweFromDetails(details); @@ -102,37 +102,17 @@ private int figureCwe(JSONObject vuln) { } switch (cwe) { - case "79": - return CweNumber.XSS; - case "89": - return CweNumber.SQL_INJECTION; case "326": - case "327": return CweNumber.WEAK_CRYPTO_ALGO; - case "328": - return CweNumber.WEAK_HASH_ALGO; - case "329": - return CweNumber.STATIC_CRYPTO_INIT; - case "330": - return CweNumber.WEAK_RANDOM; case "502": if (category(details).equals("LDAP deserialization should be disabled")) { return CweNumber.LDAP_INJECTION; } return CweNumber.INSECURE_DESERIALIZATION; - case "611": - return CweNumber.XXE; - case "614": - return CweNumber.INSECURE_COOKIE; - case "643": - return CweNumber.XPATH_INJECTION; - case "649": - return CweNumber.OBFUSCATION; - default: - System.out.println("WARN: Horusec reported CWE not yet mapped: " + cwe); - return Integer.parseInt(cwe); } + + return CweNumber.lookup(cwe); } private String fetchCweFromDetails(String details) { 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 32fd757a..56bbb3a5 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 @@ -79,8 +79,8 @@ private TestCaseResult parseTestCaseResult(JSONObject finding) { TestCaseResult tcr = new TestCaseResult(); tcr.setNumber(testNumber(filename)); - int cwe = cweNumber(finding); - tcr.setCWE(cwe); + String cwe = finding.getString("cwe").substring(4); + tcr.setCWE(mapCWE(cwe)); return tcr; } @@ -91,25 +91,18 @@ private TestCaseResult parseTestCaseResult(JSONObject finding) { return null; } - private int cweNumber(JSONObject finding) { - String cwe = finding.getString("cwe").substring(4); - - switch (cwe) { - case "78": - return CweNumber.COMMAND_INJECTION; - case "326": - case "327": - return CweNumber.WEAK_CRYPTO_ALGO; - case "330": - return CweNumber.WEAK_RANDOM; - case "532": - return CweNumber.SENSITIVE_LOGFILE; - - default: - System.out.println( - "INFO: Found following CWE which we haven't seen before: " + cwe); - return Integer.parseInt(cwe); + /** + * Maps detected CWE number to one that BenchmarkScore expects. + * + * @param cweNumber reported CWE number + * @return fixed (or same) CWE number + */ + private static CweNumber mapCWE(String cweNumber) { + if ("326".equals(cweNumber)) { + return CweNumber.WEAK_CRYPTO_ALGO; } + + return CweNumber.lookup(cweNumber); } private String filename(JSONObject vuln) { 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 b03d2e13..7026d5aa 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 @@ -21,6 +21,7 @@ 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; @@ -93,7 +94,7 @@ private TestCaseResult parseJuliaBug(Node n) { tcr.setNumber(Integer.parseInt(testNumber)); } } else if (childName.equals("CWEid")) - tcr.setCWE(Integer.parseInt(child.getTextContent())); + tcr.setCWE(CweNumber.lookup(child.getTextContent())); } return tcr; diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/KiuwanReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/KiuwanReader.java index 2b3746f1..51d9deac 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/KiuwanReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/KiuwanReader.java @@ -91,7 +91,7 @@ private TestCaseResult parseKiuwanFinding(JSONObject finding) { if (filename.contains(BenchmarkScore.TESTCASENAME)) { tcr.setNumber(testNumber(filename)); - int cwe = -1; + CweNumber cwe = CweNumber.DONTCARE; try { JSONArray mappings = finding.getJSONArray("mappings"); for (int i = 0; i < mappings.length(); i++) { @@ -103,7 +103,7 @@ private TestCaseResult parseKiuwanFinding(JSONObject finding) { } } - if (cwe != -1) { + if (!CweNumber.DONTCARE.equals(cwe)) { tcr.setCWE(cwe); tcr.setCategory(finding.getString("summary")); tcr.setEvidence(finding.getString("scannerDetail")); @@ -120,16 +120,15 @@ private TestCaseResult parseKiuwanFinding(JSONObject finding) { return null; } - private int fixCWE(String cweNumber) { - int cwe = Integer.parseInt(cweNumber); - - if (cwe == 564) { - cwe = CweNumber.SQL_INJECTION; + private CweNumber fixCWE(String cweNumber) { + if ("564".equals(cweNumber)) { + return CweNumber.SQL_INJECTION; } - if (cwe == 77) { - cwe = CweNumber.COMMAND_INJECTION; + if ("77".equals(cweNumber)) { + return CweNumber.OS_COMMAND_INJECTION; } - return cwe; + + return CweNumber.lookup(cweNumber); } } diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/KlocworkCSVReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/KlocworkCSVReader.java index b910a5dc..4b708c54 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/KlocworkCSVReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/KlocworkCSVReader.java @@ -76,7 +76,7 @@ public TestSuiteResults parse(ResultFile resultFile) throws Exception { System.out.println("> Parse error: " + record.toString()); } - if (tcr.getCWE() != 0) { + if (!CweNumber.DONTCARE.equals(tcr.getCWE())) { tr.put(tcr); } } @@ -86,10 +86,12 @@ public TestSuiteResults parse(ResultFile resultFile) throws Exception { return tr; } - private int cweLookup(String checkerKey) { + private CweNumber cweLookup(String checkerKey) { // We don't care about non-vulnerability findings - if (!checkerKey.startsWith("SV.")) return CweNumber.DONTCARE; + if (!checkerKey.startsWith("SV.")) { + return CweNumber.DONTCARE; + } switch (checkerKey) { // These few are OBE because of the SV. check above, but left in, in case we want to @@ -114,9 +116,9 @@ private int cweLookup(String checkerKey) { case "SV.EXEC.ENV": // Process Injection Environment Variables case "SV.EXEC.LOCAL": // Process Injection. Local Arguments case "SV.EXEC.PATH": // Untrusted Search Path - return CweNumber.COMMAND_INJECTION; + return CweNumber.OS_COMMAND_INJECTION; case "SV.HASH.NO_SALT": // Use of a one-way cryptographic hash without a salt - return 759; // CWE-759: Use of a One-Way Hash without a Salt + return CweNumber.UNSALTED_ONE_WAY_HASH; // Not the same as: CweNumber.WEAK_HASH_ALGO; - CWE: 328 Weak Hashing case "SV.LDAP": // Unvalidated user input is used as LDAP filter return CweNumber.LDAP_INJECTION; @@ -147,7 +149,7 @@ private int cweLookup(String checkerKey) { default: System.out.println( "WARNING: Unmapped Vulnerability category detected: " + checkerKey); - return 0; + return CweNumber.DONTCARE; } } } 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 72870d42..29e5e985 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 @@ -21,6 +21,7 @@ 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; @@ -163,8 +164,7 @@ private TestCaseResult parseLGTMFinding( "Unexpectedly found more than one location for finding against rule: " + ruleId); } - int cwe = cweForRule.intValue(); - tcr.setCWE(cwe); + tcr.setCWE(CweNumber.lookup(cweForRule.intValue())); // tcr.setCategory( props.getString( "subcategoryShortDescription" ) ); // // Couldn't find any Category info in results file tcr.setEvidence(finding.getJSONObject("message").getString("text")); @@ -175,14 +175,4 @@ private TestCaseResult parseLGTMFinding( } return null; } - - /* - private int fixCWE( String cweNumber ) { - int cwe = Integer.parseInt( cweNumber ); - if ( cwe == 94 ) cwe = 643; - if ( cwe == 36 ) cwe = 22; - if ( cwe == 23 ) cwe = 22; - return cwe; - } - */ } 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 a844d7a1..8cc18bff 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,6 +22,7 @@ import org.json.JSONException; 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; @@ -144,13 +145,12 @@ private TestCaseResult[] parseCWE(JSONObject CWE) { // Grab the number between "-num:" cwe_str = cwe_str.substring(cwe_str.indexOf('-') + 1, cwe_str.indexOf(':')); - int cwe_identifier = cweLookup(Integer.parseInt(cwe_str)); + CweNumber cwe = cweLookup(Integer.parseInt(cwe_str)); // Process each file JSONArray file_arr = CWE.getJSONArray("files"); for (int i = 0; i < file_arr.length(); i++) { - TestCaseResult result = - produceTestCaseResult(file_arr.getJSONObject(i), cwe_identifier); + TestCaseResult result = produceTestCaseResult(file_arr.getJSONObject(i), cwe); if (result != null) results.add(result); } @@ -178,13 +178,13 @@ private TestCaseResult[] parseCWE(JSONObject CWE) { *

Catch errors here because I do not want to interrupt the for loop in the above call * * @param file The JSONObject which contains a single file dictionary object - * @param cwe_identifier The numerical value of the CWE + * @param cwe CweNumber value * @return A TestCaseResult with the information from the file or null if finding is not in a * test case source file */ - private TestCaseResult produceTestCaseResult(JSONObject file, int cwe_identifier) { + private TestCaseResult produceTestCaseResult(JSONObject file, CweNumber cwe) { TestCaseResult tcr = new TestCaseResult(); - tcr.setCWE(cwe_identifier); + tcr.setCWE(cwe); String filename = ""; try { @@ -213,34 +213,16 @@ private TestCaseResult produceTestCaseResult(JSONObject file, int cwe_identifier return tcr; } - private int cweLookup(int cwe) { + private CweNumber cweLookup(int cwe) { switch (cwe) { case 23: // Relative Path Traversal <-- care about this one - return 22; // We expect 22, not 23 - - case 79: // XSS <-- care about this one - case 209: // Info leak from Error Message - case 400: // Uncontrolled Resource Consumption - case 522: // Insufficiently protected credentials - case 613: // Insufficient session expiration - case 614: // Sensitive cookie without Secure Attribute <-- care about this one - case 693: // Protection Mechanism Failure (e.g., One or more Security Response header is - // explicitly disabled in Helmet) - case 798: // Hard coded credentials - case 1275: // Sensitive cookie w/ Improper SameSite Attribute - break; // Don't care about these, or mapping is correct, so return 'as is'. - + return CweNumber.PATH_TRAVERSAL; // We expect 22, not 23 case 943: // Improper Neutralization of Special Elements in Data Query Logic (Child of // SQL Injection) - return 89; // This is likely an SQLi finding, so mapping to that. - - default: - System.out.println( - "WARNING: NJSScan-Unrecognized cwe: " - + cwe - + ". Verify mapping is correct and add mapping to NJSScanReader."); + return CweNumber + .SQL_INJECTION; // This is likely an SQLi finding, so mapping to that. } - return cwe; + return CweNumber.lookup(cwe); } } 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 310e2dc8..b3aa67c4 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 @@ -86,8 +86,7 @@ private TestCaseResult parseNetsparkerIssue(Node flaw) { Node vulnId = getNamedChild("CWE", classification); if (vulnId != null) { String cweNum = vulnId.getTextContent(); - int cwe = cweLookup(cweNum); - tcr.setCWE(cwe); + tcr.setCWE(cweLookup(cweNum)); } } @@ -112,9 +111,9 @@ private TestCaseResult parseNetsparkerIssue(Node flaw) { return null; } - private int cweLookup(String cweNum) { + private CweNumber cweLookup(String cweNum) { if (cweNum == null || cweNum.isEmpty()) { - return 0000; + return CweNumber.DONTCARE; } int cwe = Integer.parseInt(cweNum); switch (cwe) { @@ -137,6 +136,6 @@ private int cweLookup(String cweNum) { // case "trust-boundary-violation" : return 501; // trust boundary // case "xxe" : return 611; // xml entity } - return cwe; + return CweNumber.lookup(cwe); } } 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 c39fb555..ae8e86d3 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,6 +19,7 @@ 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; @@ -73,7 +74,7 @@ private void parseNoisyCricketIssue(Node item, TestSuiteResults tr) { for (String cwe : cwes) { TestCaseResult tcr = new TestCaseResult(); tcr.setNumber(testNumber); - tcr.setCWE(Integer.parseInt(cwe)); + tcr.setCWE(CweNumber.lookup(cwe)); tr.put(tcr); } } 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 6ccefdcf..3f5f8853 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 @@ -23,6 +23,7 @@ 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; @@ -35,8 +36,7 @@ public class PMDReader extends Reader { @Override public boolean canRead(ResultFile resultFile) { - return resultFile.filename().endsWith(".xml") - && resultFile.xmlRootNodeName().equals("pmd"); + return resultFile.filename().endsWith(".xml") && resultFile.xmlRootNodeName().equals("pmd"); } @Override @@ -108,7 +108,7 @@ private List parsePMDItem(Node fileNode) { return results; } - private int figureCWE(String rule) { + private CweNumber figureCWE(String rule) { switch (rule) { case "AvoidUsingOctalValues": case "CollapsibleIfStatements": @@ -126,38 +126,37 @@ private int figureCWE(String rule) { case "UnusedLocalVariable": case "UnusedPrivateMethod": case "UselessParentheses": - return 0000; // Don't care + return CweNumber.DONTCARE; // Don't think PMD reports any of these: case "??1": - return 614; // insecure cookie use + return CweNumber.INSECURE_COOKIE; case "??2": - return 330; // weak random + return CweNumber.WEAK_RANDOM; case "??3": - return 90; // LDAP injection + return CweNumber.LDAP_INJECTION; case "??4": - return 22; // path traversal case "??5": - return 22; // path traversal + return CweNumber.PATH_TRAVERSAL; case "??6": - return 327; // weak encryption + return CweNumber.WEAK_CRYPTO_ALGO; case "??7": - return 643; // xpath injection + return CweNumber.XPATH_INJECTION; case "??8": - return 328; // weak hash + return CweNumber.WEAK_HASH_ALGO; case "??9": - return 78; // command injection + return CweNumber.OS_COMMAND_INJECTION; case "??10": - return 79; // XSS + return CweNumber.XSS; - // FbInfer additional rules + // FbInfer additional rules case "RESOURCE_LEAK": case "NULL_DEREFERENCE": - return 0; + return CweNumber.DONTCARE; default: System.out.println("Unknown category: " + rule); } - return 0; + return CweNumber.DONTCARE; } } 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 9da70bc3..7560d0e2 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 @@ -158,13 +158,12 @@ private TestCaseResult parseFlowViol(Node flaw) { } // https://www.securecoding.cert.org/confluence/display/java/Parasoft - private int cweLookup(String cat) { - + private CweNumber cweLookup(String cat) { switch (cat) { // case "BD.PB.CC" : return x; // case "BD.RES.LEAKS" : return x; case "BD.SECURITY.TDCMD": - return CweNumber.COMMAND_INJECTION; + return CweNumber.OS_COMMAND_INJECTION; case "BD.SECURITY.TDFNAMES": return CweNumber.PATH_TRAVERSAL; case "BD.SECURITY.TDLDAP": @@ -193,6 +192,6 @@ private int cweLookup(String cat) { // case "Weak Cryptographic Hash" : return 328; // case "Weak Encryption" : return 327; } - return -1; + return CweNumber.DONTCARE; } } diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/QualysWASReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/QualysWASReader.java index 9eb65a5a..47ee1179 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/QualysWASReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/QualysWASReader.java @@ -19,6 +19,7 @@ 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; @@ -114,7 +115,7 @@ public TestSuiteResults parse(ResultFile resultFile) throws Exception { private TestCaseResult parseQualysVulnerability(Node issue) { TestCaseResult tcr = new TestCaseResult(); String cwe = getNamedChild("QID", issue).getTextContent(); - tcr.setCWE(translate_cwe(cwe)); + tcr.setCWE(translateCwe(cwe)); String name = getNamedChild("QID", issue).getTextContent(); tcr.setCategory(translate_name(name)); @@ -141,85 +142,85 @@ private TestCaseResult parseQualysVulnerability(Node issue) { return null; } - private int translate_cwe(String id) { + private CweNumber translateCwe(String id) { switch (id) { case "150001": - return 79; // Reflected Cross-Site Scripting (XSS) Vulnerabilities + return CweNumber.XSS; case "150003": - return 89; // SQL Injection - case "150009": - return 9999; // Links Crawled - case "150010": - return 9999; // External Links Discovered + return CweNumber.SQL_INJECTION; + case "150009": // Links Crawled + return CweNumber.DONTCARE; + case "150010": // External Links Discovered + return CweNumber.DONTCARE; case "150012": - return 89; // Blind SQL Injection - case "150018": - return 9999; // Connection Error Occurred During Web Application Scan - case "150021": - return 9999; // Scan Diagnostics + return CweNumber.SQL_INJECTION; + case "150018": // Connection Error Occurred During Web Application Scan + return CweNumber.DONTCARE; + case "150021": // Scan Diagnostics + return CweNumber.DONTCARE; case "150022": - return 209; // Verbose Error Message - case "150028": - return 9999; // Cookies Collected - case "150033": - return 9999; // Credit Card Number Pattern Identified In HTML - case "150042": - return 9999; // Server Returns HTTP 500 Message For Request - case "150046": - return 79; // Reflected Cross-Site Scripting (XSS) in HTTP Header - case "150054": - return 9999; // Email Addresses Collected - case "150055": - return 78; // PHP Command Injection - case "150079": - return 772; // Slow HTTP headers vulnerability - case "150081": - return 693; // X-Frame-Options header is not set - case "150084": - return 79; // Unencoded characters - case "150085": - return 772; // Slow HTTP POST vulnerability - case "150086": - return 9999; // Server accepts unnecessarily large POST request body - case "150104": - return 9999; // Form Contains Email Address Field - case "150115": - return 9999; // Authentication Form found - case "150122": - return 614; // Cookie Does Not Contain The "secure" Attribute - case "150123": - return 1004; // Cookie Does Not Contain The "HTTPOnly" Attribute - case "150124": - return 451; // Clickjacking - Framable Page - case "150126": - return 9999; // Links With High Resource Consumption - case "150135": - return 9999; // HTTP Strict Transport Security (HSTS) header missing/misconfigured. - case "150148": - return 9999; // AJAX Links Crawled - case "150152": - return 9999; // Forms Crawled - case "150162": - return 937; // Use of JavaScript Library with Known Vulnerability - case "150172": - return 9999; // Requests Crawled - case "150176": - return 9999; // JavaScript Libraries Detected - case "150202": - return 9999; // Missing header: X-Content-Type-Options - case "150204": - return 9999; // Missing header: X-XSS-Protection - case "150205": - return 9999; // Misconfigured header: X-XSS-Protection - case "150206": - return 9999; // Content-Security-Policy Not Implemented - case "150251": - return 643; // Blind XPath Injection + return CweNumber.ERROR_MESSAGE_WITH_SENSITIVE_INFO; + case "150028": // Cookies Collected + return CweNumber.DONTCARE; + case "150033": // Credit Card Number Pattern Identified In HTML + return CweNumber.DONTCARE; + case "150042": // Server Returns HTTP 500 Message For Request + return CweNumber.DONTCARE; + case "150046": // Reflected Cross-Site Scripting (XSS) in HTTP Header + return CweNumber.XSS; + case "150054": // Email Addresses Collected + return CweNumber.DONTCARE; + case "150055": // PHP Command Injection + return CweNumber.OS_COMMAND_INJECTION; + case "150079": // Slow HTTP headers vulnerability + return CweNumber.MISSING_RELEASE_OF_RESOURCE; + case "150081": // X-Frame-Options header is not set + return CweNumber.PROTECTION_MECHANISM_FAILURE; + case "150084": // Unencoded characters + return CweNumber.XSS; + case "150085": // Slow HTTP POST vulnerability + return CweNumber.MISSING_RELEASE_OF_RESOURCE; + case "150086": // Server accepts unnecessarily large POST request body + return CweNumber.DONTCARE; + case "150104": // Form Contains Email Address Field + return CweNumber.DONTCARE; + case "150115": // Authentication Form found + return CweNumber.DONTCARE; + case "150122": // Cookie Does Not Contain The "secure" Attribute + return CweNumber.INSECURE_COOKIE; + case "150123": // Cookie Does Not Contain The "HTTPOnly" Attribute + return CweNumber.COOKIE_WITHOUT_HTTPONLY; + case "150124": // Clickjacking - Framable Page + return CweNumber.MISREPRESENTATION_OF_CRITICAL_INFO; + case "150126": // Links With High Resource Consumption + return CweNumber.DONTCARE; + case "150135": // HTTP Strict Transport Security (HSTS) header missing/misconfigured. + return CweNumber.DONTCARE; + case "150148": // AJAX Links Crawled + return CweNumber.DONTCARE; + case "150152": // Forms Crawled + return CweNumber.DONTCARE; + case "150162": // Use of JavaScript Library with Known Vulnerability + return CweNumber.CATEGORY_OWASP_2013_A9; + case "150172": // Requests Crawled + return CweNumber.DONTCARE; + case "150176": // JavaScript Libraries Detected + return CweNumber.DONTCARE; + case "150202": // Missing header: X-Content-Type-Options + return CweNumber.DONTCARE; + case "150204": // Missing header: X-XSS-Protection + return CweNumber.DONTCARE; + case "150205": // Misconfigured header: X-XSS-Protection + return CweNumber.DONTCARE; + case "150206": // Content-Security-Policy Not Implemented + return CweNumber.DONTCARE; + case "150251": // Blind XPath Injection + return CweNumber.XPATH_INJECTION; case "123456": - return 6666; + return CweNumber.DONTCARE; } // end switch(id) System.out.println("Unknown id: " + id); - return -1; + return CweNumber.DONTCARE; } // Qualys does not provide the NAME of the vulnerabilities in the VULNERABILITY node. These are 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 ec376327..95843b6d 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 @@ -66,7 +66,7 @@ public TestSuiteResults parse(ResultFile resultFile) throws Exception { return tr; } - private int cweLookup(String cweNum, String evidence) { + private CweNumber cweLookup(String cweNum, String evidence) { int cwe = 0; if (cweNum != null && !cweNum.isEmpty()) { cwe = Integer.parseInt(cweNum); @@ -95,14 +95,14 @@ private int cweLookup(String cweNum, String evidence) { case "X-Content-Type-Options header not found": case "X-Frame-Options HTTP header checking": case "X-XSS-Protection header not found": - return 0; + return CweNumber.DONTCARE; default: { // If this prints out anything new, add to this mapping so we know it's // mapped properly. System.out.println( "Found new unmapped finding with evidence: " + evidence); - return 0; // In case they add any new mappings + return CweNumber.DONTCARE; // In case they add any new mappings } } case 79: @@ -143,7 +143,7 @@ private int cweLookup(String cweNum, String evidence) { // FP rate up 7.75% return CweNumber.SQL_INJECTION; } - return cwe; + return CweNumber.lookup(cwe); } @JsonIgnoreProperties(ignoreUnknown = true) 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 83639ca1..5330b220 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 @@ -21,6 +21,7 @@ import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVRecord; 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; @@ -33,7 +34,7 @@ public boolean canRead(ResultFile resultFile) { && resultFile.line(0).contains("Reshift Report"); } - private static int cweLookup(String checkerKey) { + private static CweNumber cweLookup(String checkerKey) { checkerKey = checkerKey.replace("-SECOND-ORDER", ""); switch (checkerKey) { @@ -41,38 +42,38 @@ private static int cweLookup(String checkerKey) { case "Path Traversal (Read)": case "Path Traversal (Relative)": case "Path Traversal (Write)": - return 22; // path traversal + return CweNumber.PATH_TRAVERSAL; case "SQL Injection (Hibernate)": case "SQL Injection (Java Database Connectivity)": case "SQL Injection (JDBC)": case "SQL Injection (Non-constant String)": case "SQL Injection (Prepared Statement)": - return 89; // sql injection + return CweNumber.SQL_INJECTION; case "Arbitrary Command Execution": - return 78; // command injection + return CweNumber.OS_COMMAND_INJECTION; case "XPath Injection": - return 643; // xpath injection + return CweNumber.XPATH_INJECTION; case "Cipher is Susceptible to Padding Oracle": case "Cipher With No Integrity": case "DES is Insecure": case "DESede is Insecure": case "Static IV": - return 327; // weak encryption + return CweNumber.WEAK_CRYPTO_ALGO; case "MD2, MD4 and MD5 Are Weak Hash Functions": case "SHA-1 is a Weak Hash Function": - return 328; // weak hash + return CweNumber.WEAK_HASH_ALGO; case "LDAP Injection": - return 90; // ldap injection + return CweNumber.LDAP_INJECTION; case "Cross-Site Scripting (XSS-Servlet Output)": - return 79; // xss + return CweNumber.XSS; default: System.out.println( "WARNING: Unmapped Vulnerability category detected: " + checkerKey); } - return 0; + return CweNumber.DONTCARE; } @Override @@ -122,7 +123,7 @@ public TestSuiteResults parse(ResultFile resultFile) throws Exception { url.substring( testCaseNumStart, testCaseNumStart + BenchmarkScore.TESTIDLENGTH))); - if (tcr.getCWE() != 0) { + if (!CweNumber.DONTCARE.equals(tcr.getCWE())) { tr.put(tcr); } } 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 4c9e4b71..ed73cb20 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 @@ -19,6 +19,7 @@ import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVRecord; +import org.owasp.benchmarkutils.score.CweNumber; import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; @@ -53,7 +54,7 @@ public TestSuiteResults parse(ResultFile resultFile) throws Exception { System.out.println("> Parse error: " + record.toString()); } - if (tcr.getCWE() != 0) { + if (!CweNumber.DONTCARE.equals(tcr.getCWE())) { tr.put(tcr); } } @@ -63,53 +64,53 @@ public TestSuiteResults parse(ResultFile resultFile) throws Exception { return tr; } - private int cweLookup(String checkerKey) { + private CweNumber cweLookup(String checkerKey) { checkerKey = checkerKey.replace("-SECOND-ORDER", ""); switch (checkerKey) { case "COOK-SEC": - return 614; // insecure cookie use + return CweNumber.INSECURE_COOKIE; case "SQLI": - return 89; // sql injection + return CweNumber.SQL_INJECTION; case "CMD-INJECT": - return 78; // command injection + return CweNumber.OS_COMMAND_INJECTION; case "LDAP-INJECTION": - return 90; // ldap injection + return CweNumber.LDAP_INJECTION; case "header-injection": - return 113; // header injection + return CweNumber.HTTP_RESPONSE_SPLITTING; case "hql-injection": - return 564; // hql injection + return CweNumber.HIBERNATE_INJECTION; case "unsafe-readline": - return 0000; // unsafe readline + return CweNumber.DONTCARE; case "reflection-injection": - return 0000; // reflection injection + return CweNumber.DONTCARE; case "R-XSS": - return 79; // XSS + return CweNumber.XSS; case "XPATH-INJECT": - return 643; // XPath injection + return CweNumber.XPATH_INJECTION; case "DIR-TRAVERSAL": - return 22; // path traversal + return CweNumber.PATH_TRAVERSAL; case "crypto-bad-mac": - return 328; // weak hash + return CweNumber.WEAK_HASH_ALGO; case "crypto-weak-randomness": - return 330; // weak random + return CweNumber.WEAK_RANDOM; case "WEAK-ENC": - return 327; // weak encryption + return CweNumber.WEAK_CRYPTO_ALGO; case "trust-boundary-violation": - return 501; // trust boundary + return CweNumber.TRUST_BOUNDARY_VIOLATION; case "xxe": - return 611; // XML Entity Injection + return CweNumber.XXE; case "WEAK-HASH": - return 328; + return CweNumber.WEAK_HASH_ALGO; case "WEAK-RANDOM-GENERATOR": - return 330; + return CweNumber.WEAK_RANDOM; case "TRUST-BOUNDARY-VIOLATION": - return 501; + return CweNumber.TRUST_BOUNDARY_VIOLATION; default: System.out.println( "WARNING: Unmapped Vulnerability category detected: " + checkerKey); } - return 0; + return CweNumber.DONTCARE; } } 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 1edfa797..012cbf77 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 @@ -41,9 +41,6 @@ public TestSuiteResults parse(ResultFile resultFile) throws Exception { JSONArray results = resultFile.json().getJSONArray("results"); - // engine version - // duration time - // results for (int i = 0; i < results.length(); i++) { TestCaseResult tcr = parseSemgrepFindings(results.getJSONObject(i)); @@ -54,153 +51,25 @@ public TestSuiteResults parse(ResultFile resultFile) throws Exception { return tr; } - private int translate(int cwe) { - + /** + * Maps detected CWE number to one that BenchmarkScore expects. + * + * @param cwe reported CWE number + * @return fixed (or same) CWE number + */ + private CweNumber translate(int cwe) { switch (cwe) { - case 113: // Header injection; - case 200: // Information Leak / Disclosure; - case 276: // Incorrect Default Permissions; - case 352: // CSRF; - case 489: // Active Debug Code; - break; // Don't care - So return CWE 'as is' - - case 22: - return CweNumber.PATH_TRAVERSAL; - case 78: - return CweNumber.COMMAND_INJECTION; - case 79: - return CweNumber.XSS; - case 89: - return CweNumber.SQL_INJECTION; - case 90: - return CweNumber.LDAP_INJECTION; case 326: - case 327: case 696: // Incorrect Behavior Order - return CweNumber.WEAK_CRYPTO_ALGO; // weak encryption - case 328: - return CweNumber.WEAK_HASH_ALGO; - case 330: - return CweNumber.WEAK_RANDOM; - case 501: - return CweNumber.TRUST_BOUNDARY_VIOLATION; - case 614: + return CweNumber.WEAK_CRYPTO_ALGO; case 1004: return CweNumber.INSECURE_COOKIE; - case 643: - return CweNumber.XPATH_INJECTION; - default: - System.out.println( - "INFO: Found following CWE in SemGrep results which we haven't seen before: " - + cwe); } - return cwe; + + return CweNumber.lookup(cwe); } private TestCaseResult parseSemgrepFindings(JSONObject result) { - /* - { - "check_id": "java.lang.security.audit.formatted-sql-string.formatted-sql-string", - "path": "src/main/java/org/owasp/benchmark/testcode/BenchmarkTest02738.java", - "start": { - "line": 48, - "col": 3 - }, - "end": { - "line": 62, - "col": 4 - }, - "extra": { - "message": "Detected a formatted string in a SQL statement. This could lead to SQL\ninjection if variables in the SQL statement are not properly sanitized.\nUse a prepared statements (java.sql.PreparedStatement) instead. You\ncan obtain a PreparedStatement using 'connection.prepareStatement'.\n", - "metavars": { - "$W": { - "start": { - "line": 52, - "col": 4, - "offset": 2060 - }, - "end": { - "line": 52, - "col": 13, - "offset": 2069 - }, - "abstract_content": "statement", - "unique_id": { - "type": "id", - "value": "statement", - "kind": "Local", - "sid": 16 - } - }, - "$Y": { - "start": { - "line": 48, - "col": 80, - "offset": 1938 - }, - "end": { - "line": 48, - "col": 83, - "offset": 1941 - }, - "abstract_content": "\"'\"", - "unique_id": { - "type": "AST", - "md5sum": "a49ef1cc4c90797113e4bfc4fea284c2" - } - }, - "$X": { - "start": { - "line": 48, - "col": 16, - "offset": 1874 - }, - "end": { - "line": 48, - "col": 78, - "offset": 1936 - }, - "abstract_content": "\"SELECT * from USERS where USERNAME='foo' and PASSWORD='\"+bar", - "unique_id": { - "type": "AST", - "md5sum": "c06a8ea6cc3be92766bd8a358308b20a" - } - }, - "$SQL": { - "start": { - "line": 48, - "col": 10, - "offset": 1868 - }, - "end": { - "line": 48, - "col": 13, - "offset": 1871 - }, - "abstract_content": "sql", - "unique_id": { - "type": "id", - "value": "sql", - "kind": "Local", - "sid": 15 - } - } - }, - "metadata": { - "cwe": "CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')", - "owasp": "A1: Injection", - "source-rule-url": "https://find-sec-bugs.github.io/bugs.htm#SQL_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" - ] - }, - "severity": "WARNING", - "lines": "\t\tString sql = \"SELECT * from USERS where USERNAME='foo' and PASSWORD='\"+ bar +\"'\";\n\t\t\t\t\n\t\ttry {\n\t\t\tjava.sql.Statement statement = org.owasp.benchmark.helpers.DatabaseHelper.getSqlStatement();\n\t\t\tstatement.execute( sql );\n org.owasp.benchmark.helpers.DatabaseHelper.printResults(statement, sql, response);\n\t\t} catch (java.sql.SQLException e) {\n\t\t\tif (org.owasp.benchmark.helpers.DatabaseHelper.hideSQLErrors) {\n \t\tresponse.getWriter().println(\n\"Error processing request.\"\n);\n \t\treturn;\n \t}\n\t\t\telse throw new ServletException(e);\n\t\t}" - } - } - */ try { String className = result.getString("path"); className = (className.substring(className.lastIndexOf('/') + 1)).split("\\.")[0]; @@ -213,10 +82,10 @@ private TestCaseResult parseSemgrepFindings(JSONObject result) { // CWE String cweString = getStringOrFirstArrayIndex(metadata, "cwe"); - int cwe = Integer.parseInt(cweString.split(":")[0].split("-")[1]); - + CweNumber cwe = CweNumber.DONTCARE; try { - cwe = translate(cwe); + int cweNumber = Integer.parseInt(cweString.split(":")[0].split("-")[1]); + cwe = translate(cweNumber); } catch (NumberFormatException ex) { System.out.println("CWE # not parseable from: " + metadata.getString("cwe")); } 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 5ef5ad46..ef275c36 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 @@ -19,6 +19,7 @@ import java.io.BufferedReader; import java.io.FileReader; +import org.owasp.benchmarkutils.score.CweNumber; import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; @@ -67,30 +68,30 @@ public TestSuiteResults parse(ResultFile resultFile) throws Exception { return tr; } - private int categoryToCWE(String category) { + private CweNumber categoryToCWE(String category) { switch (category) { case "cmdi": - return 78; + return CweNumber.OS_COMMAND_INJECTION; case "crypto": - return 327; + return CweNumber.WEAK_CRYPTO_ALGO; case "hash": - return 328; + return CweNumber.WEAK_HASH_ALGO; case "ldapi": - return 90; + return CweNumber.LDAP_INJECTION; case "pathtraver": - return 22; + return CweNumber.PATH_TRAVERSAL; case "securecookie": - return 614; + return CweNumber.INSECURE_COOKIE; case "sqli": - return 89; + return CweNumber.SQL_INJECTION; case "trustbound": - return 501; + return CweNumber.TRUST_BOUNDARY_VIOLATION; case "weakrand": - return 330; + return CweNumber.WEAK_RANDOM; case "xpathi": - return 643; + return CweNumber.XPATH_INJECTION; case "xss": - return 79; + return CweNumber.XSS; default: throw new RuntimeException("Unknown category: " + category); } 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 941b5fb9..df53f718 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,6 +25,7 @@ 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; @@ -108,7 +109,7 @@ private String filename(JSONObject finding) { .getName(); } - private int cweNumber(JSONObject finding) { + private CweNumber cweNumber(JSONObject finding) { String ruleId = finding.getString("ruleId"); switch (ruleId) { @@ -116,47 +117,48 @@ private int cweNumber(JSONObject finding) { case "PATH_TRAVERSAL_OUT": case "PT_RELATIVE_PATH_TRAVERSAL": case "PT_ABSOLUTE_PATH_TRAVERSAL": - return 22; + return CweNumber.PATH_TRAVERSAL; case "COMMAND_INJECTION": - return 78; + return CweNumber.OS_COMMAND_INJECTION; case "HTTP_RESPONSE_SPLITTING": - return 113; + return CweNumber.HTTP_RESPONSE_SPLITTING; case "XSS_SERVLET": case "HRS_REQUEST_PARAMETER_TO_COOKIE": case "XSS_REQUEST_PARAMETER_TO_SERVLET_WRITER": - return 79; + return CweNumber.XSS; case "SQL_INJECTION_JDBC": case "SQL_INJECTION_SPRING_JDBC": case "SQL_NONCONSTANT_STRING_PASSED_TO_EXECUTE": case "SQL_PREPARED_STATEMENT_GENERATED_FROM_NONCONSTANT_STRING": - return 89; + return CweNumber.SQL_INJECTION; case "LDAP_INJECTION": - return 90; + return CweNumber.LDAP_INJECTION; case "PADDING_ORACLE": - return 209; + // FIXME: shouldn't this be 463? + return CweNumber.ERROR_MESSAGE_WITH_SENSITIVE_INFO; case "DES_USAGE": case "CIPHER_INTEGRITY": - return 327; + return CweNumber.WEAK_CRYPTO_ALGO; case "WEAK_MESSAGE_DIGEST_MD5": case "WEAK_MESSAGE_DIGEST_SHA1": - return 328; + return CweNumber.WEAK_HASH_ALGO; case "STATIC_IV": - return 329; + return CweNumber.STATIC_CRYPTO_INIT; case "PREDICTABLE_RANDOM": - return 330; + return CweNumber.WEAK_RANDOM; case "TRUST_BOUNDARY_VIOLATION": - return 501; + return CweNumber.TRUST_BOUNDARY_VIOLATION; case "HTTPONLY_COOKIE": - return 1004; + return CweNumber.COOKIE_WITHOUT_HTTPONLY; case "INSECURE_COOKIE": - return 614; + return CweNumber.INSECURE_COOKIE; case "XPATH_INJECTION": - return 643; + return CweNumber.XPATH_INJECTION; default: System.out.println( "INFO: Found following ruleId which we haven't seen before: " + ruleId); - return -1; + return CweNumber.DONTCARE; } } } 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 36aec08a..e5b49252 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,6 +22,7 @@ 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; @@ -78,14 +79,14 @@ public TestSuiteResults parse(ResultFile resultFile) throws Exception { List vulnerabilities = getNamedChildren("Vulnerability", vulnCollect); for (Node vulnerability : vulnerabilities) { String cweNum = getAttributeValue("CWE", vulnerability); - int findingCWE = cweLookup(cweNum); + CweNumber findingCWE = cweLookup(cweNum); // There is a single FindingsList per Vulnerability category Node findingsList = getNamedChild("FindingsList", vulnerability); List findings = getNamedChildren("Finding", findingsList); for (Node finding : findings) { String filename = getAttributeValue("FileName", finding); String findingName = filename.substring(0, filename.indexOf(".")); - if (findingCWE != 0) { + if (!CweNumber.DONTCARE.equals(findingCWE)) { int testNumber = extractTestNumber(findingName); if (testNumber != -1) { TestCaseResult tcr = new TestCaseResult(); @@ -115,40 +116,17 @@ private int extractTestNumber(String testfile) { return -1; } - private int cweLookup(String checkerKey) { - switch (checkerKey.trim()) { - case "1004": - return 614; // HTTPOnly Flag Not Set For Cookies:insecure cookie use - case "614": - return 614; // Cookie not Sent Over SSL:insecure cookie use - case "78": - return 78; // command injection - case "89": - return 89; // SQL injection - case "755": - return 755; // SQL Exception Vulnerability:Info Leak + private CweNumber cweLookup(String checkerKey) { + String cwe = checkerKey.trim(); + + switch (cwe) { case "258": - return 000; // "Use an empty string as a password" - case "20": - return 20; // "Input Validation Issue or Input Validation Required" - case "79": - return 79; // Malicious Scripting Attacks and xss + return CweNumber.DONTCARE; case "73": - return 22; // Path Manipulation: path traversal case "538": - return 22; // File Disclosure Vulnerability:path traversal - case "330": - return 330; // Use of java.util.Random generator function:weak random - case "327": - return 327; // Broken Cryptography or - // Weak Encryption Insecure Mode of Operation:weak encryption - case "328": - return 328; // Broken Hashing algorithm - default: - System.out.println( - "Found unrecognized vulnerability type in Snappy Tick results: " - + checkerKey); + return CweNumber.PATH_TRAVERSAL; } - return 0; + + return CweNumber.lookup(checkerKey.trim()); } } 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 f0a29e07..2dea2342 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 @@ -127,7 +127,7 @@ private TestCaseResult parseSonarQubeQualityIssue(JSONObject finding) { if (squid == null || squid.equals("none")) { return null; } - int cwe = SonarQubeReader.cweLookup(squid); + CweNumber cwe = SonarQubeReader.cweLookup(squid); tcr.setCWE(cwe); tcr.setCategory(finding.getJSONArray("tags").toString()); tcr.setEvidence(finding.getString("message")); @@ -176,7 +176,7 @@ private TestCaseResult parseSonarQubeHotSpotIssue(JSONObject finding) { if (secCat == null || secCat.equals("none")) { return null; } - int cwe = securityCategoryCWELookup(secCat, finding.getString("message")); + CweNumber cwe = securityCategoryCWELookup(secCat, finding.getString("message")); tcr.setCWE(cwe); tcr.setCategory(secCat); tcr.setEvidence( @@ -200,7 +200,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 int securityCategoryCWELookup(String secCat, String message) { + public CweNumber securityCategoryCWELookup(String secCat, String message) { // Not sure where to look up all the possible security categories in SonarQube, but the // mappings seem obvious enough. @@ -270,7 +270,7 @@ public int securityCategoryCWELookup(String secCat, String message) { + "'"); } - return -1; + return CweNumber.DONTCARE; } // This parser relies on the SQUID # mapping method in SonarQubeReader.cweLookup() 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 25b34760..f5b32376 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 @@ -175,7 +175,7 @@ private TestCaseResult parseSonarPluginIssue(Node flaw) { // case "Weak Encryption" : return 327; // case "XPath Injection" : return 643; - public static int cweLookup(String squidNumber) { + public static CweNumber cweLookup(String squidNumber) { // To look up these #'s, go here: https://rules.sonarsource.com/java/RSPEC-#### and put just // the #'s with no leading zeroes to look up the 'squid' rule. switch (squidNumber) { @@ -210,340 +210,269 @@ public static int cweLookup(String squidNumber) { case "S135": // Loops should not contain more than a single "break" or "continue" // statement return CweNumber.DONTCARE; - case "S864": - return CweNumber - .OPERATOR_PRECEDENCE_LOGIC; // Limited dependence should be placed on - // operator precedence rules in expressions - case "S888": - return CweNumber - .LOOP_WITH_UNREACHABLE_EXIT; // Relational operators should be used in "for" - // loop termination conditions - case "S899": - return CweNumber - .IMPROPER_CHECK_FOR_CONDITIONS; // Return values should not be ignored when - // they contain the operation status code - case "S1066": - return CweNumber.DONTCARE; // Collapsible "if" statements should be merged - case "S1075": - return CweNumber.DONTCARE; // URIs should not be hardcoded + case "S864": // Limited dependence should be placed on operator precedence rules in + // expressions + return CweNumber.OPERATOR_PRECEDENCE_LOGIC; + case "S888": // Relational operators should be used in "for" loop termination conditions + return CweNumber.LOOP_WITH_UNREACHABLE_EXIT; + case "S899": // Return values should not be ignored when they contain the operation + // status code + return CweNumber.IMPROPER_CHECK_FOR_CONDITIONS; + case "S1066": // Collapsible "if" statements should be merged + return CweNumber.DONTCARE; + case "S1075": // URIs should not be hardcoded + return CweNumber.DONTCARE; case "S1104": // Class variable fields should not have public accessibility return CweNumber.PUBLIC_VAR_WITHOUT_FINAL; - case "S1116": - return CweNumber.DONTCARE; // Empty statements should be removed - case "S1117": - return CweNumber.DONTCARE; // Local variables should not shadow class fields - case "S1118": - return CweNumber.DONTCARE; // Utility classes should not have public constructors - case "S1128": - return CweNumber.DONTCARE; // Unnecessary imports should be removed - case "S1130": - return CweNumber.DONTCARE; // "throws" declarations should not be superfluous - case "S1132": - return CweNumber - .DONTCARE; // Strings literals should be placed on the left side when - // checking for + case "S1116": // Empty statements should be removed + return CweNumber.DONTCARE; + case "S1117": // Local variables should not shadow class fields + return CweNumber.DONTCARE; + case "S1118": // Utility classes should not have public constructors + return CweNumber.DONTCARE; + case "S1128": // Unnecessary imports should be removed + return CweNumber.DONTCARE; + case "S1130": // "throws" declarations should not be superfluous + return CweNumber.DONTCARE; + case "S1132": // Strings literals should be placed on the left side when checking for // equality - case "S1134": - return CweNumber.DONTCARE; // Track uses of "FIXME" tags - case "S1135": - return CweNumber.DONTCARE; // Track uses of "TODO" tags - case "S1141": - return CweNumber.DONTCARE; // Try-catch blocks should not be nested - case "S1143": - return CweNumber.RETURN_INSIDE_FINALLY; // "return " statements should not occur in - // "finally" blocks - case "S1144": - return CweNumber.DONTCARE; // Unused "private" methods should be removed - case "S1145": - return CweNumber - .DONTCARE; // "if" statement conditions should not unconditionally evaluate - // to"true" or to"false" - case "S1147": - return CweNumber.SYSTEM_EXIT; // Exit methods should not be called - case "S1149": - return CweNumber - .DONTCARE; // Synchronized classes Vector, Hashtable, Stack and StringBuffer - // should not be used - case "S1155": - return CweNumber - .DONTCARE; // Collection.isEmpty() should be used to test for emptiness - case "S1161": - return CweNumber - .DONTCARE; // "@Override" should be used on overriding and implementing - // methods - case "S1163": - return CweNumber.DONTCARE; // Exceptions should not be thrown in finally blocks - case "S1168": - return CweNumber - .DONTCARE; // Empty arrays and collections should be returned instead of - // null - case "S1171": - return CweNumber.DONTCARE; // Only static class initializers should be used - case "S1172": - return CweNumber.DONTCARE; // Unused method parameters should be removed - case "S1174": - return CweNumber - .FINALIZE_DECLARED_PUBLIC; // "Object.finalize()" should remain protected + return CweNumber.DONTCARE; + case "S1134": // Track uses of "FIXME" tags + return CweNumber.DONTCARE; + case "S1135": // Track uses of "TODO" tags + return CweNumber.DONTCARE; + case "S1141": // Try-catch blocks should not be nested + return CweNumber.DONTCARE; + case "S1143": // "return " statements should not occur in "finally" blocks + return CweNumber.RETURN_INSIDE_FINALLY; + case "S1144": // Unused "private" methods should be removed + return CweNumber.DONTCARE; + case "S1145": // "if" statement conditions should not unconditionally evaluate to"true" + // or to"false" + return CweNumber.DONTCARE; + case "S1147": // Exit methods should not be called + return CweNumber.SYSTEM_EXIT; + case "S1149": // Synchronized classes Vector, Hashtable, Stack and StringBuffer should + // not be used + return CweNumber.DONTCARE; + case "S1155": // Collection.isEmpty() should be used to test for emptiness + return CweNumber.DONTCARE; + case "S1161": // "@Override" should be used on overriding and implementing methods + return CweNumber.DONTCARE; + case "S1163": // Exceptions should not be thrown in finally blocks + return CweNumber.DONTCARE; + case "S1168": // Empty arrays and collections should be returned instead of null + return CweNumber.DONTCARE; + case "S1171": // Only static class initializers should be used + return CweNumber.DONTCARE; + case "S1172": // Unused method parameters should be removed + return CweNumber.DONTCARE; + case "S1174": // "Object.finalize()" should remain protected // (versus public) when overriding - case "S1181": - return CweNumber - .CATCH_GENERIC_EXCEPTION; // Throwable and Error should not be caught - case "S1182": - return CweNumber - .CLONE_WITHOUT_SUPER_CLONE; // Classes that override "clone" should be - // "Cloneable" and call "super.clone()" - case "S1186": - return CweNumber.DONTCARE; // Methods should not be empty - case "S1192": - return CweNumber.DONTCARE; // String literals should not be duplicated - case "S1197": - return CweNumber - .DONTCARE; // Array designators "[]" should be on the type, not the variable - case "S1199": - return CweNumber.DONTCARE; // Nested code blocks should not be used - case "S1206": - return CweNumber - .OBJECT_MODEL_VIOLATION; // "equals(Object obj)" and"hashCode()" should be - // overridden in pairs - case "S1210": - return CweNumber - .DONTCARE; // "equals(Object obj)" should be overridden along with the - // "compareTo(T obj)" method + return CweNumber.FINALIZE_DECLARED_PUBLIC; + case "S1181": // Throwable and Error should not be caught + return CweNumber.CATCH_GENERIC_EXCEPTION; + case "S1182": // Classes that override "clone" should be "Cloneable" and call + // "super.clone()" + return CweNumber.CLONE_WITHOUT_SUPER_CLONE; + case "S1186": // Methods should not be empty + return CweNumber.DONTCARE; + case "S1192": // String literals should not be duplicated + return CweNumber.DONTCARE; + case "S1197": // Array designators "[]" should be on the type, not the variable + return CweNumber.DONTCARE; + case "S1199": // Nested code blocks should not be used + return CweNumber.DONTCARE; + case "S1206": // "equals(Object obj)" and"hashCode()" should be overridden in pairs + return CweNumber.OBJECT_MODEL_VIOLATION; + case "S1210": // "equals(Object obj)" should be overridden along with the "compareTo(T + // obj)" method + return CweNumber.DONTCARE; case "S1217": // Thread.run() and Runnable.run() should not be called directly return CweNumber.THREAD_WRONG_CALL; - case "S1301": - return CweNumber - .DONTCARE; // "switch" statements should have at least 3 "case" clauses - case "S1481": - return CweNumber.DONTCARE; // Remove this unused "c" local variable. - case "S1444": - return CweNumber.PUBLIC_STATIC_NOT_FINAL; // "public static" fields should always be + case "S1301": // "switch" statements should have at least 3 "case" clauses + return CweNumber.DONTCARE; + case "S1481": // Remove this unused "c" local variable. + return CweNumber.DONTCARE; + case "S1444": // "public static" fields should always be + return CweNumber.PUBLIC_STATIC_NOT_FINAL; // constant - case "S1479": - return CweNumber - .DONTCARE; // "switch" statements should not have too many "case" clauses - case "S1488": - return CweNumber - .DONTCARE; // Local variables should not be declared and then immediately - // returned - // or thrown - case "S1643": - return CweNumber.DONTCARE; // Strings should not be concatenated using '+' in a loop - case "S1659": - return CweNumber - .DONTCARE; // Multiple variables should not be declared on the same line + case "S1479": // "switch" statements should not have too many "case" clauses + return CweNumber.DONTCARE; + case "S1488": // Local variables should not be declared and then immediately returned or + // thrown + return CweNumber.DONTCARE; + case "S1643": // Strings should not be concatenated using '+' in a loop + return CweNumber.DONTCARE; + case "S1659": // Multiple variables should not be declared on the same line + return CweNumber.DONTCARE; case "S1696": // "NullPointerException" should not be caught return CweNumber.CATCHING_NULL_POINTER_EXCEPTION; - case "S1698": - return CweNumber - .OBJECT_REFERENCE_COMPARISON; // Objects should be compared with"equals()" - case "S1724": - return CweNumber.DONTCARE; // Deprecated classes and interfaces should not be - // extended/implemented - case "S1850": - return CweNumber - .DONTCARE; // "instanceof" operators that always return "true" or"false" - // should be + case "S1698": // Objects should be compared with"equals()" + return CweNumber.OBJECT_REFERENCE_COMPARISON; + case "S1724": // Deprecated classes and interfaces should not be extended/implemented + return CweNumber.DONTCARE; + case "S1850": // "instanceof" operators that always return "true" or"false" should be // removed - case "S1854": - 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 CweNumber.DONTCARE; // "@Deprecated" code should not be used - case "S1905": - return CweNumber.DONTCARE; // Redundant casts should not be used - case "S1948": - return 594; // Fields in a"Serializable" class should either be transient or + return CweNumber.DONTCARE; + case "S1854": // Unused assignments should be removed + return CweNumber.UNUSED_VAR_ASSIGNMENT; + case "S1872": // Classes should not be compared by name + return CweNumber.COMPARISON_BY_CLASS_NAME; + case "S1873": // "static final" arrays should be"private" + return CweNumber.STATIC_FINAL_ARRAY_IS_PUBLIC; + case "S1874": // "@Deprecated" code should not be used + return CweNumber.DONTCARE; + case "S1905": // Redundant casts should not be used + return CweNumber.DONTCARE; + case "S1948": // Fields in a"Serializable" class should either be transient or // serializable - case "S1989": - return 600; // Exceptions should not be thrown from servlet methods - case "S2068": - return 259; // Credentials should not be hard-coded - case "S2070": - return CweNumber.WEAK_HASH_ALGO; // Benchmark Vuln: SHACweNumber.DONTCARE and - // Message-Digest hash + return CweNumber.SAVING_UNSERIALIZABLE_OBJECT_TO_DISK; + case "S1989": // Exceptions should not be thrown from servlet methods + return CweNumber.UNCAUGHT_EXCEPTION_IN_SERVLET; + case "S2068": // Credentials should not be hard-coded + return CweNumber.HARDCODED_PASSWORD; + case "S2070": // Benchmark Vuln: SHACweNumber.DONTCARE and Message-Digest hash // algorithms should not be used - case "S2076": - return CweNumber - .COMMAND_INJECTION; // Benchmark Vuln: Values passed to OS commands should - // be sanitized - case "S2077": - return CweNumber - .SQL_INJECTION; // Benchmark Vuln: Values passed to SQL commands should be - // sanitized - case "S2078": - return CweNumber - .LDAP_INJECTION; // Benchmark Vuln: Values passed to LDAP queries should be - // sanitized - case "S2083": - 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 CweNumber.XPATH_INJECTION; // Benchmark Vuln: XPath expressions should not be - // vulnerable to injection attacks - case "S2092": - return CweNumber.INSECURE_COOKIE; // Benchmark Vuln: Cookies should be "secure" - case "S2093": - return CweNumber.DONTCARE; // Try-with-resources should be used - case "S2095": - return 459; // Resources should be closed - case "S2115": - return 521; // Secure password should be used when connecting to a database - case "S2130": - return CweNumber - .DONTCARE; // Parsing should be used to convert "Strings" to primitives - case "S2147": - return CweNumber.DONTCARE; // Catches should be combined - case "S2157": - return CweNumber.DONTCARE; // "Cloneables" should implement "clone" - case "S2160": - return CweNumber.DONTCARE; // Subclasses that add fields should override "equals" - case "S2176": - return CweNumber - .DONTCARE; // Class names should not shadow interfaces or superclasses - case "S2178": - return CweNumber.DONTCARE; // Short-circuit logic should be used in boolean contexts - case "S2184": - return 190; // Math operands should be cast before assignment - case "S2222": - return 459; // Locks should be released - case "S2225": - return 476; // "toString()" and"clone()" methods should not return null - case "S2245": - return CweNumber - .WEAK_RANDOM; // Benchmark Vuln: Pseudorandom number generators (PRNGs) - // should not be used in secure contexts - case "S2254": - return CweNumber - .DONTCARE; // "HttpServletRequest.getRequestedSessionId()" should not be - // used - case "S2257": - return CweNumber - .WEAK_CRYPTO_ALGO; // Benchmark Vuln: Only standard cryptographic algorithms - // should be used - case "S2259": - return 476; // Null pointers should not be dereferenced - case "S2275": - return CweNumber - .DONTCARE; // Printf-style format strings should not lead to unexpected - // behavior - // at runtime - case "S2277": - return 780; // Cryptographic RSA algorithms should always incorporate OAEP (Optimal + return CweNumber.WEAK_HASH_ALGO; + case "S2076": // Benchmark Vuln: Values passed to OS commands should be sanitized + return CweNumber.OS_COMMAND_INJECTION; + case "S2077": // Benchmark Vuln: Values passed to SQL commands should be sanitized + return CweNumber.SQL_INJECTION; + case "S2078": // Benchmark Vuln: Values passed to LDAP queries should be sanitized + return CweNumber.LDAP_INJECTION; + case "S2083": // Benchmark Vuln: I/O function calls should not be vulnerable to path + // injection attacks + return CweNumber.PATH_TRAVERSAL; + case "S2089": // HTTP referers should not be relied on + return CweNumber.REFERER_FIELD_IN_AUTHENTICATION; + case "S2091": // Benchmark Vuln: XPath expressions should not be vulnerable to injection + // attacks + return CweNumber.XPATH_INJECTION; + case "S2092": // Benchmark Vuln: Cookies should be "secure" + return CweNumber.INSECURE_COOKIE; + case "S2093": // Try-with-resources should be used + return CweNumber.DONTCARE; + case "S2095": // Resources should be closed + return CweNumber.INCOMPLETE_CLEANUP; + case "S2115": // Secure password should be used when connecting to a database + return CweNumber.WEAK_PASSWORD_REQUIREMENTS; + case "S2130": // Parsing should be used to convert "Strings" to primitives + return CweNumber.DONTCARE; + case "S2147": // Catches should be combined + return CweNumber.DONTCARE; + case "S2157": // "Cloneables" should implement "clone" + return CweNumber.DONTCARE; + case "S2160": // Subclasses that add fields should override "equals" + return CweNumber.DONTCARE; + case "S2176": // Class names should not shadow interfaces or superclasses + return CweNumber.DONTCARE; + case "S2178": // Short-circuit logic should be used in boolean contexts + return CweNumber.DONTCARE; + case "S2184": // Math operands should be cast before assignment + return CweNumber.INTEGER_OVERFLOW_WRAPAROUND; + case "S2222": // Locks should be released + return CweNumber.INCOMPLETE_CLEANUP; + case "S2225": // "toString()" and"clone()" methods should not return null + return CweNumber.NULL_POINTER_DEREFERENCE; + case "S2245": // Benchmark Vuln: Pseudorandom number generators (PRNGs) should not be + // used in secure contexts + return CweNumber.WEAK_RANDOM; + case "S2254": // "HttpServletRequest.getRequestedSessionId()" should not be used + return CweNumber.DONTCARE; + case "S2257": // Benchmark Vuln: Only standard cryptographic algorithms should be used + return CweNumber.WEAK_CRYPTO_ALGO; + case "S2259": // Null pointers should not be dereferenced + return CweNumber.NULL_POINTER_DEREFERENCE; + case "S2275": // Printf-style format strings should not lead to unexpected behavior at + // runtime + return CweNumber.DONTCARE; + case "S2277": // Cryptographic RSA algorithms should always incorporate OAEP (Optimal // Asymmetric Encryption Padding) - case "S2278": - return CweNumber - .WEAK_CRYPTO_ALGO; // Benchmark Vuln: DES (Data Encryption Standard) and - // DESede - // (3DES) should not be used - case "S2293": - return CweNumber.DONTCARE; // The diamond operator ("<>") should be used - case "S2384": - return 374; // Mutable members should not be stored or returned directly - case "S2386": - return 607; // Mutable fields should not be "public static" - case "S2441": - return 579; // Non-serializable objects should not be stored in"HttpSessions" - case "S2479": - return CweNumber - .DONTCARE; // 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 CweNumber - .DONTCARE; // Boolean expressions should not be gratuitous - CWEs: 570/571 - case "S2658": - return 470; // Use of Externally-Controlled Input to Select Classes or Code ('Unsafe + return CweNumber.RSA_MISSING_PADDING; + case "S2278": // Benchmark Vuln: DES (Data Encryption Standard) and DESede (3DES) should + // not be used + return CweNumber.WEAK_CRYPTO_ALGO; + case "S2293": // The diamond operator ("<>") should be used + return CweNumber.DONTCARE; + case "S2384": // Mutable members should not be stored or returned directly + return CweNumber.PASS_MUTABLE_OBJECT_TO_UNTRUSTED_MODULE; + case "S2386": // Mutable fields should not be "public static" + return CweNumber.PUBLIC_STATIC_FINAL_MUTABLE_OBJECT; + case "S2441": // Non-serializable objects should not be stored in"HttpSessions" + return CweNumber.NON_SERIALIZABLE_OBJECT_IN_SESSION; + case "S2479": // Whitespace and control characters in literals should be explicit + return CweNumber.DONTCARE; + case "S2583": // Conditions should not unconditionally evaluate to"TRUE" or to"FALSE" + return CweNumber.ACTIVE_DEBUG_CODE; + case "S2589": // Boolean expressions should not be gratuitous - CWEs: 570/571 + return CweNumber.DONTCARE; + case "S2658": // Use of Externally-Controlled Input to Select Classes or Code ('Unsafe // Reflection') - case "S2677": - return CweNumber.DONTCARE; // "read" and "readLine" return values should be used - case "S2681": - return 483; // Multiline blocks should be enclosed in curly braces - case "S2696": - return CweNumber.DONTCARE; // Instance methods should not write to "static" fields - case "S2755": - return CweNumber.XXE; // XML parsers should not be vulnerable to XXE attacks - case "S2786": - return CweNumber.DONTCARE; // Nested "enum"s should not be declared static - case "S2864": - return CweNumber - .DONTCARE; // "entrySet()" should be iterated when both the key and value - // are - // needed - case "S3008": - return CweNumber - .DONTCARE; // Static non-final field names should comply with a naming - // convention - case "S3012": - return CweNumber.DONTCARE; // Arrays should not be copied using loops - case "S3400": - return CweNumber.DONTCARE; // Methods should not return constants - case "S3518": - return 369; // Zero should not be a possible denominator - case "S3599": - return CweNumber.DONTCARE; // Double Brace Initialization should not be used - case "S3626": - return CweNumber.DONTCARE; // Jump statements should not be redundant - case "S3649": - return CweNumber - .SQL_INJECTION; // Database queries should not be vulnerable to injection - // attacks - case "S3740": - return CweNumber.DONTCARE; // Raw types should not be used - case "S3776": - return CweNumber.DONTCARE; // Cognitive Complexity of methods should not be too high - case "S3824": - return CweNumber - .DONTCARE; // "Map.get" and value test should be replaced with single method - // call - case "S3973": - return CweNumber - .DONTCARE; // A conditionally executed single line should be denoted by - // indentation - case "S4042": - return CweNumber.DONTCARE; // "java.nio.Files#delete" should be preferred - case "S4435": - return CweNumber.XXE; // XML transformers should be secured - case "S4488": - return CweNumber - .DONTCARE; // Composed "@RequestMapping" variants should be preferred - case "S4719": - return CweNumber.DONTCARE; // "StandardCharsets" constants should be preferred - case "S4838": - return CweNumber - .DONTCARE; // An iteration on a Collection should be performed on the type - // handled - // by the Collection + return CweNumber.UNSAFE_REFLECTION; + case "S2677": // "read" and "readLine" return values should be used + return CweNumber.DONTCARE; + case "S2681": // Multiline blocks should be enclosed in curly braces + return CweNumber.INCORRECT_BLOCK_DELIMITATION; + case "S2696": // Instance methods should not write to "static" fields + return CweNumber.DONTCARE; + case "S2755": // XML parsers should not be vulnerable to XXE attacks + return CweNumber.XXE; + case "S2786": // Nested "enum"s should not be declared static + return CweNumber.DONTCARE; + case "S2864": // "entrySet()" should be iterated when both the key and value are needed + return CweNumber.DONTCARE; + case "S3008": // Static non-final field names should comply with a naming convention + return CweNumber.DONTCARE; + case "S3012": // Arrays should not be copied using loops + return CweNumber.DONTCARE; + case "S3400": // Methods should not return constants + return CweNumber.DONTCARE; + case "S3518": // Zero should not be a possible denominator + return CweNumber.DIVISION_BY_ZERO; + case "S3599": // Double Brace Initialization should not be used + return CweNumber.DONTCARE; + case "S3626": // Jump statements should not be redundant + return CweNumber.DONTCARE; + case "S3649": // Database queries should not be vulnerable to injection attacks + return CweNumber.SQL_INJECTION; + case "S3740": // Raw types should not be used + return CweNumber.DONTCARE; + case "S3776": // Cognitive Complexity of methods should not be too high + return CweNumber.DONTCARE; + case "S3824": // "Map.get" and value test should be replaced with single method call + return CweNumber.DONTCARE; + case "S3973": // A conditionally executed single line should be denoted by indentation + return CweNumber.DONTCARE; + case "S4042": // "java.nio.Files#delete" should be preferred + return CweNumber.DONTCARE; + case "S4435": // XML transformers should be secured + return CweNumber.XXE; + case "S4488": // Composed "@RequestMapping" variants should be preferred + return CweNumber.DONTCARE; + case "S4719": // "StandardCharsets" constants should be preferred + return CweNumber.DONTCARE; + case "S4838": // An iteration on a Collection should be performed on the type handled by + // the Collection + return CweNumber.DONTCARE; case "S5131": // Endpoints should not be vulnerable to reflected cross-site scripting // (XSS) attacks return CweNumber.XSS; - case "S5261": - return CweNumber - .DONTCARE; // "else" statements should be clearly matched with an "if" - case "S5361": - return CweNumber - .DONTCARE; // "String#replace" should be preferred to "String#replaceAll" - case "S5542": - return CweNumber - .WEAK_CRYPTO_ALGO; // Benchmark Vuln: Encryption algorithms should be used - // with - // secure mode and padding scheme - case "S5547": - return CweNumber - .WEAK_CRYPTO_ALGO; // Benchmark Vuln: Cipher algorithms should be robust - + case "S5261": // "else" statements should be clearly matched with an "if" + return CweNumber.DONTCARE; + case "S5361": // "String#replace" should be preferred to "String#replaceAll" + return CweNumber.DONTCARE; + case "S5542": // Benchmark Vuln: Encryption algorithms should be used with secure mode + // and padding scheme + return CweNumber.WEAK_CRYPTO_ALGO; + case "S5547": // Benchmark Vuln: Cipher algorithms should be robust + return CweNumber.WEAK_CRYPTO_ALGO; case "CallToDeprecatedMethod": case "ClassVariableVisibilityCheck": - case "DuplicatedBlocks": + case "DuplicatedBlocks": // Not sure why these are being returned instead of an S#### + // value case "SwitchLastCaseIsDefaultCheck": - return CweNumber.DONTCARE; // Not sure why these are being returned instead of an - // S#### value + return CweNumber.DONTCARE; default: System.out.println( "SonarQubeReader: Unknown squid number: " @@ -551,6 +480,6 @@ public static int cweLookup(String squidNumber) { + " has no CWE mapping."); } - return -1; + return CweNumber.DONTCARE; } } 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 21f97804..0390a626 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,6 +17,7 @@ */ package org.owasp.benchmarkutils.score.parsers; +import org.owasp.benchmarkutils.score.CweNumber; import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; @@ -93,18 +94,18 @@ private TestCaseResult parseSourceMeterItem(String vuln, String file) throws Exc return null; } - private static int cweLookup(String vuln) { + private static CweNumber cweLookup(String vuln) { switch (vuln) { // case "insecure-cookie": // return 614; // insecure cookie use case "SQL Injection": - return 89; // sql injection + return CweNumber.SQL_INJECTION; case "Command Injection": - return 78; // command injection + return CweNumber.OS_COMMAND_INJECTION; case "LDAP Injection": - return 90; // ldap injection + return CweNumber.LDAP_INJECTION; case "HTTP Response Splitting": - return 113; // header injection + return CweNumber.HTTP_RESPONSE_SPLITTING; // case "hql-injection": // return 0000; // hql injection // case "unsafe-readline": @@ -112,11 +113,11 @@ private static int cweLookup(String vuln) { // case "reflection-injection": // return 0000; // reflection injection case "Cross-site Scripting": - return 79; // xss + return CweNumber.XSS; // case "xpath-injection": // return 643; // xpath injection case "Path Traversal": - return 22; // path traversal + return CweNumber.PATH_TRAVERSAL; // case "crypto-bad-mac": // return 328; // weak hash // case "crypto-weak-randomness": @@ -128,6 +129,6 @@ private static int cweLookup(String vuln) { // case "xxe": // return 611; // xml entity } - return 0; + return CweNumber.DONTCARE; } } 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 79aad119..d9ed21c7 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 @@ -86,7 +86,8 @@ private String lineNumber(Report.VulnerabilityType.Vulnerability vulnerability) private boolean resultsInCwe( Report.VulnerabilityType vulnerabilityType, Report.VulnerabilityType.Vulnerability v) { - return figureCwe(vulnerabilityType.name, v.function, v.filename) != -1; + return !CweNumber.DONTCARE.equals( + figureCwe(vulnerabilityType.name, v.function, v.filename)); } private boolean isBenchmarkTest(String filename) { @@ -97,7 +98,7 @@ private boolean isRealVulnerability(String function) { return !function.matches("/printStackTrace|Cookie$|getMessage$/"); } - private int figureCwe(String type, String function, String filename) { + private CweNumber figureCwe(String type, String function, String filename) { switch (type) { case "SQL Injection": return CweNumber.SQL_INJECTION; @@ -105,7 +106,7 @@ private int figureCwe(String type, String function, String filename) { case "File Manipulation": return CweNumber.PATH_TRAVERSAL; case "Command Execution": - return CweNumber.COMMAND_INJECTION; + return CweNumber.OS_COMMAND_INJECTION; case "Cross Site Scripting": return CweNumber.XSS; case "LDAP Injection": @@ -133,14 +134,14 @@ private int figureCwe(String type, String function, String filename) { return CweNumber.INSECURE_COOKIE; } - return -1; + return CweNumber.DONTCARE; case "JSP Page Execution": case "Dangerous File Extensions": case "Arbitrary Server Connection": case "Log Forging": case "Mail Relay": case "HTTP Response Splitting": - return -1; + return CweNumber.DONTCARE; default: System.out.println( "INFO: Unable to figure out cwe for: " @@ -149,7 +150,7 @@ private int figureCwe(String type, String function, String filename) { + function + " @ " + filename); - return -1; + return CweNumber.DONTCARE; } } 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 e39093ec..6d065de0 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,19 +17,15 @@ */ package org.owasp.benchmarkutils.score.parsers; -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.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.w3c.dom.NodeList; -import org.xml.sax.InputSource; public class VeracodeReader extends Reader { @@ -46,7 +42,6 @@ public boolean canRead(ResultFile resultFile) { @Override public TestSuiteResults parse(ResultFile resultFile) throws Exception { - TestSuiteResults tr = new TestSuiteResults("Veracode SAST", true, TestSuiteResults.ToolType.SAST); @@ -132,11 +127,24 @@ private TestCaseResult parseVeracodeVulnerability(Node flaw) { return null; } - private int translate(int cwe) { - if (cwe == 73) return 22; - if (cwe == 80) return 79; - if (cwe == 331) return 330; - if (cwe == 91) return 643; - return cwe; + /** + * Maps detected CWE number to one that BenchmarkScore expects. + * + * @param cwe reported CWE number + * @return fixed (or same) CWE number + */ + private CweNumber translate(int cwe) { + switch (cwe) { + case 73: + return CweNumber.PATH_TRAVERSAL; + case 80: + return CweNumber.XSS; + case 91: + return CweNumber.XPATH_INJECTION; + case 331: + return CweNumber.WEAK_RANDOM; + } + + return CweNumber.lookup(cwe); } } diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/VisualCodeGrepperReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/VisualCodeGrepperReader.java index aa897511..e13713ed 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/VisualCodeGrepperReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/VisualCodeGrepperReader.java @@ -106,7 +106,7 @@ private TestCaseResult parseVisualCodeGrepperIssue(Node n) { return null; } - private int figureCWE(TestCaseResult tcr, Node catnode) { + private CweNumber figureCWE(TestCaseResult tcr, Node catnode) { String cat = null; if (catnode != null) { cat = catnode.getTextContent(); @@ -131,7 +131,7 @@ private int figureCWE(TestCaseResult tcr, Node catnode) { // Command injection case "java.lang.Runtime.exec Gets Path from Variable": - return CweNumber.COMMAND_INJECTION; + return CweNumber.OS_COMMAND_INJECTION; // XPath Injection case "FileInputStream": @@ -161,8 +161,7 @@ private int figureCWE(TestCaseResult tcr, Node catnode) { return CweNumber.TRUST_BOUNDARY_VIOLATION; default: - return 00; // System.out.println( "Unknown vuln category for VisualCodeGrepper: " + - // cat ); + return CweNumber.DONTCARE; } } } diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/W3AFReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/W3AFReader.java index 55db6164..e443b567 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/W3AFReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/W3AFReader.java @@ -89,8 +89,7 @@ private TestCaseResult parseW3AFIssue(Node flaw) { tcr.setEvidence(severity + "::" + description); String name = getAttributeValue("name", flaw); - int cwe = cweLookup(name); - tcr.setCWE(cwe); + tcr.setCWE(cweLookup(name)); String uri = getAttributeValue("url", flaw); String testfile = uri.substring(uri.lastIndexOf('/') + 1); @@ -113,9 +112,9 @@ private TestCaseResult parseW3AFIssue(Node flaw) { return null; } - private int cweLookup(String name) { + private CweNumber cweLookup(String name) { if (name == null || name.isEmpty()) { - return 0000; + return CweNumber.DONTCARE; } switch (name) { case "Cross site scripting vulnerability": @@ -137,6 +136,6 @@ private int cweLookup(String name) { // case "trust-boundary-violation" : return 501; // trust boundary // case "xxe" : return 611; // xml entity } - return 0000; + return CweNumber.DONTCARE; } } 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 f19bfef6..0ecc10c1 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,6 +26,7 @@ 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; @@ -51,36 +52,38 @@ public TestSuiteResults parse(ResultFile resultFile) throws Exception { JSONObject vulnerabilities = resultFile.json().getJSONObject("vulnerabilities"); - Map categoryCweMap = new HashMap<>(); + Map categoryCweMap = new HashMap<>(); - categoryCweMap.put("CRLF Injection", 93); - categoryCweMap.put("Cross Site Request Forgery", 352); - categoryCweMap.put("Command execution", 78); // aka command injection - categoryCweMap.put("Path Traversal", 22); - categoryCweMap.put("Secure Flag cookie", 614); - categoryCweMap.put("Blind SQL Injection", 89); - categoryCweMap.put("SQL Injection", 89); - categoryCweMap.put("Cross Site Scripting", 79); - categoryCweMap.put("XML External Entity", 611); + categoryCweMap.put("CRLF Injection", CweNumber.CRLF_INJECTION); + categoryCweMap.put("Cross Site Request Forgery", CweNumber.CSRF); + categoryCweMap.put("Command execution", CweNumber.OS_COMMAND_INJECTION); + categoryCweMap.put("Path Traversal", CweNumber.PATH_TRAVERSAL); + categoryCweMap.put("Secure Flag cookie", CweNumber.INSECURE_COOKIE); + categoryCweMap.put("Blind SQL Injection", CweNumber.SQL_INJECTION); + categoryCweMap.put("SQL Injection", CweNumber.SQL_INJECTION); + categoryCweMap.put("Cross Site Scripting", CweNumber.XSS); + categoryCweMap.put("XML External Entity", CweNumber.XXE); // Add others we don't currently care about, to make sure that all findings are considered, // and no new finding types are ignored // It is possible we'd care about some of these in the future - categoryCweMap.put("Content Security Policy Configuration", 1021); - categoryCweMap.put("Open Redirect", 601); - categoryCweMap.put("Server Side Request Forgery", 918); - categoryCweMap.put("Backup file", 0); - categoryCweMap.put("Fingerprint web application framework", 0); - categoryCweMap.put("Fingerprint web server", 0); - categoryCweMap.put("Htaccess Bypass", 0); - categoryCweMap.put("HTTP Secure Headers", 0); - categoryCweMap.put("HttpOnly Flag cookie", 1004); - categoryCweMap.put("Potentially dangerous file", 0); - categoryCweMap.put("Weak credentials", 0); - - for (Map.Entry entry : categoryCweMap.entrySet()) { + categoryCweMap.put( + "Content Security Policy Configuration", + CweNumber.IMPROPER_RESTRICTION_OF_UI_LAYERS); + categoryCweMap.put("Open Redirect", CweNumber.OPEN_REDIRECT); + categoryCweMap.put("Server Side Request Forgery", CweNumber.SERVER_SIDE_REQUEST_FORGERY); + categoryCweMap.put("Backup file", CweNumber.DONTCARE); + categoryCweMap.put("Fingerprint web application framework", CweNumber.DONTCARE); + categoryCweMap.put("Fingerprint web server", CweNumber.DONTCARE); + categoryCweMap.put("Htaccess Bypass", CweNumber.DONTCARE); + categoryCweMap.put("HTTP Secure Headers", CweNumber.DONTCARE); + categoryCweMap.put("HttpOnly Flag cookie", CweNumber.COOKIE_WITHOUT_HTTPONLY); + categoryCweMap.put("Potentially dangerous file", CweNumber.DONTCARE); + categoryCweMap.put("Weak credentials", CweNumber.DONTCARE); + + for (Map.Entry entry : categoryCweMap.entrySet()) { String category = entry.getKey(); - Integer cwe = entry.getValue(); + CweNumber cwe = entry.getValue(); // The following gets all the vulnerabilities reported for the specified category // JSONArray arr = vulnerabilities.getJSONArray(category); @@ -110,7 +113,7 @@ public TestSuiteResults parse(ResultFile resultFile) throws Exception { return tr; } - private static TestCaseResult parseTestCaseResult(JSONObject finding, Integer cwe) { + private static TestCaseResult parseTestCaseResult(JSONObject finding, CweNumber cwe) { try { String filename = getFilenameFromFinding(finding); 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 aa66c733..f1f9aedc 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 @@ -76,7 +76,7 @@ public TestSuiteResults parse(ResultFile resultFile) throws Exception { // type // First, get the CWE for all these entries - int cwe = getCWE(vuln); + CweNumber cwe = getCWE(vuln); // Then process each entry Node entriesNode = getNamedChild("entries", vuln); @@ -106,47 +106,17 @@ public TestSuiteResults parse(ResultFile resultFile) throws Exception { } // Parse the CWE # out of the references included with the vuln - private int getCWE(Node vuln) { - int cwe = -1; + private CweNumber getCWE(Node vuln) { + CweNumber cwe = CweNumber.DONTCARE; Node refs = getNamedChild("references", vuln); List references = getNamedChildren("reference", refs); for (Node ref : references) { String title = getNamedChild("title", ref).getTextContent(); if (title.startsWith("CWE-")) { String cweNum = title.substring("CWE-".length(), title.indexOf(":")); - cwe = cweLookup(cweNum); + cwe = CweNumber.lookup(cweNum); } } return cwe; } - - private int cweLookup(String cwe) { - switch (cwe) { - case "22": - return CweNumber.PATH_TRAVERSAL; - case "78": - return CweNumber.COMMAND_INJECTION; - case "79": - return CweNumber.XSS; - case "89": // Normal and Blind SQL Injection - return CweNumber.SQL_INJECTION; - case "352": - return CweNumber.CSRF; - case "611": - return CweNumber.XXE; - case "93": // HTTP Response Splitting - case "530": // Exposure of Backup file - case "538": // Htaccess bypass - case "601": // Open Redirect - case "798": // Hard Coded credentials - case "918": // SSRF - return CweNumber.DONTCARE; - - // Note: Wapiti does report Secure Flag not set on cookie findings, but doesn't - // report the specific page. Only the entire web app. - default: - System.out.println("WARNING: Wapiti-Unmapped CWE number: " + cwe); - } - return -1; - } } 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 d1dacce8..87c9750d 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,6 +19,7 @@ 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; @@ -84,8 +85,7 @@ private TestCaseResult parseWebInspectIssue(Node flaw) throws Exception { Node vulnId = getNamedChild("VulnerabilityID", flaw); if (vulnId != null) { String vuln = vulnId.getTextContent(); - int cwe = cweLookup(vuln); - tcr.setCWE(cwe); + tcr.setCWE(cweLookup(vuln)); } String conf = getNamedChild("Severity", flaw).getTextContent(); @@ -112,70 +112,75 @@ private TestCaseResult parseWebInspectIssue(Node flaw) throws Exception { return null; } - private int cweLookup(String rule) { + private CweNumber cweLookup(String rule) { switch (rule) { case "810": - return 0000; // Poor Error Handling: Unhandled Exception + return CweNumber.DONTCARE; // Poor Error Handling: Unhandled Exception case "1436": - return 0000; // Poor Error Handling: Unhandled Exception + return CweNumber.DONTCARE; // Poor Error Handling: Unhandled Exception case "1498": - return 0000; // Poor Error Handling: Unhandled Exception + return CweNumber.DONTCARE; // Poor Error Handling: Unhandled Exception case "4720": - return 614; // Cookie Security: Cookie Not Sent Over SSL + return CweNumber.INSECURE_COOKIE; case "4724": - return 0000; // Password Management: Unmasked Password Field + return CweNumber.DONTCARE; // Password Management: Unmasked Password Field case "4725": - return 0000; // Server Misconfiguration: SSL Certificate Hostname Discrepancy + return CweNumber + .DONTCARE; // Server Misconfiguration: SSL Certificate Hostname Discrepancy case "4729": - return 0000; // Transport Layer Protection: Insecure Transmission + return CweNumber.DONTCARE; // Transport Layer Protection: Insecure Transmission case "5546": - return 0000; // Compliance Failure: Missing Privacy Policy + return CweNumber.DONTCARE; // Compliance Failure: Missing Privacy Policy case "5597": - return 0000; // Privacy Violation: Autocomplete + return CweNumber.DONTCARE; // Privacy Violation: Autocomplete case "5649": - return 79; // Cross-Site Scripting: Reflected + return CweNumber.XSS; case "10167": - return 0000; // Password Management: Insecure Submission + return CweNumber.DONTCARE; // Password Management: Insecure Submission case "10210": - return 0000; // Access Control: Unprotected Directory + return CweNumber.DONTCARE; // Access Control: Unprotected Directory case "10237": - return 0000; // Privacy Violation: Credit Card Number + return CweNumber.DONTCARE; // Privacy Violation: Credit Card Number case "10543": - return 0000; // Cookie Security: HTTPOnly not Set + return CweNumber.DONTCARE; // Cookie Security: HTTPOnly not Set case "10655": - return 0000; // Application Misconfiguration: Exposure of POST Parameters in GET + return CweNumber + .DONTCARE; // Application Misconfiguration: Exposure of POST Parameters in + // GET // Request case "10825": - return 0000; // Privacy Violation: Credit Card Number + return CweNumber.DONTCARE; // Privacy Violation: Credit Card Number case "10932": - return 0000; // Poor Error Handling: Server Error Message + return CweNumber.DONTCARE; // Poor Error Handling: Server Error Message case "10965": - return 0000; // Transport Layer Protection: Insecure Transmission + return CweNumber.DONTCARE; // Transport Layer Protection: Insecure Transmission case "11293": - return 79; // Cross-Frame Scripting case "11294": - return 79; // Cross-Frame Scripting + return CweNumber.XSS; case "11299": - return 89; // SQL Injection: Blind + return CweNumber.SQL_INJECTION; case "11306": - return 0000; // Server Misconfiguration: Cache Policy + return CweNumber.DONTCARE; // Server Misconfiguration: Cache Policy case "11359": - return 0000; // Server Misconfiguration: Response Headers + return CweNumber.DONTCARE; // Server Misconfiguration: Response Headers case "11365": - return 0000; // Insecure SSL: Missing Http Strict Transport + return CweNumber.DONTCARE; // Insecure SSL: Missing Http Strict Transport case "11380": - return 0000; // Often Misused: Weak SSL Certificate + return CweNumber.DONTCARE; // Often Misused: Weak SSL Certificate case "11395": - return 0000; // Transport Layer Protection: Weak SSL Protocol + return CweNumber.DONTCARE; // Transport Layer Protection: Weak SSL Protocol // case "insecure-cookie" : return 614; // insecure cookie use // case "sql-injection" : return 89; // sql injection // case "cmd-injection" : return 78; // command injection // case "ldap-injection" : return 90; // 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 "hql-injection" : return CweNumber.DONTCARE; // hql + // injection + // case "unsafe-readline" : return CweNumber.DONTCARE; // unsafe + // readline + // case "reflection-injection" : return CweNumber.DONTCARE; // + // reflection injection // case "reflected-xss" : return 79; // xss // case "xpath-injection" : return 643; // xpath injection // case "path-traversal" : return 22; // path traversal @@ -185,6 +190,6 @@ private int cweLookup(String rule) { // case "trust-boundary-violation" : return 501; // trust boundary // case "xxe" : return 611; // xml entity } - return 0; + return CweNumber.DONTCARE; } } 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 e0926584..6363a54b 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 @@ -21,6 +21,7 @@ import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; 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; @@ -51,7 +52,7 @@ public TestSuiteResults parse(ResultFile resultFile) throws Exception { private final StringBuilder m_CollectedCharacters = new StringBuilder(); private String m_ProblemTypeId; - private int m_CWE = -1; + private CweNumber m_CWE = CweNumber.DONTCARE; private String m_Class; private String m_Classification; @@ -99,15 +100,16 @@ public void endElement( case "cweNumber": // remove leading "CWE-" and thousands delimiter try { - m_CWE = + int cwe = Integer.parseInt( m_CollectedCharacters .toString() .substring(4) .replace(".", "") .replace(",", "")); - } catch (NumberFormatException e) { - m_CWE = -1; + + m_CWE = CweNumber.lookup(cwe); + } catch (NumberFormatException ignored) { } break; @@ -141,7 +143,7 @@ public void endElement( // for backward compatibility // for reports without CWE numbers - map problem type to // CWE number - if (m_CWE < 0) { + if (CweNumber.DONTCARE.equals(m_CWE)) { m_CWE = figureCWE(m_ProblemTypeId); } @@ -159,7 +161,7 @@ public void endElement( } m_ProblemTypeId = null; - m_CWE = -1; + m_CWE = CweNumber.DONTCARE; m_Class = null; m_Classification = null; break; @@ -184,45 +186,34 @@ public void characters(final char ch[], final int start, final int length) return tr; } - private int figureCWE(final String problemTypeId) { + private CweNumber figureCWE(final String problemTypeId) { switch (problemTypeId) { case "ci:CommandInjection": - return 78; - + return CweNumber.OS_COMMAND_INJECTION; case "SpecialMethodCall:WeakEncryption": - return 327; - + return CweNumber.WEAK_CRYPTO_ALGO; case "SpecialMethodCall:WeakHash": - return 328; - + return CweNumber.WEAK_HASH_ALGO; case "ci:LDAPInjection": - return 90; - + return CweNumber.LDAP_INJECTION; case "pt:PathTraversal": - return 22; - + return CweNumber.PATH_TRAVERSAL; case "cook:UnsecuredCookie": - return 614; - + return CweNumber.INSECURE_COOKIE; case "ci:SQLInjection": - return 89; - + return CweNumber.SQL_INJECTION; case "tbv:TrustBoundaryViolationSession": - return 501; - + return CweNumber.TRUST_BOUNDARY_VIOLATION; case "SpecialMethodCall:java.util.Random": - return 330; - + return CweNumber.WEAK_RANDOM; case "ci:XPathInjection": - return 643; - + return CweNumber.XPATH_INJECTION; case "xss:XSSFromRequest": case "xss:XSSFromDb": - return 79; - + return CweNumber.XSS; default: // Dummy. - return 0; + return CweNumber.DONTCARE; } } } diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ZapJsonReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ZapJsonReader.java index de4887da..cf09b996 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ZapJsonReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ZapJsonReader.java @@ -121,7 +121,7 @@ private void handleNewReportFormat(ResultFile resultFile, TestSuiteResults tr) { site -> site.alerts.forEach( alert -> { - int cwe = mapCwe(alert.cwe); + CweNumber cwe = mapCwe(alert.cwe); alert.instances.forEach( instance -> { @@ -152,55 +152,16 @@ private String extractTestName(String fullUrl) { } } - private int figureCwe(JSONObject finding) { + private CweNumber figureCwe(JSONObject finding) { return mapCwe(finding.getString("cweid")); } - static int mapCwe(String cwe) { - switch (cwe) { - case "22": - return CweNumber.PATH_TRAVERSAL; - case "78": - return CweNumber.COMMAND_INJECTION; - case "79": - return CweNumber.XSS; - case "89": - return CweNumber.SQL_INJECTION; - case "90": - return CweNumber.LDAP_INJECTION; - case "264": - case "284": - return CweNumber.IMPROPER_ACCESS_CONTROL; - - case "352": - return CweNumber.CSRF; - case "614": - return CweNumber.INSECURE_COOKIE; - - case "1004": - return CweNumber.COOKIE_WITHOUT_HTTPONLY; - - // Don't care about these: - case "16": // Configuration - case "134": // Use of Externally-Controlled Format String - case "200": // Exposure of Sensitive Information to Unauthorized Actor - When 500 errors - // are returned - case "436": // Interpretation Conflict - case "345": // Insufficient Verification of Data Authenticity - case "525": // Browser caching sensitive data - case "565": // Reliance on Cookies without Validation and Integrity Checking - case "693": // Protection Mechanism Failure - case "829": // Inclusion of Functionality from Untrusted Control Sphere (e.g., CDN) - case "933": // Security Misconfiguration - case "1021": // Improper Restriction of Rendered UI Layers or Frames - case "1275": // Sensitive Cookie with Improper SameSite Attribute - return Integer.parseInt(cwe); // Return the CWE anyway. - - default: - System.out.println( - "WARNING: ZAP CWE not mapped to expected test suite CWE: " + cwe); - return Integer.parseInt(cwe); + static CweNumber mapCwe(String cwe) { + if ("264".equals(cwe)) { + return CweNumber.IMPROPER_ACCESS_CONTROL; } + + return CweNumber.lookup(cwe); } @JsonIgnoreProperties(ignoreUnknown = true) diff --git a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ZapReader.java b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ZapReader.java index 6cc4cdc4..a090802c 100644 --- a/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ZapReader.java +++ b/plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/ZapReader.java @@ -22,6 +22,7 @@ import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; +import org.owasp.benchmarkutils.score.CweNumber; import org.owasp.benchmarkutils.score.ResultFile; import org.owasp.benchmarkutils.score.TestCaseResult; import org.owasp.benchmarkutils.score.TestSuiteResults; @@ -121,7 +122,7 @@ public TestSuiteResults parse(ResultFile resultFile) throws Exception { // private void parseAndAddZapIssues(Node flaw, TestSuiteResults tr) throws URISyntaxException { - int cwe = -1; + CweNumber cwe = CweNumber.DONTCARE; Node rule = getNamedChild("cweid", flaw); if (rule != null) { cwe = cweLookup(rule.getTextContent()); @@ -144,7 +145,7 @@ private void parseAndAddZapIssues(Node flaw, TestSuiteResults tr) throws URISynt } private void addIssue( - Node alertData, TestSuiteResults tr, int cwe, String category, int confidence) { + Node alertData, TestSuiteResults tr, CweNumber cwe, String category, int confidence) { int testNumber = testNumber(getNamedChild("uri", alertData).getTextContent()); if (testNumber > 0) { tr.put(createTestCaseResult(cwe, category, confidence, testNumber)); @@ -152,9 +153,9 @@ private void addIssue( } private TestCaseResult createTestCaseResult( - int cwe, String category, int confidence, int testNumber) { + CweNumber cwe, String category, int confidence, int testNumber) { TestCaseResult tcr = new TestCaseResult(); - if (cwe != -1) { + if (!CweNumber.DONTCARE.equals(cwe)) { tcr.setCWE(cwe); } tcr.setCategory(category); @@ -164,7 +165,7 @@ private TestCaseResult createTestCaseResult( return tcr; } - private int cweLookup(String orig) { + private CweNumber cweLookup(String orig) { return ZapJsonReader.mapCwe(orig); } } diff --git a/plugin/src/test/java/org/owasp/benchmarkutils/score/CweNumberTest.java b/plugin/src/test/java/org/owasp/benchmarkutils/score/CweNumberTest.java new file mode 100644 index 00000000..0ccd7750 --- /dev/null +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/CweNumberTest.java @@ -0,0 +1,93 @@ +/** + * 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 2022 + */ +package org.owasp.benchmarkutils.score; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.io.ByteArrayOutputStream; +import java.util.HashSet; +import java.util.Set; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class CweNumberTest { + + private static final int UNMAPPED_CWE_NUMBER = 99999; + ByteArrayOutputStream out; + + @BeforeEach + public void setUp() { + out = new java.io.ByteArrayOutputStream(); + System.setOut(new java.io.PrintStream(out)); + } + + @Test + public void returnDontCareForUnmappedCweNumber() { + assertEquals(CweNumber.DONTCARE, CweNumber.lookup(UNMAPPED_CWE_NUMBER)); + } + + @Test + public void looksUpValueByInteger() { + assertEquals(CweNumber.PATH_TRAVERSAL, CweNumber.lookup(CweNumber.PATH_TRAVERSAL.number)); + } + + @Test + public void looksUpValueByString() { + assertEquals( + CweNumber.PATH_TRAVERSAL, CweNumber.lookup("" + CweNumber.PATH_TRAVERSAL.number)); + } + + @Test + public void warnsAboutUnmappedCweNumberContainingCallerClass() { + CweNumber.lookup(UNMAPPED_CWE_NUMBER); + assertEquals( + "WARN: CweNumberTest requested unmapped CWE number " + UNMAPPED_CWE_NUMBER + ".\n", + out.toString()); + } + + @Test + public void doesNotWarnForMappedCweNumber() { + CweNumber.lookup(CweNumber.PATH_TRAVERSAL.number); + assertEquals("", out.toString()); + } + + @Test + public void returnsDontCareForUnparsableNumber() { + assertEquals(CweNumber.DONTCARE, CweNumber.lookup("unparsable")); + } + + @Test + public void showsErrorForUnparsableNumberContainingCallerClass() { + CweNumber.lookup("unparsable"); + assertEquals( + "ERROR: Failed to parse CWE number 'unparsable' provided by CweNumberTest.\n", + out.toString()); + } + + @Test + public void doesNotContainSameNumberTwice() { + CweNumber[] enumValues = CweNumber.class.getEnumConstants(); + Set cweNumbers = new HashSet<>(); + + for (CweNumber cweNumber : enumValues) { + cweNumbers.add(cweNumber.number); + } + + assertEquals(enumValues.length, cweNumbers.size()); + } +} diff --git a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/AcunetixReaderTest.java b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/AcunetixReaderTest.java index 2bff445a..de55f2c1 100644 --- a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/AcunetixReaderTest.java +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/AcunetixReaderTest.java @@ -54,7 +54,7 @@ void readerHandlesGivenResultFile() throws Exception { assertEquals(2, result.getTotalResults()); - assertEquals(CweNumber.COMMAND_INJECTION, result.get(1).get(0).getCWE()); + assertEquals(CweNumber.OS_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/BurpReaderTest.java b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/BurpReaderTest.java index 05d876ca..4fd81365 100644 --- a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/BurpReaderTest.java +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/BurpReaderTest.java @@ -54,7 +54,7 @@ void readerHandlesGivenResultFile() throws Exception { assertEquals(2, result.getTotalResults()); - assertEquals(CweNumber.COMMAND_INJECTION, result.get(1).get(0).getCWE()); + assertEquals(CweNumber.OS_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 index 59ef8023..195d8115 100644 --- a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/CASTAIPReaderTest.java +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/CASTAIPReaderTest.java @@ -54,7 +54,7 @@ void readerHandlesGivenResultFile() throws Exception { assertEquals(2, result.getTotalResults()); - assertEquals(CweNumber.COMMAND_INJECTION, result.get(1).get(0).getCWE()); + assertEquals(CweNumber.OS_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/ContrastScanReaderTest.java b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/ContrastScanReaderTest.java index 96872e3d..875cd0b1 100644 --- a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/ContrastScanReaderTest.java +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/ContrastScanReaderTest.java @@ -54,7 +54,7 @@ void readerHandlesGivenResultFile() throws Exception { assertEquals(2, result.getTotalResults()); - assertEquals(CweNumber.COMMAND_INJECTION, result.get(1).get(0).getCWE()); + assertEquals(CweNumber.OS_COMMAND_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/FortifyReaderTest.java b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/FortifyReaderTest.java index 9a5792aa..98e20171 100644 --- a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/FortifyReaderTest.java +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/FortifyReaderTest.java @@ -55,7 +55,7 @@ void readerHandlesGivenResultFile() throws Exception { assertEquals(2, result.getTotalResults()); - assertEquals(CweNumber.COMMAND_INJECTION, result.get(1).get(0).getCWE()); + assertEquals(CweNumber.OS_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/InsiderReaderTest.java b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/InsiderReaderTest.java index 9fcdf32f..f96d237f 100644 --- a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/InsiderReaderTest.java +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/InsiderReaderTest.java @@ -54,7 +54,7 @@ void readerHandlesGivenResultFile() throws Exception { assertEquals(2, result.getTotalResults()); - assertEquals(CweNumber.COMMAND_INJECTION, result.get(1).get(0).getCWE()); + assertEquals(CweNumber.OS_COMMAND_INJECTION, result.get(1).get(0).getCWE()); assertEquals(CweNumber.WEAK_CRYPTO_ALGO, result.get(2).get(0).getCWE()); } } diff --git a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/Rapid7ReaderTest.java b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/Rapid7ReaderTest.java index 3bdcd51b..222e6048 100644 --- a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/Rapid7ReaderTest.java +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/Rapid7ReaderTest.java @@ -57,6 +57,6 @@ void readerHandlesGivenResultFile() throws Exception { assertEquals(2, result.getTotalResults()); assertEquals(CweNumber.SQL_INJECTION, result.get(1).get(0).getCWE()); - assertEquals(CweNumber.COMMAND_INJECTION, result.get(2).get(0).getCWE()); + assertEquals(CweNumber.OS_COMMAND_INJECTION, result.get(2).get(0).getCWE()); } } diff --git a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/SeekerReaderTest.java b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/SeekerReaderTest.java index c4904ed6..e52b9f99 100644 --- a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/SeekerReaderTest.java +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/SeekerReaderTest.java @@ -54,7 +54,7 @@ void readerHandlesGivenResultFile() throws Exception { assertEquals(2, result.getTotalResults()); - assertEquals(CweNumber.COMMAND_INJECTION, result.get(1).get(0).getCWE()); + assertEquals(CweNumber.OS_COMMAND_INJECTION, result.get(1).get(0).getCWE()); assertEquals(CweNumber.TRUST_BOUNDARY_VIOLATION, result.get(2).get(0).getCWE()); } } 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 index 80f9b451..8247d18f 100644 --- a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/SemgrepReaderTest.java +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/SemgrepReaderTest.java @@ -76,7 +76,7 @@ void readerHandlesGivenResultFileInV121() throws Exception { assertEquals(2, result.getTotalResults()); - assertEquals(CweNumber.COMMAND_INJECTION, result.get(3).get(0).getCWE()); + assertEquals(CweNumber.OS_COMMAND_INJECTION, result.get(3).get(0).getCWE()); assertEquals(CweNumber.INSECURE_COOKIE, result.get(4).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 index 2f0df0c9..52c73ad2 100644 --- a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/SonarQubeReaderTest.java +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/SonarQubeReaderTest.java @@ -56,7 +56,7 @@ void readerHandlesGivenPluginResultFile() throws Exception { assertEquals(2, result.getTotalResults()); - assertEquals(CweNumber.COMMAND_INJECTION, result.get(1).get(0).getCWE()); + assertEquals(CweNumber.OS_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/VeracodeReaderTest.java b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/VeracodeReaderTest.java index 618fbbaf..87fc3fe3 100644 --- a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/VeracodeReaderTest.java +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/VeracodeReaderTest.java @@ -1,12 +1,12 @@ 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.*; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - class VeracodeReaderTest extends ReaderTestBase { private ResultFile resultFile; @@ -33,7 +33,7 @@ void readerHandlesGivenResultFile() throws Exception { assertEquals(3, result.getTotalResults()); - assertEquals(CweNumber.COMMAND_INJECTION, result.get(7).get(0).getCWE()); + assertEquals(CweNumber.OS_COMMAND_INJECTION, result.get(7).get(0).getCWE()); assertEquals(CweNumber.SQL_INJECTION, result.get(8).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 index 88c0374d..b6f00108 100644 --- a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/WapitiJsonReaderTest.java +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/WapitiJsonReaderTest.java @@ -54,7 +54,7 @@ void readerHandlesGivenResultFile() throws Exception { assertEquals(2, result.getTotalResults()); - assertEquals(CweNumber.COMMAND_INJECTION, result.get(1).get(0).getCWE()); + assertEquals(CweNumber.OS_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 index 5b0fb949..40219e38 100644 --- a/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/WapitiReaderTest.java +++ b/plugin/src/test/java/org/owasp/benchmarkutils/score/parsers/WapitiReaderTest.java @@ -55,6 +55,6 @@ void readerHandlesGivenResultFile() throws Exception { assertEquals(2, result.getTotalResults()); assertEquals(CweNumber.SQL_INJECTION, result.get(1).get(0).getCWE()); - assertEquals(CweNumber.COMMAND_INJECTION, result.get(2).get(0).getCWE()); + assertEquals(CweNumber.OS_COMMAND_INJECTION, result.get(2).get(0).getCWE()); } } diff --git a/plugin/src/test/resources/testfiles/Benchmark_Veracode.xml b/plugin/src/test/resources/testfiles/Benchmark_Veracode.xml index 983987f4..699e590d 100644 --- a/plugin/src/test/resources/testfiles/Benchmark_Veracode.xml +++ b/plugin/src/test/resources/testfiles/Benchmark_Veracode.xml @@ -1,73 +1,79 @@ - - - - - - - - - - - - - - - - - - - - - This source of the tainted data is an external web request. - - - - - - - This source of the tainted data is an external web request. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - This source of the tainted data is an external web request. - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + This source of the tainted data is an external web request. + + + + + + + This source of the tainted data is an external web request. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + This source of the tainted data is an external web request. + + + + + + + + + + + +