feat: add binary classifier for hashicorp vault (#4121)

* add binary classifier for hashicorp vault

The Go Binary Cataloger isn't able to parse the version out of the
binary shipped in the DockerHub images of hashicorp/vault because the
version of the main module isn't set in the binary. Therefore, add a
binary classifier cataloger for this binary.

Signed-off-by: Will Murphy <willmurphyscode@users.noreply.github.com>

* chore: add test fixtures, update vault

Signed-off-by: Keith Zantow <kzantow@gmail.com>

* chore: set binary classifier package type based on PURL

Signed-off-by: Keith Zantow <kzantow@gmail.com>

* chore: use github.com/hashicorp/vault as package name

Signed-off-by: Keith Zantow <kzantow@gmail.com>

* chore: update tests

Signed-off-by: Keith Zantow <kzantow@gmail.com>

---------

Signed-off-by: Will Murphy <willmurphyscode@users.noreply.github.com>
Signed-off-by: Keith Zantow <kzantow@gmail.com>
Co-authored-by: Keith Zantow <kzantow@gmail.com>
This commit is contained in:
Will Murphy 2025-08-08 13:26:15 -04:00 committed by GitHub
parent 8c6a2bcbb6
commit 594b309cdf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 75 additions and 0 deletions

View File

@ -75,6 +75,12 @@ func (c cataloger) Catalog(_ context.Context, resolver file.Resolver) ([]pkg.Pac
newPackages:
for i := range newPkgs {
newPkg := &newPkgs[i]
purlType := pkg.TypeFromPURL(newPkg.PURL)
// for certain results, such as hashicorp vault we are returning a golang PURL, so we can use Golang package type,
// despite not having the known metadata, this should result in downstream grype matching to use the golang matcher
if purlType != pkg.UnknownPkg {
newPkg.Type = purlType
}
for j := range packages {
p := &packages[j]
// consolidate identical packages found in different locations or by different classifiers
@ -92,6 +98,9 @@ func (c cataloger) Catalog(_ context.Context, resolver file.Resolver) ([]pkg.Pac
// mergePackages merges information from the extra package into the target package
func mergePackages(target *pkg.Package, extra *pkg.Package) {
if extra.Type != pkg.BinaryPkg && target.Type == pkg.BinaryPkg {
target.Type = extra.Type
}
// add the locations
target.Locations.Add(extra.Locations.ToSlice()...)
// update the metadata to indicate which classifiers were used

View File

@ -1007,6 +1007,28 @@ func Test_Cataloger_PositiveCases(t *testing.T) {
Metadata: metadata("consul-binary"),
},
},
{
logicalFixture: "vault/1.20.2/linux-amd64",
expected: pkg.Package{
Name: "github.com/hashicorp/vault",
Version: "1.20.2",
Type: "golang",
PURL: "pkg:golang/github.com/hashicorp/vault@1.20.2",
Locations: locations("vault"),
Metadata: metadata("hashicorp-vault-binary"),
},
},
{
logicalFixture: "vault/1.19.4/linux-arm64",
expected: pkg.Package{
Name: "github.com/hashicorp/vault",
Version: "1.19.4",
Type: "golang",
PURL: "pkg:golang/github.com/hashicorp/vault@1.19.4",
Locations: locations("vault"),
Metadata: metadata("hashicorp-vault-binary"),
},
},
{
logicalFixture: "erlang/25.3.2.6/linux-amd64",
expected: pkg.Package{

View File

@ -448,6 +448,16 @@ func DefaultClassifiers() []binutils.Classifier {
PURL: mustPURL("pkg:golang/github.com/hashicorp/consul@version"),
CPEs: singleCPE("cpe:2.3:a:hashicorp:consul:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "hashicorp-vault-binary",
FileGlob: "**/vault",
EvidenceMatcher: m.FileContentsVersionMatcher(
// revoke1.18.0
`(?m)revoke(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`),
Package: "github.com/hashicorp/vault",
PURL: mustPURL("pkg:golang/github.com/hashicorp/vault@version"),
CPEs: singleCPE("cpe:2.3:a:hashicorp:vault:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "nginx-binary",
FileGlob: "**/nginx",

View File

@ -0,0 +1,11 @@
name: vault
offset: 191891817
length: 420
snippetSha256: fd8eb7979e1e7bbc254f2f7a26f6a70ecb479cc4f50c804f3b0789bc0e229097
fileSha256: a4754a343e619adef87a1d7e1368a0709ba29802fefbe8d70105c11085becd43
### byte snippet to follow ###
ctstreamPragma</a>.
:httpssocks Locked%s.logCT_LOGLOCAL0@level[INFO][WARN]env:///v1/%sDELETEcreateErrorserrorsclient/data/lookupactualAcceptregionawskmsocikmspkcs11%s%s%scloud:%s.%s:revoke1.19.4)(nil))(%#v) {...}frenchCommonArabicBrahmiCarianChakmaCopticGothicHangulHatranHebrewKaithiKhojkiLepchaLycianLydianRejangSyriacTai_LeTangsaTangutTeluguThaanaWanchoYezidiHyphen\u%04x\U%08xgetentpasswd390625%s
%s
%q: %wnumber\uff

View File

@ -0,0 +1,9 @@
name: vault
offset: 213670425
length: 220
snippetSha256: d9b23916d00e8085a4066974641ef77962f2e0aae6f4244688d2c4fe4286c92b
fileSha256: fb484f1b458e5d2fd28270b406a8b26b28d040dddcaa1d099aa9ee4ac927b730
### byte snippet to follow ###
ctstreamPragma</a>.
:httpssocks Locked%s.logCT_LOGLOCAL0@level[INFO][WARN]env:///v1/%sDELETEcreateErrorserrorsclient/data/lookupactualAcceptregionawskmsocikmspkcs11%s%s%scloud:%s.%s:revoke1.20.2)(nil))(%#v) {...}frenchCo

View File

@ -724,6 +724,20 @@ from-images:
paths:
- /bin/consul
- version: 1.20.2
images:
- ref: hashicorp/vault@sha256:5cd2003247e0a574a66c66aee1916b1e9e7f99640298f2e61271a8842d2d2a19
platform: linux/amd64
paths:
- /bin/vault
- version: 1.19.4
images:
- ref: hashicorp/vault@sha256:b5f675b0bf681568cd7354c697fe4ce953024312d6d23ee7216deda60c192bad
platform: linux/arm64
paths:
- /bin/vault
- version: 3.0.2
images:
- ref: fluent/fluent-bit:3.0.2-amd64@sha256:7e6fe8efd51dda0739e355f58bf5e3b1623cbf2d4a23c06c7a365d9553e2d242