mirror of
https://github.com/anchore/syft.git
synced 2026-11-01 23:16:30 +01:00
feat: Record where CPEs come from (#2552)
Syft can get CPEs from several source, including generating them based on package data, finding them in the NVD CPE dictionary, or finding them declared in a manifest or existing SBOM. Record where Syft got CPEs so that consumers of SBOMs can reason about how trustworthy they are. Signed-off-by: Will Murphy <will.murphy@anchore.com>
This commit is contained in:
@@ -12,7 +12,7 @@ func encodeSingleCPE(p pkg.Package) string {
|
||||
// Since the CPEs in a package are sorted by specificity
|
||||
// we can extract the first CPE as the one to output in cyclonedx
|
||||
if len(p.CPEs) > 0 {
|
||||
return p.CPEs[0].String()
|
||||
return p.CPEs[0].Attributes.String()
|
||||
}
|
||||
return ""
|
||||
}
|
||||
@@ -25,7 +25,7 @@ func encodeCPEs(p pkg.Package) (out []cyclonedx.Property) {
|
||||
}
|
||||
out = append(out, cyclonedx.Property{
|
||||
Name: "syft:cpe23",
|
||||
Value: c.String(),
|
||||
Value: c.Attributes.String(),
|
||||
})
|
||||
}
|
||||
return
|
||||
@@ -33,7 +33,7 @@ func encodeCPEs(p pkg.Package) (out []cyclonedx.Property) {
|
||||
|
||||
func decodeCPEs(c *cyclonedx.Component) (out []cpe.CPE) {
|
||||
if c.CPE != "" {
|
||||
cp, err := cpe.New(c.CPE)
|
||||
cp, err := cpe.New(c.CPE, cpe.DeclaredSource)
|
||||
if err != nil {
|
||||
log.Warnf("invalid CPE: %s", c.CPE)
|
||||
} else {
|
||||
@@ -44,7 +44,7 @@ func decodeCPEs(c *cyclonedx.Component) (out []cpe.CPE) {
|
||||
if c.Properties != nil {
|
||||
for _, p := range *c.Properties {
|
||||
if p.Name == "syft:cpe23" {
|
||||
cp, err := cpe.New(p.Value)
|
||||
cp, err := cpe.New(p.Value, cpe.DeclaredSource)
|
||||
if err != nil {
|
||||
log.Warnf("invalid CPE: %s", p.Value)
|
||||
} else {
|
||||
|
||||
@@ -10,8 +10,8 @@ import (
|
||||
)
|
||||
|
||||
func Test_encodeCPE(t *testing.T) {
|
||||
testCPE := cpe.Must("cpe:2.3:a:name:name:3.2:*:*:*:*:*:*:*")
|
||||
testCPE2 := cpe.Must("cpe:2.3:a:name:name2:3.2:*:*:*:*:*:*:*")
|
||||
testCPE := cpe.Must("cpe:2.3:a:name:name:3.2:*:*:*:*:*:*:*", "test-source")
|
||||
testCPE2 := cpe.Must("cpe:2.3:a:name:name2:3.2:*:*:*:*:*:*:*", "test-source-2")
|
||||
tests := []struct {
|
||||
name string
|
||||
input pkg.Package
|
||||
@@ -26,7 +26,7 @@ func Test_encodeCPE(t *testing.T) {
|
||||
expected: "",
|
||||
},
|
||||
{
|
||||
name: "single CPE",
|
||||
name: "single Attributes",
|
||||
input: pkg.Package{
|
||||
CPEs: []cpe.CPE{
|
||||
testCPE,
|
||||
|
||||
@@ -222,7 +222,7 @@ func Test_decode(t *testing.T) {
|
||||
if e.cpe != "" {
|
||||
foundCPE := false
|
||||
for _, c := range p.CPEs {
|
||||
cstr := c.BindToFmtString()
|
||||
cstr := c.Attributes.BindToFmtString()
|
||||
if e.cpe == cstr {
|
||||
foundCPE = true
|
||||
break
|
||||
|
||||
@@ -10,7 +10,7 @@ func ExternalRefs(p pkg.Package) (externalRefs []ExternalRef) {
|
||||
for _, c := range p.CPEs {
|
||||
externalRefs = append(externalRefs, ExternalRef{
|
||||
ReferenceCategory: SecurityReferenceCategory,
|
||||
ReferenceLocator: c.String(),
|
||||
ReferenceLocator: c.Attributes.String(),
|
||||
ReferenceType: Cpe23ExternalRefType,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
)
|
||||
|
||||
func Test_ExternalRefs(t *testing.T) {
|
||||
testCPE := cpe.Must("cpe:2.3:a:name:name:3.2:*:*:*:*:*:*:*")
|
||||
testCPE := cpe.Must("cpe:2.3:a:name:name:3.2:*:*:*:*:*:*:*", cpe.Source(""))
|
||||
tests := []struct {
|
||||
name string
|
||||
input pkg.Package
|
||||
@@ -27,7 +27,7 @@ func Test_ExternalRefs(t *testing.T) {
|
||||
expected: []ExternalRef{
|
||||
{
|
||||
ReferenceCategory: SecurityReferenceCategory,
|
||||
ReferenceLocator: testCPE.String(),
|
||||
ReferenceLocator: testCPE.Attributes.String(),
|
||||
ReferenceType: Cpe23ExternalRefType,
|
||||
},
|
||||
{
|
||||
|
||||
@@ -123,7 +123,7 @@ func newDirectoryCatalog() *pkg.Collection {
|
||||
},
|
||||
PURL: "a-purl-2", // intentionally a bad pURL for test fixtures
|
||||
CPEs: []cpe.CPE{
|
||||
cpe.Must("cpe:2.3:*:some:package:2:*:*:*:*:*:*:*"),
|
||||
cpe.Must("cpe:2.3:*:some:package:2:*:*:*:*:*:*:*", cpe.Source("")),
|
||||
},
|
||||
})
|
||||
catalog.Add(pkg.Package{
|
||||
@@ -140,7 +140,7 @@ func newDirectoryCatalog() *pkg.Collection {
|
||||
},
|
||||
PURL: "pkg:deb/debian/package-2@2.0.1",
|
||||
CPEs: []cpe.CPE{
|
||||
cpe.Must("cpe:2.3:*:some:package:2:*:*:*:*:*:*:*"),
|
||||
cpe.Must("cpe:2.3:*:some:package:2:*:*:*:*:*:*:*", cpe.Source("")),
|
||||
},
|
||||
})
|
||||
|
||||
@@ -175,7 +175,7 @@ func newDirectoryCatalogWithAuthorField() *pkg.Collection {
|
||||
},
|
||||
PURL: "a-purl-2", // intentionally a bad pURL for test fixtures
|
||||
CPEs: []cpe.CPE{
|
||||
cpe.Must("cpe:2.3:*:some:package:2:*:*:*:*:*:*:*"),
|
||||
cpe.Must("cpe:2.3:*:some:package:2:*:*:*:*:*:*:*", cpe.GeneratedSource),
|
||||
},
|
||||
})
|
||||
catalog.Add(pkg.Package{
|
||||
@@ -192,7 +192,7 @@ func newDirectoryCatalogWithAuthorField() *pkg.Collection {
|
||||
},
|
||||
PURL: "pkg:deb/debian/package-2@2.0.1",
|
||||
CPEs: []cpe.CPE{
|
||||
cpe.Must("cpe:2.3:*:some:package:2:*:*:*:*:*:*:*"),
|
||||
cpe.Must("cpe:2.3:*:some:package:2:*:*:*:*:*:*:*", "another-test-source"),
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ func populateImageCatalog(catalog *pkg.Collection, img *image.Image) {
|
||||
},
|
||||
PURL: "a-purl-1", // intentionally a bad pURL for test fixtures
|
||||
CPEs: []cpe.CPE{
|
||||
cpe.Must("cpe:2.3:*:some:package:1:*:*:*:*:*:*:*"),
|
||||
cpe.Must("cpe:2.3:*:some:package:1:*:*:*:*:*:*:*", cpe.GeneratedSource),
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -139,7 +139,7 @@ func populateImageCatalog(catalog *pkg.Collection, img *image.Image) {
|
||||
},
|
||||
PURL: "pkg:deb/debian/package-2@2.0.1",
|
||||
CPEs: []cpe.CPE{
|
||||
cpe.Must("cpe:2.3:*:some:package:2:*:*:*:*:*:*:*"),
|
||||
cpe.Must("cpe:2.3:*:some:package:2:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user