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

feat(sbom): use group field for jar in cyclonedx #4674

Merged
merged 1 commit into from
Jun 22, 2023
Merged
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
2 changes: 2 additions & 0 deletions pkg/sbom/cyclonedx/core/cyclonedx.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ type CycloneDX struct {
type Component struct {
Type cdx.ComponentType
Name string
Group string
Version string
PackageURL *purl.PackageURL
Licenses []string
Expand Down Expand Up @@ -120,6 +121,7 @@ func (c *CycloneDX) MarshalComponent(component *Component, components map[string
BOMRef: bomRef,
Type: component.Type,
Name: component.Name,
Group: component.Group,
Version: component.Version,
PackageURL: c.PackageURL(component.PackageURL),
Supplier: c.Supplier(component.Supplier),
Expand Down
11 changes: 10 additions & 1 deletion pkg/sbom/cyclonedx/marshal.go
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,14 @@ func pkgComponent(pkg Package) (*core.Component, error) {
return nil, xerrors.Errorf("failed to new package purl: %w", err)
}

name := pkg.Name
var group string
// use `group` field for GroupID and `name` for ArtifactID for jar files
if pkg.Type == ftypes.Jar {
name = pu.Name
group = pu.Namespace
}

properties := map[string]string{
PropertyPkgID: pkg.ID,
PropertyPkgType: pkg.Type,
Expand All @@ -305,7 +313,8 @@ func pkgComponent(pkg Package) (*core.Component, error) {

return &core.Component{
Type: cdx.ComponentTypeLibrary,
Name: pkg.Name,
Name: name,
Group: group,
Version: pu.Version,
PackageURL: &pu,
Supplier: pkg.Maintainer,
Expand Down
35 changes: 35 additions & 0 deletions pkg/sbom/cyclonedx/marshal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1045,6 +1045,18 @@ func TestMarshaler_Marshal(t *testing.T) {
},
},
},
{
Target: "Java",
Class: types.ClassLangPkg,
Type: ftypes.Jar,
Packages: []ftypes.Package{
{
Name: "org.springframework:spring-web",
Version: "5.3.22",
FilePath: "spring-web-5.3.22.jar",
},
},
},
},
},
want: &cdx.BOM{
Expand Down Expand Up @@ -1103,13 +1115,32 @@ func TestMarshaler_Marshal(t *testing.T) {
},
},
},
{
BOMRef: "pkg:maven/org.springframework/spring-web@5.3.22?file_path=spring-web-5.3.22.jar",
Type: "library",
Name: "spring-web",
Group: "org.springframework",
Version: "5.3.22",
PackageURL: "pkg:maven/org.springframework/spring-web@5.3.22",
Properties: &[]cdx.Property{
{
Name: "aquasecurity:trivy:FilePath",
Value: "spring-web-5.3.22.jar",
},
{
Name: "aquasecurity:trivy:PkgType",
Value: "jar",
},
},
},
},
Vulnerabilities: &[]cdx.Vulnerability{},
Dependencies: &[]cdx.Dependency{
{
Ref: "3ff14136-e09f-4df9-80ea-000000000002",
Dependencies: &[]string{
"3ff14136-e09f-4df9-80ea-000000000003",
"pkg:maven/org.springframework/spring-web@5.3.22?file_path=spring-web-5.3.22.jar",
},
},
{
Expand All @@ -1122,6 +1153,10 @@ func TestMarshaler_Marshal(t *testing.T) {
Ref: "pkg:gem/actioncable@6.1.4.1",
Dependencies: lo.ToPtr([]string{}),
},
{
Ref: "pkg:maven/org.springframework/spring-web@5.3.22?file_path=spring-web-5.3.22.jar",
Dependencies: lo.ToPtr([]string{}),
},
},
},
},
Expand Down
3 changes: 2 additions & 1 deletion pkg/sbom/cyclonedx/testdata/happy/bom.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@
{
"bom-ref": "pkg:maven/org.codehaus.mojo/child-project@1.0?file_path=app%2Fmaven%2Ftarget%2Fchild-project-1.0.jar",
"type": "library",
"name": "org.codehaus.mojo:child-project",
"name": "child-project",
"group": "org.codehaus.mojo",
"version": "1.0",
"purl": "pkg:maven/org.codehaus.mojo/child-project@1.0",
"properties": [
Expand Down
59 changes: 59 additions & 0 deletions pkg/sbom/cyclonedx/testdata/happy/group-in-name.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
{
"bomFormat": "CycloneDX",
"specVersion": "1.4",
"serialNumber": "urn:uuid:8366a7c8-229c-4518-b86c-8a1bcf69af01",
"version": 1,
"metadata": {
"timestamp": "2023-06-20T04:32:10+00:00",
"tools": [
{
"vendor": "aquasecurity",
"name": "trivy",
"version": "0.42.1"
}
],
"component": {
"bom-ref": "b0ae8323-eb7b-4be5-bc5c-4849fd795ec0",
"type": "application",
"name": "spring-web-5.3.22.jar",
"properties": [
{
"name": "aquasecurity:trivy:SchemaVersion",
"value": "2"
}
]
}
},
"components": [
{
"bom-ref": "pkg:maven/org.springframework/spring-web@5.3.22?file_path=spring-web-5.3.22.jar",
"type": "library",
"name": "org.springframework:spring-web",
"version": "5.3.22",
"purl": "pkg:maven/org.springframework/spring-web@5.3.22",
"properties": [
{
"name": "aquasecurity:trivy:FilePath",
"value": "spring-web-5.3.22.jar"
},
{
"name": "aquasecurity:trivy:PkgType",
"value": "jar"
}
]
}
],
"dependencies": [
{
"ref": "b0ae8323-eb7b-4be5-bc5c-4849fd795ec0",
"dependsOn": [
"pkg:maven/org.springframework/spring-web@5.3.22?file_path=spring-web-5.3.22.jar"
]
},
{
"ref": "pkg:maven/org.springframework/spring-web@5.3.22?file_path=spring-web-5.3.22.jar",
"dependsOn": []
}
],
"vulnerabilities": []
}
12 changes: 11 additions & 1 deletion pkg/sbom/cyclonedx/unmarshal.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ package cyclonedx
import (
"bytes"
"errors"
"fmt"
"io"
"sort"
"strconv"

"github.com/aquasecurity/trivy/pkg/sbom/cyclonedx/core"

cdx "github.com/CycloneDX/cyclonedx-go"
"github.com/package-url/packageurl-go"
"github.com/samber/lo"
"golang.org/x/exp/maps"
"golang.org/x/xerrors"
Expand Down Expand Up @@ -344,7 +346,7 @@ func toPackage(component cdx.Component) (bool, string, *ftypes.Package, error) {
pkg := p.Package()
// Trivy's marshall loses case-sensitivity in PURL used in SBOM for packages (Go, Npm, PyPI),
// so we have to use an original package name
pkg.Name = component.Name
pkg.Name = getPackageName(p.Type, component)
pkg.Ref = component.BOMRef

for _, license := range lo.FromPtr(component.Licenses) {
Expand Down Expand Up @@ -405,3 +407,11 @@ func toTrivyCdxComponent(component cdx.Component) ftypes.Component {
PackageURL: component.PackageURL,
}
}

func getPackageName(typ string, component cdx.Component) string {
// Jar uses `Group` field for `GroupID`
if typ == packageurl.TypeMaven && component.Group != "" {
return fmt.Sprintf("%s:%s", component.Group, component.Name)
}
return component.Name
}
Comment on lines +411 to +417
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think it should be done here. What do you think?

trivy/pkg/purl/purl.go

Lines 73 to 85 in df61fd4

if p.Type == packageurl.TypeMaven || p.Type == ftypes.Gradle {
// Maven and Gradle packages separate ":"
// e.g. org.springframework:spring-core
pkg.Name = strings.Join([]string{
p.Namespace,
p.Name,
}, ":")
} else {
pkg.Name = strings.Join([]string{
p.Namespace,
p.Name,
}, "/")
}

Copy link
Collaborator

Choose a reason for hiding this comment

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

Or is PURL missing groupID?

Copy link
Contributor Author

@DmitriyLewen DmitriyLewen Jun 20, 2023

Choose a reason for hiding this comment

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

we use component.Name after this PR - https://github.com/aquasecurity/trivy/pull/4306/files#diff-caf585364b1a95f5cb5dbda210a5ca931fad058915ba586540c8aa32a7883311R346

But maybe it's better to use the purl name for jars. Wdyt?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Oh, I just remember the change. OK, so we can go with your change.

19 changes: 19 additions & 0 deletions pkg/sbom/cyclonedx/unmarshal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,25 @@ func TestUnmarshaler_Unmarshal(t *testing.T) {
},
},
},
{
name: "happy path for jar where name is GroupID and ArtifactID",
inputFile: "testdata/happy/group-in-name.json",
want: types.SBOM{
Applications: []ftypes.Application{
{
Type: "jar",
Libraries: []ftypes.Package{
{
Name: "org.springframework:spring-web",
Version: "5.3.22",
Ref: "pkg:maven/org.springframework/spring-web@5.3.22?file_path=spring-web-5.3.22.jar",
FilePath: "spring-web-5.3.22.jar",
},
},
},
},
},
},
{
name: "happy path only os component",
inputFile: "testdata/happy/os-only-bom.json",
Expand Down