mirror of
https://github.com/SAP/jenkins-library.git
synced 2025-03-03 15:02:35 +02:00
fix(whitesourceExecuteScan): failOnSevereVulnerabilities (#3894)
* fix(whitesourceExecuteScan): failOnSevereVulnerabilities failOnSevereVulnerabilities has not been considered properly for security vulnerabilities. * chore: remove comment * chore: update formatting
This commit is contained in:
parent
bc974ffdd2
commit
890c437c3f
@ -452,7 +452,6 @@ func wsScanOptions(config *ScanOptions) *ws.ScanOptions {
|
||||
// Unified Agent is the only supported option by WhiteSource going forward:
|
||||
// The Unified Agent will be used to perform the scan.
|
||||
func executeScan(config *ScanOptions, scan *ws.Scan, utils whitesourceUtils) error {
|
||||
|
||||
options := wsScanOptions(config)
|
||||
|
||||
// Execute scan with Unified Agent jar file
|
||||
@ -463,7 +462,6 @@ func executeScan(config *ScanOptions, scan *ws.Scan, utils whitesourceUtils) err
|
||||
}
|
||||
|
||||
func checkPolicyViolations(config *ScanOptions, scan *ws.Scan, sys whitesource, utils whitesourceUtils, reportPaths []piperutils.Path, influx *whitesourceExecuteScanInflux) (piperutils.Path, error) {
|
||||
|
||||
policyViolationCount := 0
|
||||
for _, project := range scan.ScannedProjects() {
|
||||
alerts, err := sys.GetProjectAlertsByType(project.Token, "REJECTED_BY_POLICY_RESOURCE")
|
||||
@ -491,7 +489,7 @@ func checkPolicyViolations(config *ScanOptions, scan *ws.Scan, sys whitesource,
|
||||
}
|
||||
|
||||
jsonViolationReportPath := filepath.Join(ws.ReportsDirectory, "whitesource-ip.json")
|
||||
err = utils.FileWrite(jsonViolationReportPath, violationContent, 0666)
|
||||
err = utils.FileWrite(jsonViolationReportPath, violationContent, 0o666)
|
||||
if err != nil {
|
||||
return piperutils.Path{}, fmt.Errorf("failed to write policy violation report: %w", err)
|
||||
}
|
||||
@ -516,12 +514,12 @@ func checkPolicyViolations(config *ScanOptions, scan *ws.Scan, sys whitesource,
|
||||
// ignore JSON errors since structure is in our hands
|
||||
jsonReport, _ := ipReport.ToJSON()
|
||||
if exists, _ := utils.DirExists(reporting.StepReportDirectory); !exists {
|
||||
err := utils.MkdirAll(reporting.StepReportDirectory, 0777)
|
||||
err := utils.MkdirAll(reporting.StepReportDirectory, 0o777)
|
||||
if err != nil {
|
||||
return policyReport, errors.Wrap(err, "failed to create reporting directory")
|
||||
}
|
||||
}
|
||||
if err := utils.FileWrite(filepath.Join(reporting.StepReportDirectory, fmt.Sprintf("whitesourceExecuteScan_ip_%v.json", ws.ReportSha(config.ProductName, scan))), jsonReport, 0666); err != nil {
|
||||
if err := utils.FileWrite(filepath.Join(reporting.StepReportDirectory, fmt.Sprintf("whitesourceExecuteScan_ip_%v.json", ws.ReportSha(config.ProductName, scan))), jsonReport, 0o666); err != nil {
|
||||
return policyReport, errors.Wrapf(err, "failed to write json report")
|
||||
}
|
||||
// we do not add the json report to the overall list of reports for now,
|
||||
@ -555,7 +553,7 @@ func checkSecurityViolations(config *ScanOptions, scan *ws.Scan, sys whitesource
|
||||
project := ws.Project{Name: config.ProjectName, Token: config.ProjectToken}
|
||||
// ToDo: see if HTML report generation is really required here
|
||||
// we anyway need to do some refactoring here since config.ProjectToken != "" essentially indicates an aggregated project
|
||||
if _, _, err := checkProjectSecurityViolations(cvssSeverityLimit, project, sys, influx); err != nil {
|
||||
if _, _, err := checkProjectSecurityViolations(config, cvssSeverityLimit, project, sys, influx); err != nil {
|
||||
return reportPaths, err
|
||||
}
|
||||
} else {
|
||||
@ -564,7 +562,7 @@ func checkSecurityViolations(config *ScanOptions, scan *ws.Scan, sys whitesource
|
||||
allAlerts := []ws.Alert{}
|
||||
for _, project := range scan.ScannedProjects() {
|
||||
// collect errors and aggregate vulnerabilities from all projects
|
||||
if vulCount, alerts, err := checkProjectSecurityViolations(cvssSeverityLimit, project, sys, influx); err != nil {
|
||||
if vulCount, alerts, err := checkProjectSecurityViolations(config, cvssSeverityLimit, project, sys, influx); err != nil {
|
||||
allAlerts = append(allAlerts, alerts...)
|
||||
vulnerabilitiesCount += vulCount
|
||||
errorsOccured = append(errorsOccured, fmt.Sprint(err))
|
||||
@ -607,7 +605,7 @@ func checkSecurityViolations(config *ScanOptions, scan *ws.Scan, sys whitesource
|
||||
}
|
||||
|
||||
// checkSecurityViolations checks security violations and returns an error if the configured severity limit is crossed.
|
||||
func checkProjectSecurityViolations(cvssSeverityLimit float64, project ws.Project, sys whitesource, influx *whitesourceExecuteScanInflux) (int, []ws.Alert, error) {
|
||||
func checkProjectSecurityViolations(config *ScanOptions, cvssSeverityLimit float64, project ws.Project, sys whitesource, influx *whitesourceExecuteScanInflux) (int, []ws.Alert, error) {
|
||||
// get project alerts (vulnerabilities)
|
||||
alerts, err := sys.GetProjectAlertsByType(project.Token, "SECURITY_VULNERABILITY")
|
||||
if err != nil {
|
||||
@ -628,10 +626,13 @@ func checkProjectSecurityViolations(cvssSeverityLimit float64, project ws.Projec
|
||||
}
|
||||
// https://github.com/SAP/jenkins-library/blob/master/vars/whitesourceExecuteScan.groovy#L558
|
||||
if severeVulnerabilities > 0 {
|
||||
log.SetErrorCategory(log.ErrorCompliance)
|
||||
return severeVulnerabilities, alerts, fmt.Errorf("%v Open Source Software Security vulnerabilities with CVSS score greater "+
|
||||
"or equal to %.1f detected in project %s",
|
||||
severeVulnerabilities, cvssSeverityLimit, project.Name)
|
||||
if config.FailOnSevereVulnerabilities {
|
||||
log.SetErrorCategory(log.ErrorCompliance)
|
||||
return severeVulnerabilities, alerts, fmt.Errorf("%v Open Source Software Security vulnerabilities with CVSS score greater or equal to %.1f detected in project %s", severeVulnerabilities, cvssSeverityLimit, project.Name)
|
||||
}
|
||||
log.Entry().Infof("%v Open Source Software Security vulnerabilities with CVSS score greater or equal to %.1f detected in project %s", severeVulnerabilities, cvssSeverityLimit, project.Name)
|
||||
log.Entry().Info("Step will only create data but not fail due to setting failOnSevereVulnerabilities: false")
|
||||
return severeVulnerabilities, alerts, nil
|
||||
}
|
||||
return 0, alerts, nil
|
||||
}
|
||||
@ -687,7 +688,7 @@ func aggregateVersionWideVulnerabilities(config *ScanOptions, utils whitesourceU
|
||||
}
|
||||
|
||||
reportPath := filepath.Join(ws.ReportsDirectory, "project-names-aggregated.txt")
|
||||
if err := utils.FileWrite(reportPath, []byte(projectNames), 0666); err != nil {
|
||||
if err := utils.FileWrite(reportPath, []byte(projectNames), 0o666); err != nil {
|
||||
return errors.Wrapf(err, "failed to write report: %s", reportPath)
|
||||
}
|
||||
if err := newVulnerabilityExcelReport(versionWideAlerts, config, utils); err != nil {
|
||||
@ -716,13 +717,13 @@ func newVulnerabilityExcelReport(alerts []ws.Alert, config *ScanOptions, utils w
|
||||
return err
|
||||
}
|
||||
|
||||
if err := utils.MkdirAll(ws.ReportsDirectory, 0777); err != nil {
|
||||
if err := utils.MkdirAll(ws.ReportsDirectory, 0o777); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fileName := filepath.Join(ws.ReportsDirectory,
|
||||
fmt.Sprintf("vulnerabilities-%s.xlsx", utils.Now().Format(wsReportTimeStampLayout)))
|
||||
stream, err := utils.FileOpen(fileName, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0666)
|
||||
stream, err := utils.FileOpen(fileName, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0o666)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -781,14 +782,14 @@ func newLibraryCSVReport(libraries map[string][]ws.Library, config *ScanOptions,
|
||||
}
|
||||
|
||||
// Ensure reporting directory exists
|
||||
if err := utils.MkdirAll(ws.ReportsDirectory, 0777); err != nil {
|
||||
if err := utils.MkdirAll(ws.ReportsDirectory, 0o777); err != nil {
|
||||
return errors.Wrapf(err, "failed to create directories: %s", ws.ReportsDirectory)
|
||||
}
|
||||
|
||||
// Write result to file
|
||||
fileName := fmt.Sprintf("%s/libraries-%s.csv", ws.ReportsDirectory,
|
||||
utils.Now().Format(wsReportTimeStampLayout))
|
||||
if err := utils.FileWrite(fileName, []byte(output), 0666); err != nil {
|
||||
if err := utils.FileWrite(fileName, []byte(output), 0o666); err != nil {
|
||||
return errors.Wrapf(err, "failed to write file: %s", fileName)
|
||||
}
|
||||
filePath := piperutils.Path{Name: "aggregated-libraries", Target: fileName}
|
||||
|
@ -192,12 +192,13 @@ func TestCheckAndReportScanResults(t *testing.T) {
|
||||
t.Run("check vulnerabilities - limit exceeded", func(t *testing.T) {
|
||||
// init
|
||||
config := &ScanOptions{
|
||||
ProductToken: "mock-product-token",
|
||||
ProjectName: "mock-project - 1",
|
||||
ProjectToken: "mock-project-token",
|
||||
Version: "1",
|
||||
SecurityVulnerabilities: true,
|
||||
CvssSeverityLimit: "4",
|
||||
ProductToken: "mock-product-token",
|
||||
ProjectName: "mock-project - 1",
|
||||
ProjectToken: "mock-project-token",
|
||||
Version: "1",
|
||||
SecurityVulnerabilities: true,
|
||||
CvssSeverityLimit: "4",
|
||||
FailOnSevereVulnerabilities: true,
|
||||
}
|
||||
scan := newWhitesourceScan(config)
|
||||
utils := newWhitesourceUtilsMock()
|
||||
@ -534,7 +535,8 @@ func TestCheckSecurityViolations(t *testing.T) {
|
||||
|
||||
t.Run("error - non-aggregated", func(t *testing.T) {
|
||||
config := ScanOptions{
|
||||
CvssSeverityLimit: "5",
|
||||
CvssSeverityLimit: "5",
|
||||
FailOnSevereVulnerabilities: true,
|
||||
}
|
||||
scan := newWhitesourceScan(&config)
|
||||
scan.AppendScannedProject("testProject1")
|
||||
@ -554,8 +556,9 @@ func TestCheckSecurityViolations(t *testing.T) {
|
||||
|
||||
t.Run("error - aggregated", func(t *testing.T) {
|
||||
config := ScanOptions{
|
||||
CvssSeverityLimit: "5",
|
||||
ProjectToken: "theProjectToken",
|
||||
CvssSeverityLimit: "5",
|
||||
ProjectToken: "theProjectToken",
|
||||
FailOnSevereVulnerabilities: true,
|
||||
}
|
||||
scan := newWhitesourceScan(&config)
|
||||
systemMock := ws.NewSystemMock("ignored")
|
||||
@ -579,7 +582,7 @@ func TestCheckProjectSecurityViolations(t *testing.T) {
|
||||
systemMock.Alerts = []ws.Alert{}
|
||||
influx := whitesourceExecuteScanInflux{}
|
||||
|
||||
severeVulnerabilities, alerts, err := checkProjectSecurityViolations(7.0, project, systemMock, &influx)
|
||||
severeVulnerabilities, alerts, err := checkProjectSecurityViolations(&ScanOptions{FailOnSevereVulnerabilities: true}, 7.0, project, systemMock, &influx)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 0, severeVulnerabilities)
|
||||
assert.Equal(t, 0, len(alerts))
|
||||
@ -593,7 +596,7 @@ func TestCheckProjectSecurityViolations(t *testing.T) {
|
||||
}
|
||||
influx := whitesourceExecuteScanInflux{}
|
||||
|
||||
severeVulnerabilities, alerts, err := checkProjectSecurityViolations(7.0, project, systemMock, &influx)
|
||||
severeVulnerabilities, alerts, err := checkProjectSecurityViolations(&ScanOptions{FailOnSevereVulnerabilities: true}, 7.0, project, systemMock, &influx)
|
||||
assert.Contains(t, fmt.Sprint(err), "1 Open Source Software Security vulnerabilities")
|
||||
assert.Equal(t, 1, severeVulnerabilities)
|
||||
assert.Equal(t, 2, len(alerts))
|
||||
@ -604,7 +607,7 @@ func TestCheckProjectSecurityViolations(t *testing.T) {
|
||||
systemMock.AlertError = fmt.Errorf("failed to read alerts")
|
||||
influx := whitesourceExecuteScanInflux{}
|
||||
|
||||
_, _, err := checkProjectSecurityViolations(7.0, project, systemMock, &influx)
|
||||
_, _, err := checkProjectSecurityViolations(&ScanOptions{FailOnSevereVulnerabilities: true}, 7.0, project, systemMock, &influx)
|
||||
assert.Contains(t, fmt.Sprint(err), "failed to retrieve project alerts from WhiteSource")
|
||||
})
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user