Skip to content

Commit

Permalink
AST-25406 Add gl-sast report (#606)
Browse files Browse the repository at this point in the history
* AST-25406 Add gl-sast report

* Add changes due to code review

* Remove row
  • Loading branch information
margaritalm authored Oct 26, 2023
1 parent cf64c05 commit 5933079
Show file tree
Hide file tree
Showing 5 changed files with 226 additions and 2 deletions.
107 changes: 106 additions & 1 deletion internal/commands/result.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"os"
"path/filepath"
"regexp"
"strconv"
"strings"
"text/template"
"time"
Expand Down Expand Up @@ -81,6 +82,7 @@ var resultsFormats = []string{
printer.FormatJSON,
printer.FormatSarif,
printer.FormatSonar,
printer.FormatGL,
}
var summaryFormats = []string{
printer.FormatSummaryConsole,
Expand Down Expand Up @@ -851,6 +853,10 @@ func createReport(format,
jsonRpt := createTargetName(targetFile, targetPath, printer.FormatJSON)
return exportJSONResults(jsonRpt, results)
}
if printer.IsFormat(format, printer.FormatGL) {
jsonRpt := createTargetName("gl-sast-report", targetPath, printer.FormatJSON)
return exportGlSastResults(jsonRpt, results, summary)
}
if printer.IsFormat(format, printer.FormatSummaryConsole) {
return writeConsoleSummary(summary)
}
Expand Down Expand Up @@ -988,7 +994,28 @@ func exportSarifResults(targetFile string, results *wrappers.ScanResultsCollecti
_ = f.Close()
return nil
}

func exportGlSastResults(targetFile string, results *wrappers.ScanResultsCollection, summary *wrappers.ResultSummary) error {
var err error
var resultsJSON []byte
log.Println("Creating gl-sast Report: ", targetFile)
var glSastResults = convertCxResultsToGLSast(results)
glSastResults = addStatus(summary, glSastResults)
resultsJSON, err = json.Marshal(glSastResults)
if err != nil {
return errors.Wrapf(err, "%s: failed to serialize results response ", failedGettingAll)
}
f, err := os.Create(targetFile)
if err != nil {
return errors.Wrapf(err, "%s: failed to create target file ", failedGettingAll)
}
_, _ = fmt.Fprintln(f, string(resultsJSON))
defer f.Close()
return nil
}
func addStatus(summary *wrappers.ResultSummary, glSastResults *wrappers.GlSastResultsCollection) *wrappers.GlSastResultsCollection {
glSastResults.Scan.Status = summary.Status
return glSastResults
}
func exportSonarResults(targetFile string, results *wrappers.ScanResultsCollection) error {
var err error
var resultsJSON []byte
Expand Down Expand Up @@ -1221,6 +1248,84 @@ func convertCxResultsToSarif(results *wrappers.ScanResultsCollection) *wrappers.
sarif.Runs = append(sarif.Runs, createSarifRun(results))
return sarif
}
func convertCxResultsToGLSast(results *wrappers.ScanResultsCollection) *wrappers.GlSastResultsCollection {
var glSast = new(wrappers.GlSastResultsCollection)
glSast.Scan = wrappers.ScanGlReport{}
glSast = setConstValueGlReport(glSast)
glVulnra := convertCxResultToGlVulnerability(results, glSast)
glSast.Vulnerabilities = glVulnra
return glSast
}

func convertCxResultToGlVulnerability(results *wrappers.ScanResultsCollection, glSast *wrappers.GlSastResultsCollection) []wrappers.GlVulnerabilities {
for _, result := range results.Results {
engineType := strings.TrimSpace(result.Type)
if engineType == commonParams.SastType {
glSast = parseGlSastVulnerability(result, glSast)
}
}
return glSast.Vulnerabilities
}

func parseGlSastVulnerability(result *wrappers.ScanResult, glSast *wrappers.GlSastResultsCollection) *wrappers.GlSastResultsCollection {
queryName := result.ScanResultData.QueryName
fileName := result.ScanResultData.Nodes[0].FileName
lineNumber := strconv.FormatUint(uint64(result.ScanResultData.Nodes[0].Line), 10)
startLine := result.ScanResultData.Nodes[0].Line
endLine := result.ScanResultData.Nodes[0].Line + result.ScanResultData.Nodes[0].Length
ID := fmt.Sprintf("%s:%s:%s", queryName, fileName, lineNumber)
category := fmt.Sprintf("%s-%s", wrappers.VendorName, result.Type)
message := fmt.Sprintf("%s@%s:%s", queryName, fileName, lineNumber)

glSast.Vulnerabilities = append(glSast.Vulnerabilities, wrappers.GlVulnerabilities{
ID: ID,
Category: category,
Name: queryName,
Message: message,
Description: result.Description,
CVE: ID,
Severity: result.Severity,
Confidence: result.Severity,
Solution: "",
Scanner: wrappers.GlScanner{
ID: category,
Name: category,
},
Links: nil,
Tracking: wrappers.Tracking{Items: wrappers.Item{
Signatures: wrappers.Signature{
Algorithm: result.Type + "-Algorithm ",
Value: "NA"},
File: fileName,
EndLine: endLine,
StartLine: startLine},
},
Flags: wrappers.Flag{
Type: "",
Origin: result.Type,
Description: result.Description,
},
Location: wrappers.Location{
File: fileName,
StartLine: startLine,
EndLine: endLine,
Class: fileName,
},
})
return glSast
}

func setConstValueGlReport(glSast *wrappers.GlSastResultsCollection) *wrappers.GlSastResultsCollection {
glSast.Schema = "https://gitlab.com/gitlab-org/gitlab/-/blob/8a42b7e8ab41ec2920f02fb4b36f244bbbb4bfb8/lib/gitlab/ci/parsers/security/validators/schemas/14.1.2/sast-report-format.json"
glSast.Version = "14.1.2"
glSast.Scan.Analyzer.URL = wrappers.AnalyzerURL
glSast.Scan.Analyzer.Name = wrappers.VendorName
glSast.Scan.Analyzer.Vendor.Name = wrappers.VendorName
glSast.Scan.Analyzer.ID = wrappers.AnalyzerID
glSast.Scan.Scanner.ID = wrappers.AnalyzerID
glSast.Scan.Scanner.Name = wrappers.VendorName
return glSast
}

func convertCxResultsToSonar(results *wrappers.ScanResultsCollection) *wrappers.ScanResultsSonar {
var sonar = new(wrappers.ScanResultsSonar)
Expand Down
6 changes: 6 additions & 0 deletions internal/commands/result_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -317,3 +317,9 @@ func TestSBOMReportXMLWithProxy(t *testing.T) {
// Remove generated json file
os.Remove(fmt.Sprintf("%s.%s", fileName+"_"+printer.FormatSbom, printer.FormatXML))
}

func TestRunGetResultsByScanIdGLFormat(t *testing.T) {
execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "gl-sast")
// Run test for gl-sast report type
os.Remove(fmt.Sprintf("%s.%s", fileName, printer.FormatGL))
}
1 change: 1 addition & 0 deletions internal/commands/util/printer/printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const (
FormatSummaryMarkdown = "markdown"
FormatSbom = "sbom"
FormatXML = "xml"
FormatGL = "gl-sast"
)

func Print(w io.Writer, view interface{}, format string) error {
Expand Down
111 changes: 111 additions & 0 deletions internal/wrappers/results-gl-sast.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package wrappers

const (
AnalyzerName = "CxOne"
AnalyzerID = AnalyzerName + "-SAST"
AnalyzerURL = "https://checkmarx.company.com/"
VendorName = "Checkmarx"
)

type GlSastResultsCollection struct {
Scan ScanGlReport `json:"scan"`
Schema string `json:"schema"`
Version string `json:"version"`
Vulnerabilities []GlVulnerabilities `json:"vulnerabilities"`
}
type GlVulnerabilities struct {
ID string `json:"id"`
Category string `json:"category"`
Name string `json:"name"`
Message string `json:"message"`
Description string `json:"description"`
CVE string `json:"cve"`
Severity string `json:"severity"`
Confidence string `json:"confidence"`
Solution string `json:"solution"`
Scanner GlScanner `json:"scanner"`
Identifiers []Identifier `json:"identifiers"`
Links []string `json:"links"`
Tracking Tracking `json:"tracking"`
Flags Flag `json:"flags"`
Location Location `json:"location"`
}
type Identifier struct {
Type string `json:"type"`
Name string `json:"name"`
URL string `json:"url"`
Value string `json:"value"`
}
type Flag struct {
Type string `json:"type"`
Origin string `json:"origin"`
Description string `json:"description"`
}
type Location struct {
File string `json:"file"`
StartLine uint `json:"start_line"`
EndLine uint `json:"end_line"`
Class string `json:"class"`
}

type Tracking struct {
Items Item `json:"items"`
}
type Item struct {
Signatures Signature `json:"signatures"`
File string `json:"file"`
EndLine uint `json:"end_line"`
StartLine uint `json:"start_line"`
}
type Signature struct {
Algorithm string `json:"algorithm"`
Value string `json:"value"`
}
type ScanGlReport struct {
EndTime string `json:"end_time"`
Analyzer Analyzer `json:"analyzer"`
Scanner GlScanner `json:"scanner"`
StartTime string `json:"start_time"`
Status string `json:"status"`
Type string `json:"type"`
}

type Analyzer struct {
ID string `json:"id"`
Name string `json:"name"`
URL string `json:"url"`
Vendor Vendor `json:"vendor"`
Version string `json:"version"`
}
type GlScanner struct {
ID string `json:"id"`
Name string `json:"name"`
}
type Vendor struct {
Name string `json:"name"`
}
type GLSastIdentifiers struct {
Type string `json:"type"`
Name string `json:"name"`
URL string `json:"url"`
Value string `json:"value"`
}
type GlSastTracking struct {
Items []GlSastTrackingItems `json:"items"`
}

type GlSastTrackingItems struct {
Signatures GlSastTrackingItemsSignatures `json:"signatures"`
File string `json:"file"`
EndLine string `json:"end_line"`
StartLine string `json:"start_line"`
}
type GlSastTrackingItemsSignatures struct {
Algorithm string `json:"algorithm"`
Value string `json:"value"`
}
type GlSastFlags struct {
Type string `json:"type"`
Origin string `json:"origin"`
Description string `json:"description"`
}
3 changes: 2 additions & 1 deletion test/integration/result_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ func TestResultListJson(t *testing.T) {
printer.FormatSummaryJSON,
printer.FormatPDF,
printer.FormatSummaryMarkdown,
printer.FormatGL,
}, ",",
),
flag(params.TargetFlag), fileName,
Expand All @@ -60,7 +61,7 @@ func TestResultListJson(t *testing.T) {

// assert all files were created
func assertResultFilesCreated(t *testing.T) {
extensions := []string{printer.FormatJSON, printer.FormatSarif, printer.FormatHTML, printer.FormatJSON, printer.FormatPDF, printer.FormatMarkdown}
extensions := []string{printer.FormatJSON, printer.FormatSarif, printer.FormatHTML, printer.FormatJSON, printer.FormatPDF, printer.FormatMarkdown, printer.FormatGL}

for _, e := range extensions {
_, err := os.Stat(fmt.Sprintf("%s%s.%s", resultsDirectory, fileName, e))
Expand Down

0 comments on commit 5933079

Please sign in to comment.