Skip to content
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

AST_25406 #590

Closed
wants to merge 4 commits into from
Closed
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
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 @@ -850,6 +851,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, "json")
return exportGlSastResults(jsonRpt, results, summary)
}
if printer.IsFormat(format, printer.FormatSummaryConsole) {
return writeConsoleSummary(summary)
}
Expand Down Expand Up @@ -987,7 +992,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 @@ -1219,6 +1245,85 @@ 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)
} /*else if engineType == commonParams.KicsType {
// Add code for KicsType if required.
} else if engineType == commonParams.ScaType {
// Add code for ScaType if required.
}*/
}
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

glSast.Vulnerabilities = append(glSast.Vulnerabilities, wrappers.GlVulnerabilities{
ID: queryName + ":" + fileName + ":" + lineNumber,
Category: wrappers.VendorName + "-" + result.Type,
Name: queryName,
Message: queryName + "@" + fileName + " : " + lineNumber,
Description: result.Description,
CVE: queryName + ":" + fileName + ":" + lineNumber,
Severity: result.Severity,
Confidence: result.Severity,
Solution: "",
Scanner: wrappers.GlScanner{
ID: wrappers.VendorName + "-" + result.Type,
Name: wrappers.VendorName + "-" + result.Type,
},
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
Loading