|
| 1 | +package org.owasp.benchmarkutils.score.parsers; |
| 2 | + |
| 3 | +import org.json.JSONArray; |
| 4 | +import org.json.JSONObject; |
| 5 | +import org.owasp.benchmarkutils.score.*; |
| 6 | + |
| 7 | +public class GitLabSastReader extends Reader { |
| 8 | + @Override |
| 9 | + public boolean canRead(ResultFile resultFile) { |
| 10 | + return resultFile.isJson() |
| 11 | + && resultFile.json().has("scan") |
| 12 | + && resultFile |
| 13 | + .json() |
| 14 | + .getJSONObject("scan") |
| 15 | + .getJSONObject("analyzer") |
| 16 | + .getJSONObject("vendor") |
| 17 | + .getString("name") |
| 18 | + .equalsIgnoreCase("GitLab"); |
| 19 | + } |
| 20 | + |
| 21 | + @Override |
| 22 | + public TestSuiteResults parse(ResultFile resultFile) throws Exception { |
| 23 | + TestSuiteResults tr = new TestSuiteResults("GitLab-SAST", true, TestSuiteResults.ToolType.SAST); |
| 24 | + |
| 25 | + JSONArray vulnerabilities = resultFile.json().getJSONArray("vulnerabilities"); |
| 26 | + |
| 27 | + for (int vulnerability = 0; vulnerability < vulnerabilities.length(); vulnerability++) { |
| 28 | + TestCaseResult tcr = parseGitLabSastFindings(vulnerabilities.getJSONObject(vulnerability)); |
| 29 | + if (tcr != null) { |
| 30 | + tr.put(tcr); |
| 31 | + } |
| 32 | + } |
| 33 | + return tr; |
| 34 | + } |
| 35 | + |
| 36 | + private TestCaseResult parseGitLabSastFindings(JSONObject vulnerability) { |
| 37 | + |
| 38 | + try { |
| 39 | + String className = vulnerability.getJSONObject("location").getString("file"); |
| 40 | + className = (className.substring(className.lastIndexOf('/') + 1)).split("\\.")[0]; |
| 41 | + |
| 42 | + if (className.startsWith(BenchmarkScore.TESTCASENAME)) { |
| 43 | + TestCaseResult tcr = new TestCaseResult(); |
| 44 | + |
| 45 | + JSONArray identifiers = vulnerability.getJSONArray("identifiers"); |
| 46 | + |
| 47 | + int cwe = identifiers.getJSONObject(1).getInt("value"); |
| 48 | + cwe = translate(cwe); |
| 49 | + |
| 50 | + String category = identifiers.getJSONObject(2).getString("name"); |
| 51 | + category = category.split("-")[1].strip(); |
| 52 | + |
| 53 | + String evidence = vulnerability.getString("cve"); |
| 54 | + |
| 55 | + tcr.setCWE(cwe); |
| 56 | + tcr.setCategory(category); |
| 57 | + tcr.setEvidence(evidence); |
| 58 | + tcr.setConfidence(0); |
| 59 | + tcr.setNumber(testNumber(className)); |
| 60 | + |
| 61 | + return tcr; |
| 62 | + } |
| 63 | + } catch (Exception ex) { |
| 64 | + ex.printStackTrace(); |
| 65 | + } |
| 66 | + |
| 67 | + return null; |
| 68 | + } |
| 69 | + |
| 70 | + private int translate(int cwe) { |
| 71 | + //in gitlab sast { |
| 72 | + // "trustbound": 306, // Authentication Bypass Using Trust Boundaries (CWE-306) |
| 73 | + // "weakrand": 338, // Use of Cryptographically Weak Pseudo-Random Number Generator (CWE-338) |
| 74 | + // "sqli": 89, // SQL Injection (CWE-89) |
| 75 | + // "crypto": 327, // Use of a Broken or Risky Cryptographic Algorithm (CWE-327) |
| 76 | + // "cmdi": 185, // Improper Control of Generation of Code ('Code Injection') (CWE-185) |
| 77 | + // "xss": 79, // Cross-site Scripting (CWE-79) |
| 78 | + // "hash": 326, // Inadequate Encryption Strength (CWE-326) |
| 79 | + // "pathtraver": 22, // Path Traversal (CWE-22) |
| 80 | + // "securecookie": 614, // Sensitive Cookie in HTTPS Session Without 'Secure' Attribute (CWE-614) |
| 81 | + // "xpathi": 643, // XPath Injection (CWE-643) |
| 82 | + // "ldapi": 90, // Improper Neutralization of Special Elements used in an LDAP Query ('LDAP Injection') (CWE-90) |
| 83 | + // "httpresponse": 113, // Improper Neutralization of CRLF Sequences in HTTP Headers ('HTTP Response Splitting') (CWE-113) |
| 84 | + // "debugcode": 259, // Use of Hard-coded Password (CWE-259) |
| 85 | + // "cryptointegration": 1004 // Sensitive Cookie Without 'HttpOnly' Flag (CWE-1004) |
| 86 | + //} |
| 87 | + |
| 88 | + //in benchmark tool { |
| 89 | + // "trustbound": 501, |
| 90 | + // "weakrand": 330, |
| 91 | + // "sqli": 89, |
| 92 | + // "crypto": 327, |
| 93 | + // "cmdi": 78, |
| 94 | + // "xss": 79, |
| 95 | + // "hash": 328, |
| 96 | + // "pathtraver": 22, |
| 97 | + // "securecookie": 614, |
| 98 | + // "xpathi": 643, |
| 99 | + // "ldapi": 90 |
| 100 | + //} |
| 101 | + switch (cwe) { |
| 102 | + case 22: |
| 103 | + return CweNumber.PATH_TRAVERSAL; |
| 104 | + case 79: |
| 105 | + return CweNumber.XSS; |
| 106 | + case 89: |
| 107 | + return CweNumber.SQL_INJECTION; |
| 108 | + case 90: |
| 109 | + return CweNumber.LDAP_INJECTION; |
| 110 | + case 113: |
| 111 | + return CweNumber.HTTP_RESPONSE_SPLITTING; |
| 112 | + case 185: |
| 113 | + return CweNumber.COMMAND_INJECTION; |
| 114 | + case 326: |
| 115 | + case 327: |
| 116 | + case 328: |
| 117 | + return CweNumber.WEAK_CRYPTO_ALGO; |
| 118 | + case 338: |
| 119 | + return CweNumber.WEAK_RANDOM; |
| 120 | + case 614: |
| 121 | + return CweNumber.INSECURE_COOKIE; |
| 122 | + case 643: |
| 123 | + return CweNumber.XPATH_INJECTION; |
| 124 | + case 1004: |
| 125 | + return CweNumber.COOKIE_WITHOUT_HTTPONLY; |
| 126 | + case 259: |
| 127 | + case 306: |
| 128 | + break; |
| 129 | + default: |
| 130 | + System.out.println( |
| 131 | + "INFO: Found following CWE in GitLab SAST results which we haven't seen before: " |
| 132 | + + cwe); |
| 133 | + } |
| 134 | + |
| 135 | + return cwe; |
| 136 | + } |
| 137 | +} |
0 commit comments