vexrules

package
v1.13.7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 11, 2026 License: AGPL-3.0 Imports: 21 Imported by: 0

Documentation

Overview

Copyright (C) 2026 l3montree GmbH

This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.

Index

Constants

View Source
const (
	// PathPatternWildcard matches any path element at that position
	PathPatternWildcard = "*"
)

PathPattern wildcard for VEX rules

Variables

View Source
var CelEnv = sync.OnceValues(func() (*cel.Env, error) {
	return newCelEnv(func(pattern, path, artifactPurls []string) bool {
		return PathPattern(pattern).Matches(path, artifactPurls)
	})
})

CelEnv is the CEL environment used for real VEX rule matching, where the vuln's real artifacts are known.

View Source
var SoftMatchCelEnv = sync.OnceValues(func() (*cel.Env, error) {
	return newCelEnv(func(pattern, path, _ []string) bool {
		return PathPattern(pattern).SoftMatches(path)
	})
})

SoftMatchCelEnv is for callers that haven't loaded artifacts at all - e.g. crowdsourced-vexing's soft-match phase, run against representative vulns before their real artifacts are known. See PathPattern.SoftMatches for the semantics this widens matchesPattern to.

Functions

func CompileRules

func CompileRules(ctx context.Context, rules []models.UpstreamVEXRule) (map[string]CompiledRule, error)

CompileRules compiles every rule's CEL expression against the real-match CelEnv. cel.Env is safe for concurrent Compile/Program calls, so rules are compiled in parallel batches.

func CompileRulesForSoftMatching added in v1.12.5

func CompileRulesForSoftMatching(ctx context.Context, rules []models.UpstreamVEXRule) (map[string]CompiledRule, error)

CompileRulesForSoftMatching is CompileRules against SoftMatchCelEnv, for crowdsourced-vexing's soft-match phase over vulns without real artifacts.

func EvalCompiledRules

func EvalCompiledRules(ctx context.Context, compiled map[string]CompiledRule, vulnMaps []map[string]any) (map[string][]string, error)

returns map keyed by vulnID and value is a list of ruleIDs that match that vuln

func IdentityOfRule

func IdentityOfRule(rule models.UpstreamVEXRule) (string, error)

func PrepareVulnsForEval

func PrepareVulnsForEval(ctx context.Context, vulns []models.DependencyVuln) ([]map[string]any, error)

func PrepareVulnsForEvalMap added in v1.12.5

func PrepareVulnsForEvalMap(ctx context.Context, vulns []models.DependencyVuln) (map[string]map[string]any, error)

func PurlVersionMatches

func PurlVersionMatches(patternPurl, pathPurl packageurl.PackageURL) (bool, error)

func ToCELExpression

func ToCELExpression(cveID string, pattern PathPattern) string

func VexRuleTitle

func VexRuleTitle(cveID string, pattern PathPattern) string

Types

type CompiledRule added in v1.12.3

type CompiledRule struct {
	Program  cel.Program
	CVEScope *string
}

CompiledRule pairs a compiled CEL program with the CVE scope of the rule it came from, so EvalCompiledRules can narrow evaluation to just the vulns sharing that CVE instead of cross-evaluating every rule against every vuln in the batch (a scoped rule's own vuln.cveId == "..." check would reject every mismatch anyway - this just skips paying for that Eval call at all).

type PathPattern

type PathPattern []string

PathPattern represents a path pattern with wildcards. Patterns use suffix matching where "*" can match any number of path elements. A wildcard "*" can appear at any position to match zero or more path elements. Examples:

  • ["pkg:golang/lib@v1.0"] matches paths ending with exactly this element
  • ["*", "pkg:golang/lib@v1.0"] matches paths ending with any elements followed by this element
  • ["*"] matches any path suffix

func (PathPattern) Matches

func (p PathPattern) Matches(path []string, artifactPurls []string) bool

Matches is like matchesSuffix, but first strips a leading pattern element that identifies one of the vulnerability's own artifacts.

VulnerabilityPath is always component-only and never includes the artifact's own identity, but devguard's own exports (CSAF, CycloneDX VEX) always include the artifact as the path's root. A pattern reconstructed from such an export - e.g. a downloaded VEX document being re-uploaded - would otherwise carry that artifact element as its first path segment and never match any real vulnerability path.

Once stripped, the remainder is matched exactly from the start of path (like the ROOT stop-marker case in matchesSuffix), not as a generic suffix: the artifact anchors the pattern to the absolute root of the dependency graph, so a shorter pattern must not match as a mere suffix of a longer, distinct path through a shared component - that per-path distinction is exactly what CSAF's product tree encodes.

func (PathPattern) SoftMatches added in v1.12.5

func (p PathPattern) SoftMatches(path []string) bool

SoftMatches is Matches for callers that haven't loaded artifacts at all (e.g. crowdsourced-vexing's soft-match phase, run against representative vulns before their real artifacts are known). It always assumes the artifact-anchor element would have matched, since a real vuln always has at least one artifact and none can be ruled out here - so a "no match" from SoftMatches reliably implies Matches would also not match once real artifacts are loaded, but a "match" is only a candidate to confirm.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL