Skip to content

Reader for Gitlab Advanced SAST #186

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 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package org.owasp.benchmarkutils.score.parsers;

import static java.lang.Integer.parseInt;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import org.owasp.benchmarkutils.score.ResultFile;
import org.owasp.benchmarkutils.score.TestCaseResult;
import org.owasp.benchmarkutils.score.TestSuiteResults;

public class GitlabAdvancedSastReader extends Reader {

// 2015-08-17T14:21:14+03:00
private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");

@Override
public boolean canRead(ResultFile resultFile) {
try {
return resultFile.isJson()
&& resultFile
.json()
.getJSONObject("scan")
.getJSONObject("analyzer")
.getString("name")
.equals("GitLab Advanced SAST");
} catch (Exception e) {
return false;
}
}

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

Report report = jsonMapper.readValue(resultFile.content(), Report.class);

tr.setToolVersion(report.version);
tr.setTime(formatTimeDelta(report.scanInfo.startTime, report.scanInfo.endTime));

report.vulnerabilities.stream()
.map(this::parseJsonResult)
.filter(Objects::nonNull)
.forEach(tr::put);

return tr;
}

private TestCaseResult parseJsonResult(Report.Vulnerability issue) {
Optional<Report.Vulnerability.Identifier> cweIdentifier =
issue.identifiers.stream()
.filter(identifier -> "cwe".equals(identifier.type))
.findFirst();

if (cweIdentifier.isEmpty()) {
return null;
}

TestCaseResult tcr = new TestCaseResult();

tcr.setCWE(parseInt(cweIdentifier.get().value));
tcr.setNumber(testNumber(issue.location.file));

return tcr;
}

private String formatTimeDelta(String start, String end) {
try {
return TestSuiteResults.formatTime(
sdf.parse(end).getTime() - sdf.parse(start).getTime());
} catch (Exception e) {
return "Unknown";
}
}

@JsonIgnoreProperties(ignoreUnknown = true)
private static class Report {
@JsonProperty String version;

@JsonProperty("scan")
ScanInfo scanInfo;

@JsonProperty("vulnerabilities")
List<Vulnerability> vulnerabilities;

@JsonIgnoreProperties(ignoreUnknown = true)
private static class ScanInfo {
@JsonProperty("start_time")
String startTime;

@JsonProperty("end_time")
String endTime;
}

@JsonIgnoreProperties(ignoreUnknown = true)
private static class Vulnerability {
@JsonProperty Location location;

@JsonProperty List<Identifier> identifiers;

@JsonIgnoreProperties(ignoreUnknown = true)
private static class Location {
@JsonProperty String file;
}

@JsonIgnoreProperties(ignoreUnknown = true)
private static class Identifier {
@JsonProperty String type;

@JsonProperty String value;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ public static List<Reader> allReaders() {
new FortifyReader(),
new FortifySarifReader(),
new FusionLiteInsightReader(),
new GitlabAdvancedSastReader(),
new HCLAppScanIASTReader(),
new HCLAppScanSourceReader(),
new HCLAppScanStandardReader(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/**
* 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 Sascha Knoop
* @created 2025
*/
package org.owasp.benchmarkutils.score.parsers;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.owasp.benchmarkutils.score.BenchmarkScore;
import org.owasp.benchmarkutils.score.CweNumber;
import org.owasp.benchmarkutils.score.ResultFile;
import org.owasp.benchmarkutils.score.TestHelper;
import org.owasp.benchmarkutils.score.TestSuiteResults;

public class GitlabAdvancedSastReaderTest extends ReaderTestBase {

private ResultFile resultFile;

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

@Test
public void onlyGitlabAdvancedSastReaderReportsCanReadAsTrue() {
assertOnlyMatcherClassIs(this.resultFile, GitlabAdvancedSastReader.class);
}

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

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

assertEquals(2, result.getTotalResults());

assertEquals(CweNumber.PATH_TRAVERSAL, result.get(1).get(0).getCWE());
assertEquals(CweNumber.COOKIE_WITHOUT_HTTPONLY, result.get(2).get(0).getCWE());
}
}
Loading