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

Task # AST-31546 #699

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
175 changes: 173 additions & 2 deletions internal/commands/result.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@
lowLabel = "low"
infoLabel = "info"
sonarTypeLabel = "_sonar"
glSastTypeLobel = ".gl-sast-report"
glSastTypeLabel = ".gl-sast-report"
glDependencyTypeLabel = ".gl-dependency-report"
directoryPermission = 0700
infoSonar = "INFO"
lowSonar = "MINOR"
Expand Down Expand Up @@ -103,6 +104,7 @@
printer.FormatSummaryMarkdown,
printer.FormatSbom,
printer.FormatGL,
printer.FormatGLDependency,
}

var filterResultsListFlagUsage = fmt.Sprintf(
Expand Down Expand Up @@ -200,6 +202,7 @@
printer.FormatPDF,
printer.FormatSummaryMarkdown,
printer.FormatGL,
printer.FormatGLDependency,
)
resultShowCmd.PersistentFlags().String(commonParams.ReportFormatPdfToEmailFlag, "", pdfToEmailFlagDescription)
resultShowCmd.PersistentFlags().String(commonParams.ReportSbomFormatFlag, defaultSbomOption, sbomReportFlagDescription)
Expand Down Expand Up @@ -914,9 +917,14 @@
return exportJSONResults(jsonRpt, results)
}
if printer.IsFormat(format, printer.FormatGL) {
jsonRpt := createTargetName(fmt.Sprintf("%s%s", targetFile, glSastTypeLobel), targetPath, printer.FormatJSON)
jsonRpt := createTargetName(fmt.Sprintf("%s%s", targetFile, glSastTypeLabel), targetPath, printer.FormatJSON)
return exportGlSastResults(jsonRpt, results, summary)
}
if printer.IsFormat(format, printer.FormatGLDependency) {
jsonRpt := createTargetName(fmt.Sprintf("%s%s", targetFile, glDependencyTypeLabel), targetPath, printer.FormatJSON)
return exportGlDependencyResults(jsonRpt, results, summary)
}

if printer.IsFormat(format, printer.FormatSummaryConsole) {
return writeConsoleSummary(summary)
}
Expand Down Expand Up @@ -1080,6 +1088,53 @@
defer f.Close()
return nil
}

func exportGlDependencyResults(targetFile string, results *wrappers.ScanResultsCollection, summary *wrappers.ResultSummary) error {
log.Println("Creating Gl-dependency: ", targetFile)
var glDependencyResult = new(wrappers.GlDependencyResultsCollection)
err := addScanToGlDependencyReport(summary, glDependencyResult)
convertCxResultToGlDependencyVulnerability(results, glDependencyResult, summary.BaseURI)
convertCxResultToGlDependencyFiles(results, glDependencyResult, summary.BaseURI)
resultsJSON, err := json.Marshal(glDependencyResult)
if err != nil {
return errors.Wrapf(err, "%s: failed to serialize gl sast report ", failedListingResults)
}
f, err := os.Create(targetFile)
if err != nil {
return errors.Wrapf(err, "%s: failed to create target file ", failedListingResults)
}
_, _ = fmt.Fprintln(f, string(resultsJSON))
defer f.Close()

return nil
}

func addScanToGlDependencyReport(summary *wrappers.ResultSummary, glDependencyResult *wrappers.GlDependencyResultsCollection) error {
createdAt, err := time.Parse(summaryCreatedAtLayout, summary.CreatedAt)
if err != nil {
return err
}

glDependencyResult.Schema = "https://gitlab.com/gitlab-org/gitlab/-/raw/master/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/sast-report-format.json"

Check failure on line 1118 in internal/commands/result.go

View workflow job for this annotation

GitHub Actions / lint

string `https://gitlab.com/gitlab-org/gitlab/-/raw/master/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/sast-report-format.json` has 2 occurrences, make it a constant (goconst)
glDependencyResult.Version = "15.0.0"

Check failure on line 1119 in internal/commands/result.go

View workflow job for this annotation

GitHub Actions / lint

string `15.0.0` has 2 occurrences, make it a constant (goconst)
glDependencyResult.Scan.Analyzer.VendorGlSCA.VendorGlname = wrappers.AnalyzerScaID
glDependencyResult.Scan.Analyzer.Name = wrappers.AnalyzerScaID
glDependencyResult.Scan.Analyzer.Name = wrappers.AnalyzerScaID
Copy link
Contributor

Choose a reason for hiding this comment

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

duplicate line: glDependencyResult.Scan.Analyzer.Name = wrappers.AnalyzerScaID

glDependencyResult.Scan.Analyzer.Id = wrappers.ScannerId
glDependencyResult.Scan.Scanner.Id = wrappers.ScannerId
glDependencyResult.Scan.Scanner.Name = wrappers.AnalyzerScaID
glDependencyResult.Scan.Scanner.VendorGlSCA.VendorGlname = wrappers.AnalyzerScaID
glDependencyResult.Scan.Status = commonParams.Success
glDependencyResult.Scan.Type = wrappers.ScannerType
glDependencyResult.Scan.StartTime = createdAt.Format(glTimeFormat)
glDependencyResult.Scan.EndTime = createdAt.Format(glTimeFormat)
glDependencyResult.Scan.Scanner.Name = wrappers.AnalyzerScaID
glDependencyResult.Scan.Scanner.VersionGlSca = commonParams.Version
glDependencyResult.Scan.Analyzer.VersionGlSca = commonParams.Version

return nil
}

func addScanToGlSastReport(summary *wrappers.ResultSummary, glSast *wrappers.GlSastResultsCollection) error {
createdAt, err := time.Parse(summaryCreatedAtLayout, summary.CreatedAt)
if err != nil {
Expand Down Expand Up @@ -1374,6 +1429,21 @@
}
}

func convertCxResultToGlDependencyVulnerability(results *wrappers.ScanResultsCollection, glDependencyResult *wrappers.GlDependencyResultsCollection, summaryBaseURI string) {

Check failure on line 1432 in internal/commands/result.go

View workflow job for this annotation

GitHub Actions / lint

`convertCxResultToGlDependencyVulnerability` - `summaryBaseURI` is unused (unparam)
Copy link
Contributor

Choose a reason for hiding this comment

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

Please create a differnet go file that contain only GL logic and call if from the results

for _, result := range results.Results {
if strings.TrimSpace(result.Type) == commonParams.ScaType {
glDependencyResult = parseGlDependencyVulnerability(result, glDependencyResult)
}
}
}

func convertCxResultToGlDependencyFiles(results *wrappers.ScanResultsCollection, glDependencyResult *wrappers.GlDependencyResultsCollection, summaryBaseURI string) {
for _, result := range results.Results {
if strings.TrimSpace(result.Type) == commonParams.ScaType {
glDependencyResult = parseGlDependencyFiles(result, glDependencyResult)
}
}
}
func parseGlSastVulnerability(result *wrappers.ScanResult, glSast *wrappers.GlSastResultsCollection, summaryBaseURI string) *wrappers.GlSastResultsCollection {
queryName := result.ScanResultData.QueryName
fileName := result.ScanResultData.Nodes[0].FileName
Expand Down Expand Up @@ -1429,6 +1499,107 @@
return glSast
}

func parseGlDependencyVulnerability(result *wrappers.ScanResult, glDependencyResult *wrappers.GlDependencyResultsCollection) *wrappers.GlDependencyResultsCollection {

if result.ScanResultData.ScaPackageCollection != nil {

glDependencyResult.Vulnerabilities = append(glDependencyResult.Vulnerabilities, wrappers.GlDepVulnerabilities{
Id: result.ID,
Name: result.VulnerabilityDetails.CveName,
Description: result.Description,
Severity: cases.Title(language.English).String(result.Severity),
Solution: result.ScanResultData.RecommendedVersion,
Identifiers: collectDependencyPackageData(result),
Links: collectDependencyPackageLinks(result),
TrackingDep: wrappers.TrackingDep{
Items: collectDependencyPackageItemsDep(result),
},
Flags: make([]string, 0),
LocationDep: wrappers.GlDepVulnerabilityLocation{
File: *(result.ScanResultData.ScaPackageCollection.Locations[0]),
Dependency: wrappers.DependencyLocation{
Package: wrappers.PackageName{Name: result.ScanResultData.PackageIdentifier},
DependencyLocationVersion: "",
Copy link
Contributor

Choose a reason for hiding this comment

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

you can delete these empty properties, I think it is the same if you don't provide them

Iid: "",
Direct: result.ScanResultData.ScaPackageCollection.IsDirectDependency,
DependencyPath: "",
},
},
})
}
return glDependencyResult
}

func parseGlDependencyFiles(result *wrappers.ScanResult, glDependencyResult *wrappers.GlDependencyResultsCollection) *wrappers.GlDependencyResultsCollection {
if result.ScanResultData.ScaPackageCollection != nil {
glDependencyResult.DependencyFiles = append(glDependencyResult.DependencyFiles, wrappers.DependencyFile{
Path: result.ScanResultData.ScaPackageCollection.ID, ///Need to enter correct File path
PackageManager: result.ScanResultData.ScaPackageCollection.ID, //Need to enter correct Package_manager

Check failure on line 1537 in internal/commands/result.go

View workflow job for this annotation

GitHub Actions / lint

commentFormatting: put a space between `//` and comment text (gocritic)
Dependencies: collectDependencyFileLocations(result),
})
}
return glDependencyResult
}

func collectDependencyFileLocations(result *wrappers.ScanResult) []wrappers.DependencyLocation {
allIdentifierLocations := []wrappers.DependencyLocation{}
for i := 0; i < len(result.ScanResultData.PackageData); i++ {
allIdentifierLocations = append(allIdentifierLocations, wrappers.DependencyLocation{
Package: wrappers.PackageName{
Name: result.ScanResultData.PackageData[i].Type,
},
DependencyLocationVersion: result.ScanResultData.PackageData[i].URL,
Iid: result.ScanResultData.PackageData[i].Type,
Direct: true,
DependencyPath: result.ScanResultData.PackageData[i].Type,
})
}
return allIdentifierLocations
}

func collectDependencyPackageItemsDep(result *wrappers.ScanResult) []wrappers.ItemDep {
allDependencyPackageItemDep := []wrappers.ItemDep{}
if result.ScanResultData.ScaPackageCollection != nil {
allDependencyPackageItemDep = append(allDependencyPackageItemDep, wrappers.ItemDep{
Signature: []wrappers.SignatureDep{{Algorithm: "SCA-Algorithm ", Value: "NA"}},
File: *result.ScanResultData.ScaPackageCollection.DependencyPathArray[0][0].Locations[0],
EndLine: 0,
StartLine: 0,
})
}
return allDependencyPackageItemDep

}

func collectDependencyPackageLinks(result *wrappers.ScanResult) []wrappers.LinkDep {
allDependencyPackageLinks := []wrappers.LinkDep{}
for i := 0; i < len(result.ScanResultData.PackageData); i++ {

allDependencyPackageLinks = append(allDependencyPackageLinks, wrappers.LinkDep{
Name: result.ScanResultData.PackageData[i].Type,
Url: result.ScanResultData.PackageData[i].URL,
})

}
return allDependencyPackageLinks

}

func collectDependencyPackageData(result *wrappers.ScanResult) []wrappers.IdentifierDep {
allIdentifierDep := []wrappers.IdentifierDep{}
for i := 0; i < len(result.ScanResultData.PackageData); i++ {

allIdentifierDep = append(allIdentifierDep, wrappers.IdentifierDep{
Type: result.ScanResultData.PackageData[i].Type,
Value: result.ScanResultData.PackageData[i].URL,
Name: result.ScanResultData.PackageData[i].URL,
})

}
return allIdentifierDep
}

// func IdentifiersPackageData
func convertCxResultsToSonar(results *wrappers.ScanResultsCollection) *wrappers.ScanResultsSonar {
var sonar = new(wrappers.ScanResultsSonar)
sonar.Results = parseResultsSonar(results)
Expand Down
1 change: 1 addition & 0 deletions internal/commands/util/printer/printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const (
FormatSbom = "sbom"
FormatXML = "xml"
FormatGL = "gl-sast"
FormatGLDependency = "gl-dependency"
)

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

const (
AnalyzerScaName = "CxOne"
AnalyzerScaID = AnalyzerScaName + "-SCA"
ScannerId = "SCA"

Check failure on line 6 in internal/wrappers/results-gl-dependency.go

View workflow job for this annotation

GitHub Actions / lint

const `ScannerId` should be `ScannerID` (golint)
ScannerType = "dependency_scanning"
)

type GlDependencyResultsCollection struct {
Scan ScanGlDepReport `json:"scan"`
Schema string `json:"schema"`
Version string `json:"version"`
Vulnerabilities []GlDepVulnerabilities `json:"vulnerabilities"`
DependencyFiles []DependencyFile `json:"dependency_files"`
}

type GlVendor struct {
VendorGlname string `json:"name"`
}

type ScanGlDepReport struct {
EndTime string `json:"end_time,omitempty"`
Analyzer GlDepAnalyzer `json:"analyzer,omitempty"`
Scanner GlDepScanner `json:"scanner,omitempty"`
StartTime string `json:"start_time,omitempty"`
Status string `json:"status,omitempty"`
Type string `json:"type"`
}

type GlDepAnalyzer struct {
Id string `json:"id,omitempty"`

Check failure on line 32 in internal/wrappers/results-gl-dependency.go

View workflow job for this annotation

GitHub Actions / lint

struct field `Id` should be `ID` (golint)
Name string `json:"name,omitempty"`
VendorGlSCA GlVendor `json:"vendor"`
VersionGlSca string `json:"version,omitempty"`
}

type GlDepScanner struct {
Id string `json:"id,omitempty"`

Check failure on line 39 in internal/wrappers/results-gl-dependency.go

View workflow job for this annotation

GitHub Actions / lint

struct field `Id` should be `ID` (golint)
Name string `json:"name,omitempty"`
VersionGlSca string `json:"version,omitempty"`
VendorGlSCA GlVendor `json:"vendor"`
}

type GlDepVulnerabilities struct {
Id string `json:"id"`

Check failure on line 46 in internal/wrappers/results-gl-dependency.go

View workflow job for this annotation

GitHub Actions / lint

struct field `Id` should be `ID` (golint)
Name string `json:"name"`
Description string `json:"description"`
Severity string `json:"severity"`
Solution interface{} `json:"solution"`
Identifiers []IdentifierDep `json:"identifiers"`
Links []LinkDep `json:"links"`
TrackingDep TrackingDep `json:"tracking"`
Flags []string `json:"flags"`
LocationDep GlDepVulnerabilityLocation `json:"location"`
}

type IdentifierDep struct {
Type string `json:"type"`
Name string `json:"name"`
Value string `json:"value"`
}

type LinkDep struct {
Name string `json:"name,omitempty"`
Url string `json:"url,omitempty"`

Check failure on line 66 in internal/wrappers/results-gl-dependency.go

View workflow job for this annotation

GitHub Actions / lint

struct field `Url` should be `URL` (golint)
}

type TrackingDep struct {
Items []ItemDep `json:"items"`
}

type ItemDep struct {
Signature []SignatureDep `json:"signatures"`
File string `json:"file"`
EndLine uint `json:"end_line"`
StartLine uint `json:"start_line"`
}

type SignatureDep struct {
Algorithm string `json:"algorithm"`
Value string `json:"value"`
}

type GlDepVulnerabilityLocation struct {
File string `json:"file"`
Dependency DependencyLocation `json:"dependency"`
}

type DependencyLocation struct {
Package PackageName `json:"package"`
DependencyLocationVersion string `json:"version"`
Iid string `json:"iid"`
Direct bool `json:"direct"`
DependencyPath string `json:"iid"`

Check failure on line 95 in internal/wrappers/results-gl-dependency.go

View workflow job for this annotation

GitHub Actions / lint

structtag: struct field DependencyPath repeats json tag "iid" also at results-gl-dependency.go:93 (govet)
}

type PackageName struct {
Name string `json:"name"`
}

type DependencyFile struct {
Path string `json:"path"`
PackageManager string `json:"package_manager"`
Dependencies []DependencyLocation `json:"dependencies"`
}
Loading