1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2025-02-21 19:48:53 +02:00

Fix SBOM component generation (#3958)

* Further improve library types

* Fix translate

* Added debug output

* Enhance data

* Added debug output

* Fix code

* Added test

* Fix test
This commit is contained in:
Sven Merk 2022-08-12 11:59:47 +02:00 committed by GitHub
parent 374cdb777b
commit 21416d82ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 70 additions and 12 deletions

View File

@ -585,16 +585,20 @@ func checkSecurityViolations(ctx context.Context, config *ScanOptions, scan *ws.
allLibraries := []ws.Library{}
for _, project := range scan.ScannedProjects() {
// collect errors and aggregate vulnerabilities from all projects
if vulCount, alerts, err := checkProjectSecurityViolations(config, cvssSeverityLimit, project, sys, assessments, influx); err != nil {
allAlerts = append(allAlerts, alerts...)
vulnerabilitiesCount += vulCount
vulCount, alerts, err := checkProjectSecurityViolations(config, cvssSeverityLimit, project, sys, assessments, influx)
if err != nil {
errorsOccured = append(errorsOccured, fmt.Sprint(err))
}
allAlerts = append(allAlerts, alerts...)
vulnerabilitiesCount += vulCount
// collect all libraries detected in all related projects and errors
if libraries, err := sys.GetProjectHierarchy(project.Token, true); err != nil {
allLibraries = append(allLibraries, libraries...)
libraries, err := sys.GetProjectHierarchy(project.Token, true)
if err != nil {
errorsOccured = append(errorsOccured, fmt.Sprint(err))
}
log.Entry().Debugf("Collected %v libraries for project %v", len(libraries), project.Name)
allLibraries = append(allLibraries, libraries...)
}
log.Entry().Debugf("Aggregated %v alerts for scanned projects", len(allAlerts))

View File

@ -379,8 +379,9 @@ func CreateCycloneSBOM(scan *Scan, libraries *[]Library, alerts *[]Alert) ([]byt
components := []cdx.Component{}
flatUniqueLibrariesMap := map[string]Library{}
transformToUniqueFlatList(libraries, &flatUniqueLibrariesMap)
transformToUniqueFlatList(libraries, &flatUniqueLibrariesMap, 1)
flatUniqueLibraries := piperutils.Values(flatUniqueLibrariesMap)
log.Entry().Debugf("Got %v unique libraries in condensed flat list", len(flatUniqueLibraries))
sort.Slice(flatUniqueLibraries, func(i, j int) bool {
return flatUniqueLibraries[i].ToPackageUrl().ToString() < flatUniqueLibraries[j].ToPackageUrl().ToString()
})
@ -395,6 +396,7 @@ func CreateCycloneSBOM(scan *Scan, libraries *[]Library, alerts *[]Alert) ([]byt
Name: lib.ArtifactID,
Version: lib.Version,
PackageURL: purl.ToString(),
Hashes: &[]cdx.Hash{{Algorithm: cdx.HashAlgoSHA1, Value: lib.Sha1}},
}
components = append(components, component)
}
@ -513,7 +515,8 @@ func WriteCycloneSBOM(sbom []byte, utils piperutils.FileUtils) ([]piperutils.Pat
return paths, nil
}
func transformToUniqueFlatList(libraries *[]Library, flatMapRef *map[string]Library) {
func transformToUniqueFlatList(libraries *[]Library, flatMapRef *map[string]Library, level int) {
log.Entry().Debugf("Got %v libraries reported on level %v", len(*libraries), level)
for _, lib := range *libraries {
key := lib.ToPackageUrl().ToString()
flatMap := *flatMapRef
@ -521,7 +524,7 @@ func transformToUniqueFlatList(libraries *[]Library, flatMapRef *map[string]Libr
if lookup.KeyID != lib.KeyID {
flatMap[key] = lib
if len(lib.Dependencies) > 0 {
transformToUniqueFlatList(&lib.Dependencies, flatMapRef)
transformToUniqueFlatList(&lib.Dependencies, flatMapRef, level+1)
}
}

View File

@ -273,7 +273,6 @@ func TestWriteSarifFile(t *testing.T) {
}
func TestCountSecurityVulnerabilities(t *testing.T) {
t.Parallel()
alerts := []Alert{
{Vulnerability: Vulnerability{CVSS3Score: 7.1}},

View File

@ -17,24 +17,36 @@
<author>apache-commons</author>
<name>commons-lang</name>
<version>2.4.30</version>
<hashes>
<hash alg="SHA-1"></hash>
</hashes>
<purl>pkg:maven/apache-commons/commons-lang@2.4.30</purl>
</component>
<component bom-ref="pkg:maven/apache-commons/commons-lang@3.15" type="library">
<author>apache-commons</author>
<name>commons-lang</name>
<version>3.15</version>
<hashes>
<hash alg="SHA-1"></hash>
</hashes>
<purl>pkg:maven/apache-commons/commons-lang@3.15</purl>
</component>
<component bom-ref="pkg:maven/apache-logging/log4j@1.14" type="library">
<author>apache-logging</author>
<name>log4j</name>
<version>1.14</version>
<hashes>
<hash alg="SHA-1"></hash>
</hashes>
<purl>pkg:maven/apache-logging/log4j@1.14</purl>
</component>
<component bom-ref="pkg:maven/apache-logging/log4j@3.25" type="library">
<author>apache-logging</author>
<name>log4j</name>
<version>3.25</version>
<hashes>
<hash alg="SHA-1"></hash>
</hashes>
<purl>pkg:maven/apache-logging/log4j@3.25</purl>
</component>
</components>

View File

@ -92,22 +92,32 @@ func transformLibToPurlType(libType string) string {
log.Entry().Debugf("LibType reported as %v", libType)
switch strings.ToLower(libType) {
case "java":
fallthrough
case "maven_artifact":
return packageurl.TypeMaven
case "javascript/node.js":
fallthrough
case "node_packaged_module":
return packageurl.TypeNPM
case "javascript/bower":
return "bower"
case "go":
fallthrough
case "go_package":
return packageurl.TypeGolang
case "python":
fallthrough
case "python_package":
return packageurl.TypePyPi
case "debian":
fallthrough
case "debian_package":
return packageurl.TypeDebian
case "docker":
return packageurl.TypeDocker
case "source library":
return "src"
case ".net":
fallthrough
case "dot_net_resource":
return packageurl.TypeNuget
}
return packageurl.TypeGeneric

View File

@ -10,6 +10,7 @@ import (
"time"
piperhttp "github.com/SAP/jenkins-library/pkg/http"
"github.com/package-url/packageurl-go"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@ -295,6 +296,32 @@ func TestGetProductName(t *testing.T) {
assert.Equal(t, "Test Product", productName)
}
func TestTransformLibToPurlType(t *testing.T) {
tt := []struct {
libType string
expected string
}{
{libType: "Java", expected: packageurl.TypeMaven},
{libType: "MAVEN_ARTIFACT", expected: packageurl.TypeMaven},
{libType: "javascript/Node.js", expected: packageurl.TypeNPM},
{libType: "node_packaged_module", expected: packageurl.TypeNPM},
{libType: "javascript/bower", expected: "bower"},
{libType: "go", expected: packageurl.TypeGolang},
{libType: "go_package", expected: packageurl.TypeGolang},
{libType: "python", expected: packageurl.TypePyPi},
{libType: "python_package", expected: packageurl.TypePyPi},
{libType: "debian", expected: packageurl.TypeDebian},
{libType: "debian_package", expected: packageurl.TypeDebian},
{libType: "docker", expected: packageurl.TypeDocker},
{libType: ".net", expected: packageurl.TypeNuget},
{libType: "dot_net_resource", expected: packageurl.TypeNuget},
}
for i, test := range tt {
assert.Equalf(t, test.expected, transformLibToPurlType(test.libType), "run %v failed", i)
}
}
func TestGetProjectHierarchy(t *testing.T) {
myTestClient := whitesourceMockClient{
responseBody: `{
@ -411,7 +438,10 @@ func TestGetProjectHierarchy(t *testing.T) {
}
]
}
]
],
"warningMessages":[
"Invalid input: orgToken"
]
}`,
}