vexrules

package
v1.12.1 Latest Latest
Warning

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

Go to latest
Published: Aug 2, 2026 License: AGPL-3.0 Imports: 20 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 cel.NewEnv(
		cel.Variable("vuln", cel.AnyType),
		cel.Function("matchesPattern",
			cel.Overload(
				"matchesPattern_vuln_list",
				[]*cel.Type{cel.DynType, cel.ListType(cel.StringType)},
				cel.BoolType,
				cel.BinaryBinding(func(lhs, rhs ref.Val) ref.Val {
					path, err := stringListField(lhs, "vulnerabilityPath")
					if err != nil {
						return types.NewErr("matchesPattern: invalid vuln.vulnerabilityPath: %v", err)
					}
					artifactPurls, err := stringListField(lhs, "artifactPurls")
					if err != nil {
						return types.NewErr("matchesPattern: invalid vuln.artifactPurls: %v", err)
					}
					pattern, err := toStringList(rhs)
					if err != nil {
						return types.NewErr("matchesPattern: invalid pattern argument: %v", err)
					}
					matches := PathPattern(pattern).Matches(path, artifactPurls)
					return types.Bool(matches)
				}),
			),
		),
		cel.Function("matchesPurl",
			cel.Overload("matchesPurl_string_string", []*cel.Type{cel.StringType, cel.StringType}, cel.BoolType,
				cel.BinaryBinding(func(lhs, rhs ref.Val) ref.Val {
					purl, ok := lhs.Value().(string)
					if !ok {
						return types.NewErr("matchesPurl: invalid purl argument: %v", lhs)
					}
					pattern, ok := rhs.Value().(string)
					if !ok {
						return types.NewErr("matchesPurl: invalid pattern argument: %v", rhs)
					}
					purlObj, err := packageurl.FromString(purl)
					if err != nil {
						return types.NewErr("matchesPurl: invalid purl: %v", err)
					}
					patternObj, err := packageurl.FromString(pattern)
					if err != nil {
						return types.NewErr("matchesPurl: invalid pattern purl: %v", err)
					}

					matches, err := PurlVersionMatches(patternObj, purlObj)
					if err != nil {
						return types.NewErr("matchesPurl: %v", err)
					}

					return types.Bool(matches)
				}),
			),
		),
	)
})

Functions

func CompileRules

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

func EvalCompiledRules

func EvalCompiledRules(ctx context.Context, compiled map[string]cel.Program, 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 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 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.

Jump to

Keyboard shortcuts

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