mirror of
https://github.com/anchore/syft.git
synced 2026-10-31 14:36:33 +01:00
* build(deps): bump go-make to v0.8.1
Picks up golangci-lint 2.13.2 (built with go1.27) in place of 2.11.4 (go1.26).
The old build panics outright on a go1.27 GOROOT with "file requires newer Go
version go1.27", and an older mise-shim build fails the quieter way: it loses
type info and reports zero findings with exit 0, so a ruleguard run comes back
green without having evaluated anything.
Also folds in what the newer linter flags:
- `reflect.Ptr` -> `reflect.Pointer` in three files, applied by --fix
- `tw.CellFormatting{MergeMode: ...}` -> `tw.CellMerging{Mode: ...}` in the
cataloger info table, for a staticcheck SA1019 deprecation
Note the deprecation text names `CellConfig.CellMerging.Mode`, but the field is
`CellConfig.Merging`; `CellMerging` is the type. That command path has no test
coverage, so the swap was checked by rendering the same hierarchical-merge table
both ways and diffing: byte identical.
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
* chore(lint): tune goconst for data tables
goconst got stricter in golangci-lint 2.13 and now counts strings in map
literals and struct fields, which lights up every lookup table in the repo. It
was already enabled, so this is main going red on a linter bump rather than
anything new in the tree: 101 findings, and the default threshold of 3 means a
vendor name appearing in three rows of a table reads as a magic constant.
Raising `min-occurrences` to 5 takes that to 14. The rest split by whether the
repeated string is data or an actual constant:
- `cpegenerate` is excluded by path. It maps artifact names to vendors,
products, and maven group ids, and repeats strings 35, 83, even 293 times, so
no threshold reaches it. Hoisting those would trade a readable table for
indirection.
- the two SBOM fixture builders in `format/internal/testutil` get a
function-level nolint each. The repeated names and versions are what the
golden files assert against.
- `mysql-cluster` and `php` were genuine repeated literals and are now
constants.
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
* chore(test): extract measureAlloc into a shared helper
The allocation-budget tests added during the unbounded allocation work grew a
copy of the same helper in every package they touched: four identical
`measureAlloc` definitions plus two more spelled out inline against
`runtime.MemStats`.
Now `testutils.MeasureAlloc`, at the repo root so `internal/spillbuf` can reach
it too. The doc comment carries the two things that were only recorded in some
of the copies: TotalAlloc is process-wide so callers must not use t.Parallel,
and a budget assertion only means something if the fixture would really blow
past it unguarded, so measure the unguarded path as well.
No behavior change, the body was identical in all six.
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
* chore(lint): add ruleguard rules for overflow and swallowed EOF
Two rules out of the recent unbounded allocation work (#5187, #5195, #5267,
#5291, #5292, #5293, #5294).
`noOverflowingBoundsCheck` flags `offset + size > limit` (and <, <=, >=) where
an operand is unsigned, neither addend is constant, and the operands are at
least 32 bits. Unsigned addition wraps, so an offset out of a file header can
carry the sum past the wrap point and pass a check it should have failed. The
fix is to subtract against the limit instead. Constant addends are excluded
because `pos+4 <= uint32(len(buf))` is the normal way to step a cursor, and the
32-bit floor drops nibbles widened for a comparison. Would have caught four
sites across #5195 and #5291.
`noSwallowedEOF` flags `return nil` / `return nil, nil` on an io.EOF check. The
caller gets a zero value it cannot tell from real data, and anything decoding a
fixed-size struct off it parses the padding as content. That is the shape behind
#5186.
Both decide from the expression alone, and writing the fix deletes the pattern,
so neither needs a suppression anywhere in the tree. That was the bar: rules for
the allocation and decompression classes were tried and dropped, because the
bound they look for lives in a preceding statement (or, for a decompressor
constructor, always downstream), so no correct implementation can silence them.
That would have meant ~15 permanent nolints on code that is already right. The
rules here that do work don't judge whether a bound exists, they route to a
wrapper that takes one: noDirectTempFiles, noDirectELFOpen.
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
* test: pin allocation budgets on the alpm, deb, and changelog bounds
The bounds added for #5292, #5293 and #5294 are asserted by the error they
return. That keeps passing if the bound is removed and something else rejects
the input later, which is the failure these were written for. Each of these
measures bytes instead, and proves the fixture is really a bomb first so a
fixture that quietly stops being one fails rather than passing.
- alpm mtree: 16MB of newlines, well inside the 64MB byte cap, costs 16.5GB
uncapped against 238MB with maxMtreeLines. That 16.5GB is the measurement the
line cap was added for and it was recorded only in the commit message. Note
what the cap actually buys: 300k entries still cost a few hundred MB, per
concurrent cataloger.
- deb members: 1.28GB against 392KB. Both arms read with io.ReadAll on purpose,
since the stream itself never holds much whatever the cap says; what the cap
protects is a consumer that buffers, and the real one is a tar reader building
entries.
- snap changelog: 1.28GB against 175KB. This one has no explicit cap at all. It
is held by bufio.Scanner refusing a token past MaxScanTokenSize, which is
incidental, so switching to io.ReadAll or a bufio.Reader to pick up long lines
would remove it silently.
Nothing added for the kernel module reader: its copy is already
io.Copy(tempFile, io.LimitReader(rc, max+1)), so peak disk is bounded by
construction and heap is streaming. A heap budget would assert the wrong
resource, and the three existing subtests cover the cap, at-cap fidelity, and
spill cleanup.
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
* test: pin allocation budgets on the ai and alpm byte caps
Follows the same pattern as the alpm line cap: measure bytes, and prove the
fixture is really a bomb first so one that quietly stops being a bomb fails
rather than passes.
- safetensors: 252MB against 2.6KB. The existing over-cap case deliberately
omits the body, since the guard rejects on the declared length before reading
anything. That is the right test for the guard but it would keep passing if
the check moved after the read, so this one delivers the bytes.
- gguf: 268MB against 168MB. copyHeader io.Copy's whatever it is handed, so
maxHeaderSize holds only because every caller wraps the reader first. This
pins that the limit is where the bound lives, so dropping the wrapper at a
call site fails here.
- alpm byte cap: 740MB against 132MB, the counterpart to the line cap budget.
Worth knowing for anyone writing the next one of these: a single enormous line
does not exercise the alpm byte cap. go-mtree runs its own bufio.Scanner and
refuses a token past 64KB, so that fixture fails as "token too long" before the
byte cap is consulted. The fixture here uses ordinary 1KB lines, enough of them
to pass 64MB while staying under the 300k line cap, so the byte cap is actually
the thing under test.
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
* test: assert bytes retained instead of allocated for gguf copyHeader
the bounded arm writes into a bytes.Buffer, whose doubling growth costs a
multiple of what it holds and lands on a different power of two depending on
the platform. it measured 168MB locally and 320MB on CI, past the budget.
buf.Len() states the same property deterministically.
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
---------
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
1298 lines
57 KiB
Go
1298 lines
57 KiB
Go
package binary
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/anchore/packageurl-go"
|
|
"github.com/anchore/syft/syft/cpe"
|
|
"github.com/anchore/syft/syft/pkg/cataloger/internal/binutils"
|
|
)
|
|
|
|
// mysqlClusterPackage is the package name shared by every MySQL Cluster classifier below.
|
|
const mysqlClusterPackage = "mysql-cluster"
|
|
|
|
// in both binaries and shared libraries, the version pattern is [NUL]3.11.2[NUL]
|
|
var pythonVersionTemplate = `(?m)\x00(?P<version>{{ .version }}[-._a-zA-Z0-9]*)\x00`
|
|
|
|
//nolint:funlen
|
|
func DefaultClassifiers() []binutils.Classifier {
|
|
m := binutils.ContextualEvidenceMatchers{CatalogerName: catalogerName}
|
|
|
|
var libpythonMatcher = m.FileNameTemplateVersionMatcher(
|
|
`(?:.*/|^)libpython(?P<version>[0-9]+(?:\.[0-9]+)+)[a-z]?\.so.*$`,
|
|
pythonVersionTemplate,
|
|
)
|
|
|
|
var rubyMatcher = m.FileContentsVersionMatcher(
|
|
// ruby 3.4.0dev (2024-09-15T01:06:11Z master 532af89e3b) [x86_64-linux]
|
|
// ruby 3.4.0preview1 (2024-05-16 master 9d69619623) [x86_64-linux]
|
|
// ruby 3.3.0rc1 (2023-12-11 master a49643340e) [x86_64-linux]
|
|
// ruby 3.2.1 (2023-02-08 revision 31819e82c8) [x86_64-linux]
|
|
// ruby 2.7.7p221 (2022-11-24 revision 168ec2b1e5) [x86_64-linux]
|
|
`(?m)ruby (?P<version>[0-9]+\.[0-9]+\.[0-9]+((p|preview|rc|dev)[0-9]*)?) `)
|
|
|
|
// all Elastic Beats (filebeat, metricbeat, heartbeat, packetbeat, auditbeat)
|
|
var elasticBeatsMatcher = binutils.MatchAny(
|
|
// 9.x: forcestdinsetupTest 9.4.2%s %w (filebeat/metricbeat/auditbeat)
|
|
// forcestdinsetupTest 9.4.2input (heartbeat/packetbeat)
|
|
m.FileContentsVersionMatcher(`Test (?P<version>[0-9]+\.[0-9]+\.[0-9]+)[a-z%]`),
|
|
// 9.x: exportconfigcreateplugin9.4.2-globalclient
|
|
// 8.18.x: exportconfigcreateplugin8.18.4globalclient
|
|
m.FileContentsVersionMatcher(`plugin(?:output)?(?P<version>[0-9]+\.[0-9]+\.[0-9]+)[-a-z]`),
|
|
// 8.11.x: 5m.rate8.11.2-9765625
|
|
m.FileContentsVersionMatcher(`5m\.rate(?P<version>[0-9]+\.[0-9]+\.[0-9]+)-`),
|
|
)
|
|
|
|
classifiers := []binutils.Classifier{
|
|
{
|
|
Class: "python-binary",
|
|
FileGlob: "**/python*",
|
|
EvidenceMatcher: binutils.MatchAny(
|
|
// try to find version information from libpython shared libraries
|
|
binutils.SharedLibraryLookup(
|
|
`^libpython[0-9]+(?:\.[0-9]+)+[a-z]?\.so.*$`,
|
|
libpythonMatcher),
|
|
// check for version information in the binary
|
|
m.FileNameTemplateVersionMatcher(
|
|
`(?:.*/|^)python(?P<version>[0-9]+(?:\.[0-9]+)+)$`,
|
|
pythonVersionTemplate),
|
|
),
|
|
Package: "python",
|
|
PURL: mustPURL("pkg:generic/python@version"),
|
|
CPEs: []cpe.CPE{
|
|
cpe.Must("cpe:2.3:a:python_software_foundation:python:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
cpe.Must("cpe:2.3:a:python:python:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
},
|
|
{
|
|
Class: "python-binary-lib",
|
|
FileGlob: "**/libpython*.so*",
|
|
EvidenceMatcher: libpythonMatcher,
|
|
Package: "python",
|
|
PURL: mustPURL("pkg:generic/python@version"),
|
|
CPEs: []cpe.CPE{
|
|
cpe.Must("cpe:2.3:a:python_software_foundation:python:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
cpe.Must("cpe:2.3:a:python:python:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
},
|
|
{
|
|
Class: "pypy-binary-lib",
|
|
FileGlob: "**/libpypy*.so*",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
`(?m)\[PyPy (?P<version>[0-9]+\.[0-9]+\.[0-9]+)`),
|
|
Package: "pypy",
|
|
PURL: mustPURL("pkg:generic/pypy@version"),
|
|
},
|
|
{
|
|
Class: "go-binary",
|
|
FileGlob: "**/{go,go.exe}",
|
|
EvidenceMatcher: binutils.MatchAny(
|
|
m.FileContentsVersionMatcher(
|
|
`(?m)go(?P<version>[0-9]+\.[0-9]+(\.[0-9]+|beta[0-9]+|alpha[0-9]+|rc[0-9]+)?)\x00`),
|
|
binutils.SupportingEvidenceMatcher("VERSION*",
|
|
m.FileContentsVersionMatcher(
|
|
`(?m)go(?P<version>[0-9]+\.[0-9]+(\.[0-9]+|beta[0-9]+|alpha[0-9]+|rc[0-9]+|-[_0-9a-z]+)?)`)),
|
|
binutils.SupportingEvidenceMatcher("../VERSION*",
|
|
m.FileContentsVersionMatcher(
|
|
`(?m)go(?P<version>[0-9]+\.[0-9]+(\.[0-9]+|beta[0-9]+|alpha[0-9]+|rc[0-9]+|-[_0-9a-z]+)?)`)),
|
|
),
|
|
Package: "go",
|
|
PURL: mustPURL("pkg:generic/go@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:golang:go:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "julia-binary",
|
|
FileGlob: "**/libjulia-internal.so",
|
|
EvidenceMatcher: binutils.MatchAny(
|
|
// �1.13.0-beta3[NUL]branch
|
|
// [NUL]GIT_VERSION_INFO[NUL]jl_image_unpack[NUL]1.13.0-alpha2[NUL]branch
|
|
// [NUL]GIT_VERSION_INFO[NUL]__init__[NUL]1.12.6[NUL]branch[NUL]commit
|
|
// [NUL]GIT_VERSION_INFO[NUL]__init__[NUL]verify_methods[NUL]1.11.9[NUL]branch[NUL]commit
|
|
// [NUL][NUL]__init__[NUL]1.10.11[NUL]verify_methods[NUL]
|
|
m.FileContentsVersionMatcher(`\x00__init__\x00(?P<version>[0-9]+\.[0-9]+\.[0-9]+(-alpha[0-9]|-beta[0-9]|-rc[0-9])?)\x00(branch|verify_methods)`),
|
|
m.FileContentsVersionMatcher(`(?P<version>[0-9]+\.[0-9]+\.[0-9]+(-alpha[0-9]|-beta[0-9]|-rc[0-9])?)\x00branch\x00`),
|
|
// [NUL]verify_methods[NUL]Task cannot be serialized[NUL]1.9.0-alpha1[NUL]BigInt[NUL]
|
|
m.FileContentsVersionMatcher(`\x00verify_methods\x00.{0,30}(?P<version>[0-9]+\.[0-9]+\.[0-9]+(-alpha[0-9]|-beta[0-9]|-rc[0-9])?)\x00BigInt`),
|
|
// unknown option `%s`[NUL]1.8.5[NUL]julia version %s
|
|
m.FileContentsVersionMatcher(`\x00(?P<version>[0-9]+\.[0-9]+\.[0-9]+(-alpha[0-9]|-beta[0-9]|-rc[0-9])?)\x00julia version`),
|
|
),
|
|
Package: "julia",
|
|
PURL: mustPURL("pkg:generic/julia@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:julialang:julia:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "julia-binary",
|
|
FileGlob: "**/julia",
|
|
EvidenceMatcher: binutils.SharedLibraryLookup(
|
|
// libjulia.so.1
|
|
// libjulia.so.0.6
|
|
// libjulia.so
|
|
`^libjulia\.so(\.[0-9])?(\.[0-9])?$`,
|
|
binutils.MatchAny(
|
|
// unknown option `%s`[NUL]1.5.4[NUL]julia version %s
|
|
m.FileContentsVersionMatcher(`\x00(?P<version>[0-9]+\.[0-9]+\.[0-9]+(-alpha[0-9]|-beta[0-9]|-rc[0-9])?)\x00julia version`),
|
|
// [NUL]#kw#[NUL]1.3.1[NUL]BigInt
|
|
// [NUL]#kw#[NUL]0.7.0-beta2[NUL]_require_dependencies
|
|
m.FileContentsVersionMatcher(`\x00#kw#\x00(?P<version>[0-9]+\.[0-9]+\.[0-9]+(-alpha[0-9]|-beta[0-9]|-rc[0-9])?)\x00(BigInt|_require_dependencies)`),
|
|
// [NUL]ObjectIdDict[NUL]0.6.4[NUL]jl_sysimg_cpu_target
|
|
m.FileContentsVersionMatcher(`\x00ObjectIdDict\x00(?P<version>[0-9]+\.[0-9]+\.[0-9]+(-alpha[0-9]|-beta[0-9]|-rc[0-9])?)\x00jl_sysimg_cpu_target`),
|
|
// [NUL]require[NUL]0.4.6[NUL]core2
|
|
m.FileContentsVersionMatcher(`\x00require\x00(?P<version>[0-9]+\.[0-9]+\.[0-9]+(-alpha[0-9]|-beta[0-9]|-rc[0-9])?)\x00core2`),
|
|
),
|
|
),
|
|
Package: "julia",
|
|
PURL: mustPURL("pkg:generic/julia@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:julialang:julia:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "helm",
|
|
FileGlob: "**/helm",
|
|
EvidenceMatcher: binutils.MatchAny(
|
|
// [NUL]v1.21.2[NUL].......[NUL][NUL]v4.1.4[NUL][NUL][NUL]
|
|
// [NUL]v2.0.0-beta.2[NUL][NUL][NUL]
|
|
m.FileContentsVersionMatcher(`\x00v(?P<version>[0-9]+\.[0-9]+\.[0-9]+(-alpha\.[0-9]|-beta\.[0-9]|-rc\.[0-9])?)\x00{2,}`),
|
|
// [NUK]'[DLE]v3.12.0[NUL][NUL]...go1.20.3[NUL][NUL]
|
|
m.FileContentsVersionMatcher(`v(?P<version>[0-9]+\.[0-9]+\.[0-9]+(-alpha\.[0-9]|-beta\.[0-9]|-rc\.[0-9])?)\x00+.{1,500}go[0-9]+\.[0-9]+\.[0-9]+\x00+`),
|
|
// [NUL]v3.11.1[NUL]�[NUL]
|
|
m.FileContentsVersionMatcher(`\x00v(?P<version>[0-9]+\.[0-9]+\.[0-9]+(-alpha\.[0-9]|-beta\.[0-9]|-rc\.[0-9])?)\x00`),
|
|
// [NUL]@�@v3.15.2[NUL][NUL]
|
|
m.FileContentsVersionMatcher(`@v(?P<version>[0-9]+\.[0-9]+\.[0-9]+(-alpha\.[0-9]|-beta\.[0-9]|-rc\.[0-9])?)\x00`),
|
|
),
|
|
Package: "helm",
|
|
PURL: mustPURL("pkg:golang/helm.sh/helm@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:helm:helm:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "redis-binary",
|
|
FileGlob: "**/redis-server",
|
|
EvidenceMatcher: binutils.MatchAll(
|
|
// Negative Matchers to exclude valkey-server
|
|
binutils.MatchNone(
|
|
binutils.MatchPath("**/valkey-server"),
|
|
),
|
|
binutils.MatchAny(
|
|
// matches most recent versions of redis (~v7), e.g. "7.0.14buildkitsandbox-1702957741000000000"
|
|
m.FileContentsVersionMatcher(`[^\d](?P<version>\d+.\d+\.\d+)buildkitsandbox-\d+`),
|
|
// matches against older versions of redis (~v3 - v6), e.g. "4.0.11841ce7054bd9-1542359302000000000"
|
|
m.FileContentsVersionMatcher(`[^\d](?P<version>[0-9]+\.[0-9]+\.[0-9]+)\w{12}-\d+`),
|
|
// matches against older versions of redis (~v2), e.g. "Server started, Redis version 2.8.23"
|
|
m.FileContentsVersionMatcher(`Redis version (?P<version>[0-9]+\.[0-9]+\.[0-9]+)`),
|
|
),
|
|
),
|
|
Package: "redis",
|
|
PURL: mustPURL("pkg:generic/redis@version"),
|
|
CPEs: []cpe.CPE{
|
|
cpe.Must("cpe:2.3:a:redislabs:redis:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
cpe.Must("cpe:2.3:a:redis:redis:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
},
|
|
{
|
|
Class: "valkey-binary",
|
|
FileGlob: "**/valkey-server",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
// valkey9.0.0buildkitsandbox-1764887574000000000
|
|
`[^\d](?P<version>\d+.\d+\.\d+)buildkitsandbox-\d+`),
|
|
Package: "valkey",
|
|
PURL: mustPURL("pkg:generic/valkey@version"),
|
|
CPEs: []cpe.CPE{
|
|
cpe.Must("cpe:2.3:a:lfprojects:valkey:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
cpe.Must("cpe:2.3:a:linuxfoundation:valkey:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
cpe.Must("cpe:2.3:a:valkey-io:valkey:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
},
|
|
{
|
|
Class: "nodejs-binary",
|
|
FileGlob: "**/node",
|
|
EvidenceMatcher: binutils.MatchAny(
|
|
// [NUL]node v0.10.48[NUL]
|
|
// [NUL]v0.12.18[NUL]
|
|
// [NUL]v4.9.1[NUL]
|
|
// node.js/v22.9.0
|
|
m.FileContentsVersionMatcher(`(?m)\x00(node )?v(?P<version>(0|4|5|6)\.[0-9]+\.[0-9]+)\x00`),
|
|
m.FileContentsVersionMatcher(`(?m)node\.js\/v(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`),
|
|
),
|
|
Package: "node",
|
|
PURL: mustPURL("pkg:generic/node@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:nodejs:node.js:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "busybox-binary",
|
|
FileGlob: "**/busybox",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
`(?m)BusyBox\s+v(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`),
|
|
Package: "busybox",
|
|
PURL: mustPURL("pkg:generic/busybox@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:busybox:busybox:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "util-linux-binary",
|
|
FileGlob: "**/getopt",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
`\x00util-linux\s(?P<version>[0-9]+\.[0-9]+\.[0-9]+)\x00`),
|
|
Package: "util-linux",
|
|
PURL: mustPURL("pkg:generic/util-linux@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:kernel:util-linux:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "haproxy-binary",
|
|
FileGlob: "**/haproxy",
|
|
EvidenceMatcher: binutils.MatchAny(
|
|
m.FileContentsVersionMatcher(`(?m)version (?P<version>[0-9]+\.[0-9]+(\.|-dev|-rc)[0-9]+)(-[a-z0-9]{7})?, released 20`),
|
|
m.FileContentsVersionMatcher(`(?m)HA-Proxy version (?P<version>[0-9]+\.[0-9]+(\.|-dev)[0-9]+)`),
|
|
m.FileContentsVersionMatcher(`(?m)(?P<version>[0-9]+\.[0-9]+(\.|-dev)[0-9]+)-[0-9a-zA-Z]{7}.+HAProxy version`),
|
|
),
|
|
Package: "haproxy",
|
|
PURL: mustPURL("pkg:generic/haproxy@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:haproxy:haproxy:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "perl-binary",
|
|
FileGlob: "**/perl",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
`(?m)\/usr\/local\/lib\/perl\d\/(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`),
|
|
Package: "perl",
|
|
PURL: mustPURL("pkg:generic/perl@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:perl:perl:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "php-composer-binary",
|
|
FileGlob: "**/composer*",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
`(?m)'pretty_version'\s*=>\s*'(?P<version>[0-9]+\.[0-9]+\.[0-9]+(beta[0-9]+|alpha[0-9]+|RC[0-9]+)?)'`),
|
|
Package: "composer",
|
|
PURL: mustPURL("pkg:generic/composer@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:getcomposer:composer:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "httpd-binary",
|
|
FileGlob: "**/httpd",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
`(?m)Apache\/(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`),
|
|
Package: "httpd",
|
|
PURL: mustPURL("pkg:generic/httpd@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:apache:http_server:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "memcached-binary",
|
|
FileGlob: "**/memcached",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
`(?m)memcached\s(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`),
|
|
Package: "memcached",
|
|
PURL: mustPURL("pkg:generic/memcached@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:memcached:memcached:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "traefik-binary",
|
|
FileGlob: "**/traefik",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
// [NUL]v1.7.34[NUL]
|
|
// [NUL]2.9.6[NUL]
|
|
// 3.0.4[NUL]
|
|
`(?m)(\x00v?|\x{FFFD}.?)(?P<version>[0-9]+\.[0-9]+\.[0-9]+(-alpha[0-9]|-beta[0-9]|-rc[0-9])?)\x00`),
|
|
Package: "traefik",
|
|
PURL: mustPURL("pkg:generic/traefik@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:traefik:traefik:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "arangodb-binary",
|
|
FileGlob: "**/arangosh",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
`(?m)\x00*(?P<version>[0-9]+\.[0-9]+\.[0-9]+(-[0-9]+)?)\s(enterprise\s)?\[linux\]`),
|
|
Package: "arangodb",
|
|
PURL: mustPURL("pkg:generic/arangodb@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:arangodb:arangodb:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "postgresql-binary",
|
|
FileGlob: "**/postgres",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
// [NUL]PostgreSQL 15beta4
|
|
// [NUL]PostgreSQL 15.1
|
|
// [NUL]PostgreSQL 9.6.24
|
|
// ?PostgreSQL 9.5alpha1
|
|
`(?m)(\x00|\?)PostgreSQL (?P<version>[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)`),
|
|
Package: "postgresql",
|
|
PURL: mustPURL("pkg:generic/postgresql@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:postgresql:postgresql:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "mysql-binary",
|
|
FileGlob: "**/mysql",
|
|
EvidenceMatcher: binutils.MatchAny(
|
|
// shutdown[NUL]8.0.37[NUL][NUL][NUL][NUL][NUL]mysql_real_esc
|
|
m.FileContentsVersionMatcher(`\x00(?P<version>[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)\x00+mysql`),
|
|
// /export/home/pb2/build/sb_0-26781090-1516292385.58/release/mysql-8.0.4-rc/mysys_ssl/my_default.cc
|
|
m.FileContentsVersionMatcher(`(?m).*/mysql-(?P<version>[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)`),
|
|
),
|
|
Package: "mysql",
|
|
PURL: mustPURL("pkg:generic/mysql@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:oracle:mysql:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "mysql-binary",
|
|
FileGlob: "**/mysql",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
`(?m).*/percona-server-(?P<version>[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)`),
|
|
Package: "percona-server",
|
|
PURL: mustPURL("pkg:generic/percona-server@version"),
|
|
CPEs: []cpe.CPE{
|
|
cpe.Must("cpe:2.3:a:oracle:mysql:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
cpe.Must("cpe:2.3:a:percona:percona_server:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
},
|
|
{
|
|
Class: "mysql-binary",
|
|
FileGlob: "**/mysql",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
`(?m).*/Percona-XtraDB-Cluster-(?P<version>[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)`),
|
|
Package: "percona-xtradb-cluster",
|
|
PURL: mustPURL("pkg:generic/percona-xtradb-cluster@version"),
|
|
CPEs: []cpe.CPE{
|
|
cpe.Must("cpe:2.3:a:oracle:mysql:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
cpe.Must("cpe:2.3:a:percona:percona_server:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
cpe.Must("cpe:2.3:a:percona:xtradb_cluster:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
},
|
|
{
|
|
// Legacy MySQL Cluster contains both MySQL Server and MySQL Cluster versions (Example: 5.7.33-ndb-7.5.21)
|
|
// This classifier identifies the MySQL Server version of the mysqld binary (5.7.33 in the example above).
|
|
Class: "mysqld-mysql-cluster-legacy-binary",
|
|
FileGlob: "**/mysqld",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
`cluster-gpl\x00(?P<version>[0-9]+(\.[0-9]+)?(\.[0-9]+)?)\-ndb\-[0-9]+(\.[0-9]+)?(\.[0-9]+)?`),
|
|
Package: "mysql-server",
|
|
PURL: mustPURL("pkg:generic/mysql-server@version"),
|
|
CPEs: []cpe.CPE{
|
|
cpe.Must("cpe:2.3:a:oracle:mysql:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
cpe.Must("cpe:2.3:a:oracle:mysql_server:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
},
|
|
{
|
|
Class: "mysqld-binary",
|
|
FileGlob: "**/mysqld",
|
|
EvidenceMatcher: binutils.BranchingEvidenceMatcher([]binutils.Classifier{
|
|
{
|
|
// Legacy MySQL Cluster contains both MySQL Server and MySQL Cluster versions (Example: 5.7.33-ndb-7.5.21)
|
|
// This classifier identifies the MySQL Cluster version of the mysqld binary (7.5.21 in the example above).
|
|
Class: "mysqld-mysql-cluster-legacy-binary",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
`cluster-gpl\x00[0-9]+(\.[0-9]+)?(\.[0-9]+)?\-ndb\-(?P<version>[0-9]+(\.[0-9]+)?(\.[0-9]+)?)`),
|
|
Package: mysqlClusterPackage,
|
|
PURL: mustPURL("pkg:generic/mysql-cluster@version"),
|
|
CPEs: []cpe.CPE{
|
|
cpe.Must("cpe:2.3:a:oracle:mysql_cluster:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
},
|
|
{
|
|
// mysqld from MySQL Cluster after versioning was aligned with MySQL Server
|
|
Class: "mysqld-mysql-cluster-binary",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
`/mysql-cluster-gpl-(?P<version>[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)/`),
|
|
Package: mysqlClusterPackage,
|
|
PURL: mustPURL("pkg:generic/mysql-cluster@version"),
|
|
CPEs: []cpe.CPE{
|
|
cpe.Must("cpe:2.3:a:oracle:mysql:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
cpe.Must("cpe:2.3:a:oracle:mysql_server:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
cpe.Must("cpe:2.3:a:oracle:mysql_cluster:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
},
|
|
{
|
|
// mysqld from MySQL Server
|
|
Class: "mysqld-mysql-server-binary",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
`/mysql-(?P<version>[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)/`),
|
|
Package: "mysql-server",
|
|
PURL: mustPURL("pkg:generic/mysql-server@version"),
|
|
CPEs: []cpe.CPE{
|
|
cpe.Must("cpe:2.3:a:oracle:mysql:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
cpe.Must("cpe:2.3:a:oracle:mysql_server:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
},
|
|
}...),
|
|
},
|
|
{
|
|
Class: "ndbd-binary",
|
|
FileGlob: "**/ndbd",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
`/mysql-cluster-gpl-(?P<version>[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)/`),
|
|
Package: mysqlClusterPackage,
|
|
PURL: mustPURL("pkg:generic/mysql-cluster@version"),
|
|
CPEs: []cpe.CPE{
|
|
cpe.Must("cpe:2.3:a:oracle:mysql_cluster:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
},
|
|
{
|
|
Class: "ndbmtd-binary",
|
|
FileGlob: "**/ndbmtd",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
`/mysql-cluster-gpl-(?P<version>[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)/`),
|
|
Package: mysqlClusterPackage,
|
|
PURL: mustPURL("pkg:generic/mysql-cluster@version"),
|
|
CPEs: []cpe.CPE{
|
|
cpe.Must("cpe:2.3:a:oracle:mysql_cluster:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
},
|
|
{
|
|
Class: "ndb_mgmd-binary",
|
|
FileGlob: "**/ndb_mgmd",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
`/mysql-cluster-gpl-(?P<version>[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)/`),
|
|
Package: mysqlClusterPackage,
|
|
PURL: mustPURL("pkg:generic/mysql-cluster@version"),
|
|
CPEs: []cpe.CPE{
|
|
cpe.Must("cpe:2.3:a:oracle:mysql_cluster:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
},
|
|
{
|
|
Class: "xtrabackup-binary",
|
|
FileGlob: "**/xtrabackup",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
`(?m).*/percona-xtrabackup-(?P<version>[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)`),
|
|
Package: "percona-xtrabackup",
|
|
PURL: mustPURL("pkg:generic/percona-xtrabackup@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:percona:xtrabackup:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "mariadb-binary",
|
|
FileGlob: "**/{mariadb,mysql}",
|
|
EvidenceMatcher: binutils.MatchAny(
|
|
// 10.6.15-MariaDB
|
|
m.FileContentsVersionMatcher(`(?m)(?P<version>[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)-MariaDB`),
|
|
// MariaDB.org / RHEL tarball builds embed the release directory name, which does not contain the
|
|
// "-MariaDB" marker. The version is in the build path instead, e.g.:
|
|
// mariadb-11.8.5-2-redhat-x86_64/rhel-8/bin/mariadb
|
|
// mariadb-11.8.5-linux-systemd-x86_64
|
|
// Without this the older matcher misses the version and a later release suffix (e.g. "2") can be
|
|
// picked up instead, producing false-positive matches against ancient CVEs (see anchore/grype#3452).
|
|
m.FileContentsVersionMatcher(`(?m)(?:^|/)mariadb-(?P<version>[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)-`),
|
|
),
|
|
Package: "mariadb",
|
|
PURL: mustPURL("pkg:generic/mariadb@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:mariadb:mariadb:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "rust-standard-library-linux",
|
|
FileGlob: "**/libstd-????????????????.so",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
// clang LLVM (rustc version 1.48.0 (7eac88abb 2020-11-16))
|
|
`(?m)(\x00)clang LLVM \(rustc version (?P<version>[0-9]+(\.[0-9]+)?(\.[0-9]+)) \(\w+ \d{4}\-\d{2}\-\d{2}\)`),
|
|
Package: "rust",
|
|
PURL: mustPURL("pkg:generic/rust@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:rust-lang:rust:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "rust-standard-library-macos",
|
|
FileGlob: "**/libstd-????????????????.dylib",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
// c 1.48.0 (7eac88abb 2020-11-16)
|
|
`(?m)c (?P<version>[0-9]+(\.[0-9]+)?(\.[0-9]+)) \(\w+ \d{4}\-\d{2}\-\d{2}\)`),
|
|
Package: "rust",
|
|
PURL: mustPURL("pkg:generic/rust@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:rust-lang:rust:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "ruby-binary",
|
|
FileGlob: "**/ruby",
|
|
EvidenceMatcher: binutils.MatchAny(
|
|
rubyMatcher,
|
|
binutils.SharedLibraryLookup(
|
|
// try to find version information from libruby shared libraries
|
|
`^libruby\.so.*$`,
|
|
rubyMatcher),
|
|
),
|
|
Package: "ruby",
|
|
PURL: mustPURL("pkg:generic/ruby@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:ruby-lang:ruby:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "erlang-binary",
|
|
FileGlob: "**/erlexec",
|
|
EvidenceMatcher: binutils.MatchAny(
|
|
m.FileContentsVersionMatcher(
|
|
// <artificial>[NUL]/usr/src/otp_src_25.3.2.6/erts/
|
|
`(?m)/src/otp_src_(?P<version>[0-9]+\.[0-9]+(\.[0-9]+){0,2}(-rc[0-9])?)/erts/`,
|
|
),
|
|
m.FileContentsVersionMatcher(
|
|
// <artificial>[NUL]/usr/local/src/otp-25.3.2.7/erts/
|
|
`(?m)/usr/local/src/otp-(?P<version>[0-9]+\.[0-9]+(\.[0-9]+){0,2}(-rc[0-9])?)/erts/`,
|
|
),
|
|
),
|
|
Package: "erlang",
|
|
PURL: mustPURL("pkg:generic/erlang@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "erlang-alpine-binary",
|
|
FileGlob: "**/beam.smp",
|
|
EvidenceMatcher: binutils.MatchAny(
|
|
m.FileContentsVersionMatcher(
|
|
// <artificial>[NUL]/usr/src/otp_src_25.3.2.6/erts/
|
|
`(?m)/src/otp_src_(?P<version>[0-9]+\.[0-9]+(\.[0-9]+){0,2}(-rc[0-9])?)/erts/`,
|
|
),
|
|
m.FileContentsVersionMatcher(
|
|
// <artificial>[NUL]/usr/local/src/otp-25.3.2.7/erts/
|
|
`(?m)/usr/local/src/otp-(?P<version>[0-9]+\.[0-9]+(\.[0-9]+){0,2}(-rc[0-9])?)/erts/`,
|
|
),
|
|
m.FileContentsVersionMatcher(
|
|
// [NUL][NUL]26.1.2[NUL][NUL][NUL][NUL][NUL][NUL][NUL]NUL[NUL][NUL]Erlang/OTP
|
|
`\x00+(?P<version>[0-9]+\.[0-9]+(\.[0-9]+){0,2}(-rc[0-9])?)\x00+Erlang/OTP`,
|
|
),
|
|
m.FileContentsVersionMatcher(
|
|
// Erlang/OTP 17%s [erts-6.4.1.6] [source] [64-bit] [smp:%beu:%beu] [async-threads:%d] [hipe] [kernel-poll:%s][NUL]17.5.6.9[NUL][NUL][NUL]
|
|
`(?s)Erlang/OTP.{1,150}\x00+(?P<version>[0-9]+\.[0-9]+(\.[0-9]+){0,2}(-rc[0-9])?)\x00+`,
|
|
),
|
|
),
|
|
Package: "erlang",
|
|
PURL: mustPURL("pkg:generic/erlang@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "erlang-library",
|
|
FileGlob: "**/liberts_internal.a",
|
|
EvidenceMatcher: binutils.MatchAny(
|
|
m.FileContentsVersionMatcher(
|
|
// <artificial>[NUL]/usr/src/otp_src_25.3.2.6/erts/
|
|
`(?m)/src/otp_src_(?P<version>[0-9]+\.[0-9]+(\.[0-9]+){0,2}(-rc[0-9])?)/erts/`,
|
|
),
|
|
m.FileContentsVersionMatcher(
|
|
// <artificial>[NUL]/usr/local/src/otp-25.3.2.7/erts/
|
|
`(?m)/usr/local/src/otp-(?P<version>[0-9]+\.[0-9]+(\.[0-9]+){0,2}(-rc[0-9])?)/erts/`,
|
|
),
|
|
),
|
|
Package: "erlang",
|
|
PURL: mustPURL("pkg:generic/erlang@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "swipl-binary",
|
|
FileGlob: "**/swipl",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
`(?m)swipl-(?P<version>[0-9]+\.[0-9]+\.[0-9]+)\/`,
|
|
),
|
|
Package: "swipl",
|
|
PURL: mustPURL("pkg:generic/swipl@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "dart-binary",
|
|
FileGlob: "**/dart",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
// MathAtan[NUL]2.12.4 (stable)
|
|
// "%s"[NUL]3.0.0 (stable)
|
|
// Dart,GC"[NUL]3.5.2 (stable)
|
|
// Dart,GC"[NUL]3.6.0-216.1.beta (beta)
|
|
`(?m)\x00(?P<version>[0-9]+\.[0-9]+\.[0-9]+(-[0-9]+(\.[0-9]+)?\.beta)?) `,
|
|
),
|
|
Package: "dart",
|
|
PURL: mustPURL("pkg:generic/dart@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:dart:dart_software_development_kit:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "deno-binary",
|
|
FileGlob: "**/deno",
|
|
EvidenceMatcher: binutils.MatchAny(
|
|
m.FileContentsVersionMatcher(
|
|
// Deno/2.6.3Deno/
|
|
// Deno/1.41.0cli/
|
|
`Deno/(?P<version>[0-9]+\.[0-9]+\.[0-9]+)(Deno/|cli/)`,
|
|
),
|
|
m.FileContentsVersionMatcher(
|
|
// Deno/2.6.3
|
|
// Deno/1.41.0
|
|
`Deno/(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`,
|
|
),
|
|
m.FileContentsVersionMatcher(
|
|
// cli/tools/standalone.rsdeno-canary/f4bed1081456089559c82441a13c4fb700840cac1.11.3dlwindows
|
|
`deno-canary/[0-9a-z]{40}(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`,
|
|
),
|
|
m.FileContentsVersionMatcher(
|
|
// deno::tools::standalonedeno-65db94feba9d4d51a09b74629f566dbc90484fbarelease/v1.29.4windows
|
|
// cli/tools/standalone.rsdeno-74064c9d8c222b33b2a552ea0af1054f57002a96release/v1.28.3windows
|
|
`deno-[0-9a-z]{40}release/v(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`,
|
|
),
|
|
m.FileContentsVersionMatcher(
|
|
// cli/tools/standalone.rsdeno-ab286750a8c87215a9651efb11fcc620f29140051.16.4release/vdlwindows
|
|
`deno-[0-9a-z]{40}(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`,
|
|
),
|
|
m.FileContentsVersionMatcher(
|
|
// 1.10.31567c1013cc8ff12cf039137792da66a1d0015b5DENO_UNSTABLE_COVERAGE_DIRNo current directorycli/main
|
|
`(?P<version>[0-9]+\.[0-9]+\.[0-9]+)[0-9a-z]{40}DENO`,
|
|
),
|
|
),
|
|
Package: "deno",
|
|
PURL: mustPURL("pkg:generic/deno@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:deno:deno:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "bun-binary",
|
|
FileGlob: "**/bun",
|
|
EvidenceMatcher: binutils.MatchAny(
|
|
// bun 1.1.0
|
|
// Bun v1.0.0
|
|
m.FileContentsVersionMatcher(`(?m)[Bb]un v?(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`),
|
|
// bun-1.1.0
|
|
m.FileContentsVersionMatcher(`(?m)bun-(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`),
|
|
),
|
|
Package: "bun",
|
|
PURL: mustPURL("pkg:generic/bun@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:oven-sh:bun:*:*:*:*:*:*:*:*"),
|
|
},
|
|
{
|
|
Class: "haskell-ghc-binary",
|
|
FileGlob: "**/ghc*",
|
|
EvidenceMatcher: binutils.MatchAny(
|
|
m.FileContentsVersionMatcher(
|
|
`(?m)\x00GHC (?P<version>[0-9]+\.[0-9]+\.[0-9]+)\x00`,
|
|
),
|
|
m.FileContentsVersionMatcher(
|
|
// [NUL]libHSghc-7.10.3-0AG9TOjDEtx4Ji3wSwHOBe-ghc7.10.3.so[NUL]
|
|
// [NUL]libHSghc-8.10.4-ghc8.10.4.so[NUL]
|
|
`\x00libHSghc\-(?P<version>[0-9]+\.[0-9]+\.[0-9]+)\-([a-zA-Z0-9]+\-)?ghc[0-9]+\.[0-9]+\.[0-9]+\.so\x00`,
|
|
),
|
|
),
|
|
Package: "haskell/ghc",
|
|
PURL: mustPURL("pkg:generic/haskell/ghc@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:haskell:ghc:*:*:*:*:*:*:*:*"),
|
|
},
|
|
{
|
|
Class: "haskell-cabal-binary",
|
|
FileGlob: "**/cabal",
|
|
EvidenceMatcher: binutils.MatchAny(
|
|
m.FileContentsVersionMatcher(
|
|
`(?m)\x00Cabal-(?P<version>[0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?)-`,
|
|
),
|
|
m.FileContentsVersionMatcher(
|
|
// [NUL][NUL][NUL]/opt/cabal/1.22/lib/x86_64-linux-ghc-7.10.2/cabal-install-1.22.6.0-AfxbHivcmw40BMGrAXG3jJ[NUL][NUL][NUL]
|
|
`\x00.{0,50}cabal\-install\-(?P<version>[0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?)\-[a-zA-Z0-9]+\x00+`,
|
|
),
|
|
),
|
|
Package: "haskell/cabal",
|
|
PURL: mustPURL("pkg:generic/haskell/cabal@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:haskell:cabal:*:*:*:*:*:*:*:*"),
|
|
},
|
|
{
|
|
Class: "haskell-stack-binary",
|
|
FileGlob: "**/stack",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
`(?m)Version\s*(?P<version>[0-9]+\.[0-9]+\.[0-9]+),\s*Git`,
|
|
),
|
|
Package: "haskell/stack",
|
|
PURL: mustPURL("pkg:generic/haskell/stack@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:haskell:stack:*:*:*:*:*:*:*:*"),
|
|
},
|
|
{
|
|
Class: "consul-binary",
|
|
FileGlob: "**/consul",
|
|
EvidenceMatcher: binutils.MatchAny(
|
|
m.FileContentsVersionMatcher(
|
|
// NOTE: This is brittle and may not work for past or future versions
|
|
`CONSUL_VERSION: (?P<version>\d+\.\d+\.\d+)`,
|
|
),
|
|
m.FileContentsVersionMatcher(
|
|
// GitDescribe=1.12.9"
|
|
`GitDescribe=(?P<version>\d+\.\d+\.\d+)\"`,
|
|
),
|
|
m.FileContentsVersionMatcher(
|
|
// [NUL][NUL][NUL]v1.7.14[NUL][NUL][NUL]
|
|
`\x00+v(?P<version>\d+\.\d+\.\d+)\x00+`,
|
|
),
|
|
),
|
|
Package: "consul",
|
|
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: binutils.MatchAny(
|
|
m.FileContentsVersionMatcher(
|
|
// revoke1.18.0
|
|
`(?m)revoke(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`,
|
|
),
|
|
m.FileContentsVersionMatcher(
|
|
// secondsindex_state1.20.0-rc1
|
|
`state(?P<version>[0-9]+\.[0-9]+\.[0-9]+\-rc[0-9])`,
|
|
),
|
|
m.FileContentsVersionMatcher(
|
|
// %s0.0.0.00x%016x1.14.101.49.22123-abc19531252.5.4.32.5.4.52.5.4.62.5.4.72.5.4.82.5.4.92
|
|
// %s0.0.0.00x%016x1.14.3
|
|
// txn0.0.0.00x%016x1.13.13123-abc19531252.5.4.32.5.4.52.5.4.62.5.4.72.5.4.82.5.4.92006-019765625: type ::1/128::ffff::method:
|
|
`016x(?P<version>1.1[1,3,4].[0-9]{1,2})`,
|
|
),
|
|
m.FileContentsVersionMatcher(
|
|
// [NUL][NUL][NUL]1.11.6[NUL][NUL][NUL]
|
|
`\x00+(?P<version>1\.[0-9][0,1]?\.[0-9]+)\x00+`,
|
|
),
|
|
),
|
|
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",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
// [NUL]nginx version: nginx/1.25.1 - fetches '1.25.1'
|
|
// [NUL]nginx version: openresty/1.21.4.1 - fetches '1.21.4' as this is the nginx version part
|
|
`(?m)(\x00|\?)nginx version: [^\/]+\/(?P<version>[0-9]+\.[0-9]+\.[0-9]+(?:\+\d+)?(?:-\d+)?)`,
|
|
),
|
|
Package: "nginx",
|
|
PURL: mustPURL("pkg:generic/nginx@version"),
|
|
CPEs: []cpe.CPE{
|
|
cpe.Must("cpe:2.3:a:f5:nginx:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
cpe.Must("cpe:2.3:a:nginx:nginx:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
},
|
|
{
|
|
Class: "bash-binary",
|
|
FileGlob: "**/bash",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
// @(#)Bash version 5.2.15(1) release GNU
|
|
// @(#)Bash version 5.2.0(1) alpha GNU
|
|
// @(#)Bash version 5.2.0(1) beta GNU
|
|
// @(#)Bash version 5.2.0(1) rc4 GNU
|
|
`(?m)@\(#\)Bash version (?P<version>[0-9]+\.[0-9]+\.[0-9]+)\([0-9]\) [a-z0-9]+ GNU`,
|
|
),
|
|
Package: "bash",
|
|
PURL: mustPURL("pkg:generic/bash@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:gnu:bash:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "openssl-binary",
|
|
FileGlob: "**/openssl",
|
|
EvidenceMatcher: binutils.BranchingEvidenceMatcher([]binutils.Classifier{
|
|
{
|
|
Class: "openssl-binary-aws-lc",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
// [NUL]OpenSSL 1.1.1 (compatible; AWS-LC 1.69.0)[NUL]
|
|
`AWS-LC (?P<version>[0-9]+\.[0-9]+\.[0-9]+)\)\x00`,
|
|
),
|
|
Package: "aws-lc",
|
|
PURL: mustPURL("pkg:generic/aws-lc@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:amazon:aws_libcrypto:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "openssl-binary",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
// [NUL]OpenSSL 3.1.4'
|
|
// [NUL]OpenSSL 1.1.1w'
|
|
`\x00OpenSSL (?P<version>[0-9]+\.[0-9]+\.[0-9]+([a-z]+|-alpha[0-9]|-beta[0-9]|-rc[0-9])?)`,
|
|
),
|
|
Package: "openssl",
|
|
PURL: mustPURL("pkg:generic/openssl@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:openssl:openssl:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
}...),
|
|
},
|
|
{
|
|
Class: "openldap-search-binary",
|
|
FileGlob: "**/ldapsearch",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
// $OpenLDAP: ldapsearch 2.4.45'
|
|
`\$OpenLDAP:\sldapsearch\s(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`,
|
|
),
|
|
Package: "openldap",
|
|
PURL: mustPURL("pkg:generic/openldap@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:openldap:openldap:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "qt-qtbase-lib",
|
|
FileGlob: "**/libQt*Core.so*",
|
|
EvidenceMatcher: binutils.MatchAny(
|
|
// Qt 5.x and Qt 6.x pattern [NUL][NUL]Qt 6.5.0 (x86_64-little_endian-...
|
|
m.FileContentsVersionMatcher(`\x00\x00Qt (?P<version>[0-9]+\.[0-9]+\.[0-9]+) \(`),
|
|
// Qt 4.x pattern QtCore lib ver 4.8.7
|
|
m.FileContentsVersionMatcher(`QtCore library version (?P<version>[0-9]+\.[0-9]+\.[0-9]+)`),
|
|
),
|
|
Package: "qtbase",
|
|
PURL: mustPURL("pkg:generic/qtbase@version"),
|
|
CPEs: []cpe.CPE{
|
|
cpe.Must("cpe:2.3:a:qt:qt:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
cpe.Must("cpe:2.3:a:qt:qtbase:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
},
|
|
{
|
|
Class: "gcc-binary",
|
|
FileGlob: "**/gcc",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
// GCC: \(GNU\) 12.3.0'
|
|
`GCC: \(GNU\) (?P<version>[0-9]+\.[0-9]+\.[0-9]+)`,
|
|
),
|
|
Package: "gcc",
|
|
PURL: mustPURL("pkg:generic/gcc@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:gnu:gcc:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "fluent-bit-binary",
|
|
FileGlob: "**/fluent-bit",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
// [NUL]3.0.2[NUL]%sFluent Bit
|
|
// [NUL]2.2.3[NUL]Fluent Bit
|
|
// [NUL]2.2.1[NUL][NUL][NUL]Fluent Bit
|
|
// [NUL]1.7.0[NUL]\x1b[1m[NUL]%sFluent Bit (versions 1.7.0-dev-3 through 1.7.0-dev-9 and 1.7.0-rc4 through 1.7.0-rc8)
|
|
// [NUL][NUL]1.3.10[NUL][NUL]Fluent Bit v%s
|
|
`\x00(\x00)?(?P<version>[0-9]+\.[0-9]+\.[0-9]+)\x00(\x1b\[1m\x00|\x00|\x00\x00)?(%s)?Fluent`,
|
|
),
|
|
Package: "fluent-bit",
|
|
PURL: mustPURL("pkg:github/fluent/fluent-bit@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:treasuredata:fluent_bit:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "wordpress-cli-binary",
|
|
FileGlob: "**/wp",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
// wp-cli/wp-cli 2.9.0'
|
|
`(?m)wp-cli/wp-cli (?P<version>[0-9]+\.[0-9]+\.[0-9]+)`,
|
|
),
|
|
Package: "wp-cli",
|
|
PURL: mustPURL("pkg:generic/wp-cli@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:wp-cli:wp-cli:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "curl-binary",
|
|
FileGlob: "**/curl",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
`curl/(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`,
|
|
),
|
|
Package: "curl",
|
|
PURL: mustPURL("pkg:generic/curl@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:haxx:curl:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "lighttpd-binary",
|
|
FileGlob: "**/lighttpd",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
`\x00lighttpd/(?P<version>[0-9]+\.[0-9]+\.[0-9]+)\x00`,
|
|
),
|
|
Package: "lighttpd",
|
|
PURL: mustPURL("pkg:generic/lighttpd@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:lighttpd:lighttpd:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "proftpd-binary",
|
|
FileGlob: "**/proftpd",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
`\x00ProFTPD Version (?P<version>[0-9]+\.[0-9]+\.[0-9]+[a-z]?)\x00`,
|
|
),
|
|
Package: "proftpd",
|
|
PURL: mustPURL("pkg:generic/proftpd@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:proftpd:proftpd:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "zstd-binary",
|
|
FileGlob: "**/zstd",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
`\x00v(?P<version>[0-9]+\.[0-9]+\.[0-9]+)\x00`,
|
|
),
|
|
Package: "zstd",
|
|
PURL: mustPURL("pkg:generic/zstd@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:facebook:zstandard:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "xz-binary",
|
|
FileGlob: "**/xz",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
`\x00xz \(XZ Utils\) (?P<version>[0-9]+\.[0-9]+\.[0-9]+)\x00`,
|
|
),
|
|
Package: "xz",
|
|
PURL: mustPURL("pkg:generic/xz@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:tukaani:xz:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "gzip-binary",
|
|
FileGlob: "**/gzip",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
// GNU gzip keeps the version as a bare NUL-delimited token, so require an identifying
|
|
// string from the program as well. Without it any binary that happens to be named gzip
|
|
// (such as the busybox multicall binary behind a gzip applet symlink) would have an
|
|
// arbitrary NUL-delimited "N.N" token reported as a GNU gzip version.
|
|
`%s: %s: not in gzip format`,
|
|
`\x00(?P<version>[0-9]+\.[0-9]+)\x00`,
|
|
),
|
|
Package: "gzip",
|
|
PURL: mustPURL("pkg:generic/gzip@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:gnu:gzip:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "sqlcipher-binary",
|
|
FileGlob: "**/sqlcipher",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
`[^0-9]\x00(?P<version>[0-9]+\.[0-9]+\.[0-9]+)\x00`,
|
|
),
|
|
Package: "sqlcipher",
|
|
PURL: mustPURL("pkg:generic/sqlcipher@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:zetetic:sqlcipher:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "jq-binary",
|
|
FileGlob: "**/jq",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
`\x00(?P<version>[0-9]{1,3}\.[0-9]{1,3}(\.[0-9]+)?)\x00`,
|
|
),
|
|
Package: "jq",
|
|
PURL: mustPURL("pkg:generic/jq@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:jqlang:jq:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "chrome-binary",
|
|
FileGlob: "**/chrome",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
// [NUL]127.0.6533.119[NUL]Default
|
|
`\x00(?P<version>[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\x00Default`,
|
|
),
|
|
Package: "chrome",
|
|
PURL: mustPURL("pkg:generic/chrome@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:google:chrome:*:*:*:*:*:*:*:*"),
|
|
},
|
|
{
|
|
Class: "firefox-binary",
|
|
FileGlob: "**/{firefox,firefox.exe}",
|
|
EvidenceMatcher: binutils.SupportingEvidenceMatcher(
|
|
"application.ini",
|
|
m.FileContentsVersionMatcher(
|
|
`(?ms)^Name=Firefox\r?$.*?^Version=(?P<version>[0-9]+(?:\.[0-9]+)+(?:[A-Za-z][0-9A-Za-z.-]*)?)\r?$`,
|
|
),
|
|
),
|
|
Package: "firefox",
|
|
PURL: mustPURL("pkg:generic/firefox@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:mozilla:firefox:*:*:*:*:*:*:*:*"),
|
|
},
|
|
{
|
|
Class: "ffmpeg-binary",
|
|
FileGlob: "**/ffmpeg",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
// Pattern found in the binary: "%s version 7.1.1" or "%s version 6.0"
|
|
// When executed outputs: "ffmpeg version 7.1.1" or "ffmpeg version 6.0"
|
|
`(?m)%s version (?P<version>[0-9]+\.[0-9]+(\.[0-9]+)?)`,
|
|
),
|
|
Package: "ffmpeg",
|
|
PURL: mustPURL("pkg:generic/ffmpeg@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:ffmpeg:ffmpeg:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "ffmpeg-library",
|
|
FileGlob: "**/libav*",
|
|
EvidenceMatcher: binutils.MatchAny(
|
|
// Primary pattern: FFmpeg version found in most libraries
|
|
m.FileContentsVersionMatcher(`(?m)FFmpeg version (?P<version>[0-9]+\.[0-9]+(\.[0-9]+)?)`),
|
|
// Fallback: library-specific version patterns for libavcodec and libavformat
|
|
m.FileContentsVersionMatcher(`(?m)Lavc(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`),
|
|
m.FileContentsVersionMatcher(`(?m)Lavf(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`),
|
|
),
|
|
Package: "ffmpeg",
|
|
PURL: mustPURL("pkg:generic/ffmpeg@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:ffmpeg:ffmpeg:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "ffmpeg-library",
|
|
FileGlob: "**/libswresample*",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
// FFmpeg version pattern for libswresample
|
|
`(?m)FFmpeg version (?P<version>[0-9]+\.[0-9]+(\.[0-9]+)?)`),
|
|
Package: "ffmpeg",
|
|
PURL: mustPURL("pkg:generic/ffmpeg@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:ffmpeg:ffmpeg:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "elixir-binary",
|
|
FileGlob: "**/elixir",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
// Capture optional pre-release suffix (-rc.1, -alpha.0, -beta.2,
|
|
// etc.) so release-candidate elixir images (#4819) match.
|
|
`(?m)ELIXIR_VERSION=(?P<version>[0-9]+\.[0-9]+\.[0-9]+(?:-[a-z0-9]+(?:\.[0-9]+)?)?)`),
|
|
Package: "elixir",
|
|
PURL: mustPURL("pkg:generic/elixir@version"),
|
|
CPEs: []cpe.CPE{
|
|
cpe.Must("cpe:2.3:a:elixir-lang:elixir:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
},
|
|
{
|
|
Class: "elixir-library",
|
|
FileGlob: "**/elixir/ebin/elixir.app",
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
// Same pre-release extension as elixir-binary above.
|
|
`(?m)\{vsn,"(?P<version>[0-9]+\.[0-9]+\.[0-9]+(?:-[a-z0-9]+(?:\.[0-9]+)?)?)"\}`),
|
|
Package: "elixir",
|
|
PURL: mustPURL("pkg:generic/elixir@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:elixir-lang:elixir:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "istio-binary",
|
|
FileGlob: "**/pilot-discovery",
|
|
EvidenceMatcher: binutils.MatchAny(
|
|
// [NUL]1.26.8[NUL][NUL]1.26.8[NUL]
|
|
// [NUL]1.3.7[NUL][NUL][NUL]1.3.8[NUL]
|
|
m.FileContentsVersionMatcher(`[0-9]+\.[0-9]+\.[0-9]+\x00+(?P<version>[0-9]+\.[0-9]+\.[0-9]+(-alpha\.[0-9]+|-beta\.[0-9]+|-rc\.[0-9]+|-dev)?)\x00+`),
|
|
// Clean[NUL][NUL][NUL]1.8.0[NUL]
|
|
m.FileContentsVersionMatcher(`Clean\x00+(?P<version>[0-9]+\.[0-9]+\.[0-9]+(-alpha\.[0-9]+|-beta\.[0-9]+|-rc\.[0-9]+|-dev)?)\x00+`),
|
|
// Modified[NUL][NUL][NUL][NUL][NUL][NUL][NUL][NUL]1.10-dev[NUL][NUL][NUL]
|
|
m.FileContentsVersionMatcher(`Modified\x00+(?P<version>[0-9]+\.[0-9]+-dev)\x00+`),
|
|
// 1.1.17[NUL]...S=v<y5
|
|
m.FileContentsVersionMatcher(`(?s)(?P<version>[0-9]+\.[0-9]+\.[0-9]+(-alpha\.[0-9]+|-beta\.[0-9]+|-rc\.[0-9]+|-dev)?)\x00+.{1,100}S?=v<y5`),
|
|
),
|
|
Package: "pilot-discovery",
|
|
PURL: mustPURL("pkg:generic/istio@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:istio:istio:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "istio-binary",
|
|
FileGlob: "**/pilot-agent",
|
|
EvidenceMatcher: binutils.MatchAny(
|
|
// [NUL]1.26.8[NUL][NUL]1.26.8[NUL]
|
|
m.FileContentsVersionMatcher(`[0-9]+\.[0-9]+\.[0-9]+\x00+(?P<version>[0-9]+\.[0-9]+\.[0-9]+(-alpha\.[0-9]+|-beta\.[0-9]+|-rc\.[0-9]+|-dev)?)\x00+`),
|
|
// Clean[NUL][NUL][NUL]1.8.0[NUL]
|
|
m.FileContentsVersionMatcher(`Clean\x00+(?P<version>[0-9]+\.[0-9]+\.[0-9]+(-alpha\.[0-9]+|-beta\.[0-9]+|-rc\.[0-9]+|-dev)?)\x00+`),
|
|
// Modified[NUL][NUL][NUL][NUL][NUL][NUL][NUL][NUL]1.10-dev[NUL][NUL][NUL]
|
|
m.FileContentsVersionMatcher(`Modified\x00+(?P<version>[0-9]+\.[0-9]+-dev)\x00+`),
|
|
// 1.1.17[NUL]...S=v<y5
|
|
m.FileContentsVersionMatcher(`(?s)(?P<version>[0-9]+\.[0-9]+\.[0-9]+(-alpha\.[0-9]+|-beta\.[0-9]+|-rc\.[0-9]+|-dev)?)\x00+.{1,100}S?=v<y5`),
|
|
),
|
|
Package: "pilot-agent",
|
|
PURL: mustPURL("pkg:generic/istio@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:istio:istio:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "grafana-binary",
|
|
FileGlob: "**/grafana",
|
|
EvidenceMatcher: binutils.MatchAny(
|
|
// [NUL][NUL][NUL][NUL]12.2.0-258092[NUL][NUL][NUL][NUL]
|
|
m.FileContentsVersionMatcher(`\x00+(?P<version>[0-9]{2}\.[0-9]+\.[0-9]+\-[0-9]{6,})\x00+`),
|
|
// security patch releases embed the raw version constant with no "release-" prefix
|
|
// and are not always preceded by NUL bytes (e.g. on arm builds):
|
|
// [NUL]11.0.5+security-01[NUL][NUL]call frame too large
|
|
// [NUL]12.4.3+security-02[NUL][NUL]
|
|
m.FileContentsVersionMatcher(`\x00(?P<version>[0-9]{1,2}\.[0-9]+\.[0-9]+)\+security-[0-9]+\x00`),
|
|
// [NUL][NUL][NUL][NUL]release-12.3.2+security-01[NUL][NUL][NUL][NUL]
|
|
// [NUL][NUL][NUL][NUL]release-12.3.1[NUL][NUL][NUL][NUL]
|
|
m.FileContentsVersionMatcher(`\x00+release-(?P<version>[0-9]{2}\.[0-9]+\.[0-9]+(-beta[0-9]|-test|-preview)?)(\+security-[0-9]+)?\x00+`),
|
|
// [NUL][NUL][NUL][NUL]go1.21.8[NUL][NUL][NUL][NUL][NUL][NUL][NUL][NUL]11.0.0-preview[NUL][NUL]...+DT
|
|
m.FileContentsVersionMatcher(`(?s)\x00+go1\.[0-9]+\.[0-9]+\x00+(?P<version>[0-9]{2}\.[0-9]+\.[0-9]+(-beta[0-9]|-test|-preview)?)(\+security-[0-9]+)?\x00+.{1,500}\+DT`),
|
|
// HEAD[NUL][NUL][NUL][NUL]12.0.0[NUL][NUL]$a
|
|
// 11.0.0[NUL][NUL]$a
|
|
m.FileContentsVersionMatcher(`(?P<version>[0-9]{2}\.[0-9]+\.[0-9]+(-beta[0-9]|-test|-preview)?)(\+security-[0-9]+)?\x00+\$a`),
|
|
// [NUL]0xDC0xBF10.4.19[NUL]
|
|
m.FileContentsVersionMatcher(`\x00.(?P<version>10\.[0-9]+\.[0-9]+(-beta[0-9]|-test|-preview)?)(\+security-[0-9]+)?\x00`),
|
|
// 10.3.12[NUL]...[NUL]go1.22.7[NUL][NUL][NUL][NUL]...+DT
|
|
m.FileContentsVersionMatcher(`(?s)(?P<version>[0-9]{2}\.[0-9]+\.[0-9]+(-beta[0-9]|-test|-preview)?)(\+security-[0-9]+)?\x00+.{1,100}\x00go1\.[0-9]+\.[0-9]+\x00.{1,100}\+DT`),
|
|
// 9.5.21[NUL][NUL]v9.5.x[NUL][NUL][NUL][NUL][NUL][NUL]$a
|
|
m.FileContentsVersionMatcher(`(?P<version>[0-9]+\.[0-9]+\.[0-9]+(-beta[0-9]|-test|-preview)?)(\+security-[0-9]+)?\x00+v[0-9]+\.[0-9]+\.x\x00+`),
|
|
// HEAD[NUL][NUL][NUL][NUL]9.2.20[NUL][NUL][NUL][NUL]
|
|
// HEAD[NUL][NUL]:[NUL][NUL][NUL][NUL][NUL][NUL][NUL][NUL][NUL]9.2.13[NUL][NUL][NUL][NUL]
|
|
m.FileContentsVersionMatcher(`HEAD\x00+.*\x00+(?P<version>[0-9]\.[0-9]+\.[0-9]+(-beta[0-9]|-test|-preview)?)(\+security-[0-9]+)?\x00+`),
|
|
// 1b0f5f0a81[NUL][NUL][NUL][NUL][NUL][NUL]9.4.0-beta1[NUL][NUL][NUL][NUL][NUL]/usr/local/go
|
|
m.FileContentsVersionMatcher(`[a-z0-9]+\x00+(?P<version>[0-9]\.[0-9]+\.[0-9]+(-beta[0-9]|-test|-preview)?)(\+security-[0-9]+)?\x00+\/usr\/local\/go`),
|
|
),
|
|
Package: "grafana",
|
|
PURL: mustPURL("pkg:generic/grafana@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:grafana:grafana:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "grafana-binary",
|
|
FileGlob: "**/grafana-server",
|
|
EvidenceMatcher: binutils.MatchAny(
|
|
// 78f0340031[NUL][NUL][NUL][NUL][NUL][NUL]9.3.0-beta1[NUL][NUL][NUL][NUL][NUL]/usr/local/go
|
|
m.FileContentsVersionMatcher(`[a-z0-9]+\x00+(?P<version>[0-9]\.[0-9]+\.[0-9]+(-beta[0-9]|-test)?)\x00+\/usr\/local\/go`),
|
|
// HEAD[NUL][NUL][NUL][NUL]9.0.0[NUL]:[NUL]
|
|
// HEAD[NUL][NUL][NUL][NUL]:[NUL][NUL][NUL][NUL][NUL][NUL][NUL]7.5.17[NUL][NUL][NUL][NUL]
|
|
// HEAD[NUL][NUL][NUL][NUL]m[NUL]...[NUL][NUL]6.7.6[NUL][NUL][NUL].[NUL][NUL][NUL][NUL][NUL][NUL][NUL]:
|
|
m.FileContentsVersionMatcher(`HEAD\x00+.*\x00+(?P<version>[0-9]\.[0-9]+\.[0-9]+(-beta[0-9]|-test)?)\x00+`),
|
|
// [NUL][NUL][NUL][NUL][NUL]6.7.0-test[NUL][NUL][NUL]...[NUL][NUL][NUL][NUL]/usr/local/go
|
|
// [NUL][NUL][NUL][NUL][NUL]6.0.0-beta1[NUL][NUL][NUL]...[NUL][NUL][NUL][NUL]/usr/local/go
|
|
m.FileContentsVersionMatcher(`(?s)\x00+(?P<version>[0-9]\.[0-9]+\.[0-9]+(-beta[0-9]|-test)?)\x00+.*\x00+.{1,1000}\x00+\/u`),
|
|
),
|
|
Package: "grafana",
|
|
PURL: mustPURL("pkg:generic/grafana@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:grafana:grafana:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "envoy-binary",
|
|
FileGlob: "**/envoy",
|
|
EvidenceMatcher: binutils.MatchAny(
|
|
// 1.3x [NUL]1.36.4[NUL]...envoy_reloadable_features
|
|
// 1.34.5 [NUL]1.34.5[NUL]...envoy.reloadable_features
|
|
m.FileContentsVersionMatcher(`(?s)\x00(?P<version>1\.3[0-9]\.[0-9]+(-dev)?)\x00.{0,1000}envoy_reloadable_features`),
|
|
m.FileContentsVersionMatcher(`(?s)\x00(?P<version>1\.34\.5)\x00.{0,200}envoy\.reloadable_features`),
|
|
// 1.2x envoy_quic_...[NUL]1.28.7[NUL]
|
|
m.FileContentsVersionMatcher(`(?s)envoy_quic_.{0,1000}\x00(?P<version>1\.2[0-9]\.[0-9]+(-dev)?)\x00`),
|
|
// 1.2x [NUL]1.20.7[NUL]Unable to
|
|
// 1.1x [NUL]1.18.6-dev[NUL]Unable to
|
|
m.FileContentsVersionMatcher(`(?s)\x00(?P<version>1\.[12][0-9]\.[0-9]+(-dev)?)\x00.{0,1000}Unable to`),
|
|
// 1.2x [NUL]1.22.11[NUL]...ValidationError
|
|
// 1.1x [NUL]1.14.3[NUL]...ValidationError
|
|
m.FileContentsVersionMatcher(`(?s)\x00(?P<version>1\.2[0-9]\.[0-9]+(-dev)?)\x00.{0,580}ValidationError`),
|
|
m.FileContentsVersionMatcher(`(?s)\x00(?P<version>1\.1[0-9]\.[0-9]+(-dev)?)\x00.{0,1000}ValidationError`),
|
|
// 1.1x [source...[NUL]1.11.0[NUL]/
|
|
m.FileContentsVersionMatcher(`(?s)\[source/.{0,200}\x00(?P<version>1\.1[0-9]\.[0-9]+(-dev)?)\x00`),
|
|
// 1.x [NUL]1.6.0[NUL]RELEASE
|
|
m.FileContentsVersionMatcher(`(?s)\x00(?P<version>1\.[0-9]\.[0-9]+(-dev)?)\x00.{0,20}RELEASE`),
|
|
// contrib 1.3x [NUL]1.34.12[NUL]envoy_quiche... or [NUL]1.30.2[NUL]envoy/extensions... or [NUL]1.30.8[NUL]envoy://
|
|
m.FileContentsVersionMatcher(`(?s)\x00(?P<version>1\.3[0-9]\.[0-9]+(-dev)?)\x00envoy[/._:]`),
|
|
// contrib 1.3x [NUL]1.30.7[NUL]...envoy.service or [NUL]1.30.6[NUL]...envoy.data
|
|
m.FileContentsVersionMatcher(`(?s)\x00(?P<version>1\.3[0-9]\.[0-9]+(-dev)?)\x00.{0,200}envoy[./]`),
|
|
// contrib1.3x [NUL]1.31.2[NUL]...envoy_quic or [NUL]1.36.x[NUL]...envoy_quic
|
|
m.FileContentsVersionMatcher(`(?s)\x00(?P<version>1\.3[0-9]\.[0-9]+(-dev)?)\x00.{0,1000}envoy_quic`),
|
|
// contrib 1.3x [NUL]1.30.1[NUL]TLS client
|
|
m.FileContentsVersionMatcher(`(?s)\x00(?P<version>1\.3[0-9]\.[0-9]+(-dev)?)\x00TLS `),
|
|
// contrib 1.2x [NUL]1.24.9[NUL]envoy/extensions...
|
|
m.FileContentsVersionMatcher(`(?s)\x00(?P<version>1\.2[0-9]\.[0-9]+(-dev)?)\x00envoy[/._]`),
|
|
// contrib 1.2x [NUL]1.22.10[NUL]...envoy. or [NUL]1.24.5[NUL]...envoy.
|
|
m.FileContentsVersionMatcher(`(?s)\x00(?P<version>1\.2[0-9]\.[0-9]+(-dev)?)\x00.{0,500}envoy\.`),
|
|
// contrib 1.2x [NUL]1.23.7[NUL]...envoy_internal
|
|
m.FileContentsVersionMatcher(`(?s)\x00(?P<version>1\.2[0-9]\.[0-9]+(-dev)?)\x00.{0,300}envoy_`),
|
|
),
|
|
Package: "envoy",
|
|
PURL: mustPURL("pkg:generic/envoy@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:envoyproxy:envoy:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "mongodb-binary",
|
|
FileGlob: "**/mongod",
|
|
EvidenceMatcher: binutils.MatchAny(
|
|
// mongodb 4.x, 5.x, 6.x: ber followed by tcmalloc
|
|
// e.g 6.0.27[NUL]tcmalloc
|
|
m.FileContentsVersionMatcher(`(?P<version>[0-9]+\.[0-9]+\.[0-9]+)\x00tcmalloc`),
|
|
// mongodb 7.x: ver followed by "heap_size"
|
|
// e.g 7.0.28[NUL]heap_size
|
|
m.FileContentsVersionMatcher(`(?P<version>[0-9]+\.[0-9]+\.[0-9]+)\x00+heap_size`),
|
|
// mongodb 8.x: ber followed by "cppdefines"
|
|
// e.g 8.0.17[NUL]cppdefines
|
|
m.FileContentsVersionMatcher(`(?P<version>[0-9]+\.[0-9]+\.[0-9]+)\x00+cppdefines`),
|
|
),
|
|
Package: "mongodb",
|
|
PURL: mustPURL("pkg:generic/mongodb@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:mongodb:mongodb:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "ingress-nginx-binary",
|
|
FileGlob: "**/nginx-ingress-controller",
|
|
EvidenceMatcher: binutils.MatchAny(
|
|
// the release is injected with -ldflags -X, which lands it in its own NUL-padded data symbol.
|
|
// the surrounding bytes are an arch-specific float constant pool, so only the padding is portable.
|
|
// e.g. v1.9.6[NUL][NUL] on each of linux/amd64, linux/arm, linux/arm64, and linux/s390x
|
|
// note: one trailing NUL is not enough -- on s390x that matches a vendored "v1.19.0" earlier in the file
|
|
m.FileContentsVersionMatcher(`v(?P<version>[0-9]+\.[0-9]+\.[0-9]+(\-(alpha|beta)\.[0-9]+)?)\x00\x00`),
|
|
// [NUL][NUL]v1.15.1[NUL][NUL]@e[ETX][NUL][NUL][NUL][NUL]go1.26.1[NUL][NUL][NUL]
|
|
// �v1.15.1[NUL][NUL]�z[ETX][NUL][NUL][NUL][NUL]go1.24.4[NUL][NUL][NUL]
|
|
m.FileContentsVersionMatcher(`v(?P<version>[0-9]+\.[0-9]+\.[0-9]+)\x00+.{0,50}go[0-9]+\.[0-9]+(\-(alpha|beta)\.[0-9])?\.[0-9]+\x00+`),
|
|
// �Lv1.9.6[NUL][NUL]$a�c[SOH][NUL][NUL][NUL]
|
|
// [NUL][NUL]v0.34.0[NUL]......�$a�...[NUL]
|
|
m.FileContentsVersionMatcher(`v(?P<version>[0-9]+\.[0-9]+\.[0-9]+(\-(alpha|beta)\.[0-9])?)\x00+.{0,800}\$a.{0,10}\x00+`),
|
|
// [NUL][NUL]v1.7.1[NUL][NUL][NUL]...S=v<y5...
|
|
// [NUL]0.33.0[NUL][NUL]...[NUL][NUL]...S=v<y5
|
|
m.FileContentsVersionMatcher(`\x00+v?(?P<version>[0-9]+\.[0-9]+\.[0-9]+(\-(alpha|beta)\.[0-9])?)\x00+.{0,100}S=v<y5`),
|
|
// [NUL][NUL]go1.22.8[NUL][NUL][NUL][NUL][NUL][NUL][NUL][NUL][NUL]v1.12.0-beta.0[NUL][NUL]
|
|
m.FileContentsVersionMatcher(`\x00+go[0-9]+\.[0-9]+\.[0-9]+\x00+v(?P<version>[0-9]+\.[0-9]+\.[0-9]+(\-(alpha|beta)\.[0-9])?)\x00+`),
|
|
// [NUL][NUL]v1.2.0-beta.1[NUL][NUL]
|
|
// [NUL][NUL]v1.0.0-alpha.2[NUL][NUL]
|
|
m.FileContentsVersionMatcher(`\x00+v(?P<version>[0-9]+\.[0-9]+\.[0-9]+\-(alpha|beta)\.[0-9])\x00+`),
|
|
),
|
|
Package: "nginx-ingress-controller",
|
|
PURL: mustPURL("pkg:generic/nginx-ingress-controller@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:kubernetes:ingress-nginx:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "filebeat-binary",
|
|
FileGlob: "**/filebeat",
|
|
EvidenceMatcher: elasticBeatsMatcher,
|
|
Package: "filebeat",
|
|
PURL: mustPURL("pkg:generic/filebeat@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:elastic:filebeat:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "metricbeat-binary",
|
|
FileGlob: "**/metricbeat",
|
|
EvidenceMatcher: elasticBeatsMatcher,
|
|
Package: "metricbeat",
|
|
PURL: mustPURL("pkg:generic/metricbeat@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:elastic:metricbeat:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "heartbeat-binary",
|
|
FileGlob: "**/heartbeat",
|
|
EvidenceMatcher: elasticBeatsMatcher,
|
|
Package: "heartbeat",
|
|
PURL: mustPURL("pkg:generic/heartbeat@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:elastic:heartbeat:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "packetbeat-binary",
|
|
FileGlob: "**/packetbeat",
|
|
EvidenceMatcher: elasticBeatsMatcher,
|
|
Package: "packetbeat",
|
|
PURL: mustPURL("pkg:generic/packetbeat@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:elastic:packetbeat:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "auditbeat-binary",
|
|
FileGlob: "**/auditbeat",
|
|
EvidenceMatcher: elasticBeatsMatcher,
|
|
Package: "auditbeat",
|
|
PURL: mustPURL("pkg:generic/auditbeat@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:elastic:auditbeat:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "elastic-agent-binary",
|
|
FileGlob: "**/elastic-agent",
|
|
EvidenceMatcher: binutils.MatchAny(
|
|
// 9.4.x: config/statsenroll: true9.4.2-headeruint16secret
|
|
// 9.0.x: configenroll9.0.0-headeruint16secret
|
|
// 8.19.x: config/statsenroll8.19.4headeruint16secret
|
|
m.FileContentsVersionMatcher(`enroll(?:: true)?(?P<version>[0-9]+\.[0-9]+\.[0-9]+)-?header`),
|
|
// 8.11.x: 3:04PM8.11.2:https
|
|
m.FileContentsVersionMatcher(`PM(?P<version>[0-9]+\.[0-9]+\.[0-9]+):https`),
|
|
),
|
|
Package: "elastic-agent",
|
|
PURL: mustPURL("pkg:generic/elastic-agent@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:elastic:elastic_agent:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "krb5-library",
|
|
FileGlob: "**/libkrb5.so*",
|
|
// [NUL]KRB5_BRAND: krb5-1.18.4-final 1.18.4 20210722
|
|
// [NUL]KRB5_BRAND: krb5-1.17-final 1.17 20190108 (base releases brand as 2-component)
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
`\x00KRB5_BRAND:\s+krb5-[^\s]+\s+(?P<version>[0-9]+(?:\.[0-9]+){1,2})(?:\s|$)`,
|
|
),
|
|
Package: "krb5",
|
|
PURL: mustPURL("pkg:generic/krb5@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:mit:kerberos_5:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
{
|
|
Class: "heimdal-krb5-library",
|
|
FileGlob: "**/libkrb5.so*",
|
|
// $Version: Heimdal 7.5.0
|
|
// $Version: Heimdal 7.8.0
|
|
// $Version: Heimdal 7.1
|
|
// $Version: Heimdal 7.0.3
|
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
|
`(?m)\$Version:\s+Heimdal\s+(?P<version>[0-9]+(?:\.[0-9]+){1,2})(?:\s|$)`,
|
|
),
|
|
Package: "heimdal-krb5",
|
|
PURL: mustPURL("pkg:generic/heimdal-krb5@version"),
|
|
CPEs: singleCPE("cpe:2.3:a:heimdal_project:heimdal:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
|
},
|
|
}
|
|
|
|
return append(classifiers, defaultJavaClassifiers()...)
|
|
}
|
|
|
|
// singleCPE returns a []cpe.CPE with Source: Generated based on the cpe string or panics if the
|
|
// cpe string cannot be parsed into valid CPE Attributes
|
|
func singleCPE(cpeString string, source ...cpe.Source) []cpe.CPE {
|
|
src := cpe.GeneratedSource
|
|
if len(source) > 0 {
|
|
src = source[0]
|
|
}
|
|
return []cpe.CPE{
|
|
cpe.Must(cpeString, src),
|
|
}
|
|
}
|
|
|
|
func mustPURL(purl string) packageurl.PackageURL {
|
|
p, err := packageurl.FromString(purl)
|
|
if err != nil {
|
|
panic(fmt.Sprintf("invalid PURL: %s", p))
|
|
}
|
|
return p
|
|
}
|