Skip to content

Add Support for GitLab SAST #86

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
/**
* OWASP Benchmark Project
*
* <p>This file is part of the Open Web Application Security Project (OWASP) Benchmark Project For
* details, please see <a
* href="https://owasp.org/www-project-benchmark/">https://owasp.org/www-project-benchmark/</a>.
*
* <p>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.
*
* <p>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 Barath Raj
* @created 2024
*/
package org.owasp.benchmarkutils.score.parsers;

import org.json.JSONArray;
import org.json.JSONObject;
import org.owasp.benchmarkutils.score.CweNumber;
import org.owasp.benchmarkutils.score.ResultFile;
import org.owasp.benchmarkutils.score.TestCaseResult;
import org.owasp.benchmarkutils.score.TestSuiteResults;

public class GitLabSastReader extends Reader {
@Override
public boolean canRead(ResultFile resultFile) {
return resultFile.isJson()
&& resultFile.json().has("scan")
&& resultFile
.json()
.getJSONObject("scan")
.getJSONObject("analyzer")
.getJSONObject("vendor")
.getString("name")
.equalsIgnoreCase("GitLab");
}

@Override
public TestSuiteResults parse(ResultFile resultFile) throws Exception {
TestSuiteResults tr = new TestSuiteResults("GitLab-SAST", true, TestSuiteResults.ToolType.SAST);

JSONArray vulnerabilities = resultFile.json().getJSONArray("vulnerabilities");

for (int vulnerability = 0; vulnerability < vulnerabilities.length(); vulnerability++) {
TestCaseResult tcr = parseGitLabSastFindings(vulnerabilities.getJSONObject(vulnerability));
if (tcr != null) {
tr.put(tcr);
}
}
return tr;
}

private TestCaseResult parseGitLabSastFindings(JSONObject vulnerability) {

try {
int testNumber = testNumber(vulnerability.getJSONObject("location").getString("file"));

if (testNumber > -1) {
TestCaseResult tcr = new TestCaseResult();

JSONArray identifiers = vulnerability.getJSONArray("identifiers");

int cwe = identifiers.getJSONObject(1).getInt("value");
cwe = translate(cwe);

String category = identifiers.getJSONObject(2).getString("name");
category = category.split("-")[1].strip();

String evidence = vulnerability.getString("cve");

tcr.setCWE(cwe);
tcr.setCategory(category);
tcr.setEvidence(evidence);
tcr.setConfidence(0);
tcr.setNumber(testNumber);

return tcr;
}
} catch (Exception ex) {
ex.printStackTrace();
}

return null;
}

private int translate(int cwe) {

switch (cwe) {
case 22:
return CweNumber.PATH_TRAVERSAL;
case 79:
return CweNumber.XSS;
case 89:
return CweNumber.SQL_INJECTION;
case 90:
return CweNumber.LDAP_INJECTION;
case 113:
return CweNumber.HTTP_RESPONSE_SPLITTING;
case 185:
return CweNumber.COMMAND_INJECTION;
case 326:
case 327:
case 328:
return CweNumber.WEAK_CRYPTO_ALGO;
case 338:
return CweNumber.WEAK_RANDOM;
case 614:
return CweNumber.INSECURE_COOKIE;
case 643:
return CweNumber.XPATH_INJECTION;
case 1004:
return CweNumber.COOKIE_WITHOUT_HTTPONLY;
case 259:
case 306:
break;
default:
System.out.println(
"INFO: Found following CWE in GitLab SAST results which we haven't seen before: "
+ cwe);
}

return cwe;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ public static List<Reader> allReaders() {
new FluidAttacksReader(),
new FortifyReader(),
new FusionLiteInsightReader(),
new GitLabSastReader(),
new HCLAppScanIASTReader(),
new HCLAppScanSourceReader(),
new HCLAppScanStandardReader(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details
*
* @author Raj Barath
* @author Barath Raj
* @created 2023
*/
package org.owasp.benchmarkutils.score.parsers.sarif;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/**
* OWASP Benchmark Project
*
* <p>This file is part of the Open Web Application Security Project (OWASP) Benchmark Project For
* details, please see <a
* href="https://owasp.org/www-project-benchmark/">https://owasp.org/www-project-benchmark/</a>.
*
* <p>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.
*
* <p>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 Barath Raj
* @created 2024
*/
package org.owasp.benchmarkutils.score.parsers;

import org.json.JSONArray;
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 GitLabSastReaderTest extends ReaderTestBase {

private ResultFile resultFile;

@BeforeEach
void setUp() {
resultFile = TestHelper.resultFileOf("testfiles/Benchmark_GitLab_SAST.json");
BenchmarkScore.TESTCASENAME = "BenchmarkTest";
}

@Test
public void onlyGitLabSastReaderReportsCanReadAsTrue() {
assertOnlyMatcherClassIs(this.resultFile, GitLabSastReader.class);
}

@Test
void readerHandlesGivenResultFile() throws Exception {
GitLabSastReader reader = new GitLabSastReader();
TestSuiteResults result = reader.parse(resultFile);

assertEquals(TestSuiteResults.ToolType.SAST, result.getToolType());
assertTrue(result.isCommercial());
assertEquals("GitLab-SAST", result.getToolName());

assertEquals(5, result.getTotalResults());

assertEquals(CweNumber.WEAK_CRYPTO_ALGO, result.get(1).get(0).getCWE());
assertEquals(CweNumber.PATH_TRAVERSAL, result.get(5).get(0).getCWE());
}

@Test
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you test the test here? What does this test do?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually before implementing a logic in the main java file, I was trying it out in the test file. Only when It passes, i add the same logic there. This is an unnecessary test, I'll remove it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please let me know, if I need to remove this test

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd recommend to remove it, since it's basically just testing the testfile, not the reader.

void isAbleToExtractDataToCreateTestCaseResults() {
JSONArray vulnerabilities = resultFile.json().getJSONArray("vulnerabilities");
String path = vulnerabilities.getJSONObject(1).getJSONObject("location").getString("file");

assertEquals("src/main/java/org/owasp/benchmark/testcode/BenchmarkTest00001.java", path);

String className = (path.substring(path.lastIndexOf('/') + 1)).split("\\.")[0];
assertTrue(className.startsWith(BenchmarkScore.TESTCASENAME));

JSONArray identifiers = vulnerabilities.getJSONObject(1).getJSONArray("identifiers");
int cwe = identifiers.getJSONObject(1).getInt("value");
assertEquals(327, cwe);

String category = identifiers.getJSONObject(2).getString("name");
category = category.split("-")[1].strip();
assertEquals("Cryptographic Failures", category);

String evidence = vulnerabilities.getJSONObject(1).getString("cve");
assertEquals("semgrep_id:find_sec_bugs.CIPHER_INTEGRITY-1:71:71", evidence);
}
}
Loading