dynamicpathdetector

package
v0.0.290 Latest Latest
Warning

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

Go to latest
Published: Jun 26, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Index

Constants

View Source
const (
	DynamicIdentifier  string = "⋯"  // U+22EF: ⋯ (one segment / one arg)
	WildcardIdentifier string = "*"  // zero-or-more path segments (opens only)
	ExecArgsWildcard   string = "⋯⋯" // zero-or-more whole exec args
)

--- Identifier constants --- DynamicIdentifier matches exactly one path segment (single-segment wildcard), and in exec args matches exactly one whole argument. WildcardIdentifier matches zero-or-more path segments (glob-style **). It is a PATH/OPENS wildcard only — in exec args a "*" is a plain literal character (a process is frequently invoked with a literal "*", e.g. an unexpanded glob). ExecArgsWildcard is the exec-args zero-or-more wildcard: a standalone argv token that absorbs zero or more whole arguments. It is a dedicated sentinel (doubled U+22EF) precisely so it cannot collide with any real argv token — the same collision-avoidance rationale behind DynamicIdentifier. Exec args therefore need no escaping: every other byte, including "*", is literal.

View Source
const (
	OpenDynamicThreshold     = 50
	EndpointDynamicThreshold = 100
)

--- Default collapse thresholds --- OpenDynamicThreshold is the fallback threshold used by AnalyzeOpens when no more-specific CollapseConfig matches the walked path prefix. EndpointDynamicThreshold is the counterpart for AnalyzeEndpoints.

Variables

This section is empty.

Functions

func AnalyzeEndpoints

func AnalyzeEndpoints(endpoints *[]types.HTTPEndpoint, analyzer *PathAnalyzer) []types.HTTPEndpoint

func AnalyzeOpen added in v0.0.118

func AnalyzeOpen(path string, analyzer *PathAnalyzer) (string, error)

func AnalyzeOpens added in v0.0.118

func AnalyzeOpens(opens []types.OpenCalls, analyzer *PathAnalyzer, sbomSet mapset.Set[string]) ([]types.OpenCalls, error)

func AnalyzeURL

func AnalyzeURL(urlString string, analyzer *PathAnalyzer) (string, error)

func CollapseAdjacentDynamicIdentifiers added in v0.0.275

func CollapseAdjacentDynamicIdentifiers(p string) string

CollapseAdjacentDynamicIdentifiers replaces runs of adjacent DynamicIdentifier segments (e.g. "/a/⋯/⋯/b") with a single WildcardIdentifier ("/a/*/b"). Static segments between dynamic identifiers prevent collapsing. String wrapper over the internal byte-level collapseAdjacentDynamic, intended for test coverage.

func CompareDynamic added in v0.0.119

func CompareDynamic(dynamicPath, regularPath string) bool

CompareDynamic checks whether `regularPath` is matched by `dynamicPath`. The dynamic path may contain DynamicIdentifier (⋯, exactly-one-segment wildcard) or WildcardIdentifier (*, zero-or-more-segment mid-path / one-or-more-segment trailing wildcard). The node-agent R0002 rule (Files Access Anomalies) uses this at every file-open to decide whether the access is in-profile.

Anchoring contract:

  • Anchored patterns (start with `/`): `/etc/*` matches files UNDER /etc but NOT the bare `/etc` directory itself, mirroring shell glob semantics. This avoids R0002 silently allowing access to a profiled directory's parent.
  • Unanchored `*` (no leading slash): explicit catch-all that also matches the root path `/`. The only way to whitelist `/` itself is an explicit unanchored `*`.

Trailing-slash insensitivity: `/etc/` is treated as `/etc`, and `/etc/passwd/` as `/etc/passwd`. Trailing empty path components from `strings.Split` are trimmed so `len(regular) > 0` correctly reflects the presence of a real path tail when matching trailing `*`.

The empty regular path (`""`) is treated as "no path" and matches nothing — distinct from the root path `/`, which matches unanchored `*` per the contract above.

func CompareExecArgs added in v0.0.278

func CompareExecArgs(profileArgs, runtimeArgs []string) bool

CompareExecArgs reports whether runtimeArgs matches profileArgs, treating an empty profileArgs as "no constraint" (matches anything). Non-empty vectors are matched anchored at both ends by matchExecArgsStrict.

Use MatchExecArgs to express "argv must be empty"; CompareExecArgs is kept for callers that have not migrated to the ArgsRequired-aware API.

func MatchExecArgs added in v0.0.278

func MatchExecArgs(profileArgs []string, argsRequired bool, runtimeArgs []string) bool

MatchExecArgs reports whether runtimeArgs satisfies a profile entry's argv contract. argsRequired carries the entry's ExecCalls.ArgsRequired flag:

false → no constraint; matches any runtimeArgs.
true  → strict anchored match against profileArgs (empty profileArgs
        matches only an empty runtimeArgs).

The flag exists because v1beta1.ExecCalls.Args is `json:",omitempty"`: an explicit `args: []` round-trips back as nil, so the stored vector alone cannot distinguish "no constraint" from "must have no args".

func MergeDuplicateEndpoints

func MergeDuplicateEndpoints(endpoints []*types.HTTPEndpoint) []*types.HTTPEndpoint

MergeDuplicateEndpoints folds duplicates and merges same-path specific-port endpoints into a wildcard-port (:0) sibling. Folding is symmetric and is keyed on the same triple HTTPEndpoint.Equal compares — (Endpoint, Direction, Internal). An Internal=false endpoint will therefore NOT merge with an Internal=true sibling even if their path and direction match.

  • If a specific-port endpoint is encountered AFTER its :0 sibling, the specific-port methods/headers are merged INTO the wildcard entry.
  • If a specific-port endpoint is encountered BEFORE its :0 sibling, it is initially recorded; when the wildcard arrives we sweep `seen` for same-(path, direction, Internal) specific-port siblings, fold them into the wildcard, and remove them from the output.

This contract was tightened on the back of upstream review on kubescape/storage#316 — a single :0 entry must NOT cause unrelated concrete-port endpoints to be wildcarded; only same-path same-Internal siblings fold.

func MergeStrings added in v0.0.118

func MergeStrings(existing, new []string) []string

func ProcessEndpoint

func ProcessEndpoint(endpoint *types.HTTPEndpoint, analyzer *PathAnalyzer, newEndpoints []*types.HTTPEndpoint) (*types.HTTPEndpoint, error)

Types

type CollapseConfig added in v0.0.275

type CollapseConfig struct {
	Prefix    string
	Threshold int
}

--- Collapse configuration --- CollapseConfig controls the threshold at which children of a trie node (under the given path Prefix) are collapsed into a dynamic node (⋯). Longest-prefix wins at analysis time.

func DefaultCollapseConfig added in v0.0.275

func DefaultCollapseConfig() CollapseConfig

DefaultCollapseConfig returns a value copy of the package-private fallback. Mutating the returned struct does not affect package state. The accessor pattern matches DefaultCollapseConfigs() — both protect the threshold-tuning surface from accidental cross-test or cross-caller corruption.

func DefaultCollapseConfigs added in v0.0.275

func DefaultCollapseConfigs() []CollapseConfig

DefaultCollapseConfigs returns a defensive copy of the package-level default per-prefix collapse thresholds. Callers that mutate the result will not affect the package state or other callers.

type PathAnalyzer

type PathAnalyzer struct {
	RootNodes map[string]*SegmentNode
	// contains filtered or unexported fields
}

func NewPathAnalyzer

func NewPathAnalyzer(threshold int) *PathAnalyzer

NewPathAnalyzer builds an analyzer with a single global collapse threshold and no per-prefix overrides — equivalent behaviour to the pre-CollapseConfig world. Retained so existing callers don't need to change.

func NewPathAnalyzerWithConfigs added in v0.0.275

func NewPathAnalyzerWithConfigs(defaultThreshold int, configs []CollapseConfig) *PathAnalyzer

NewPathAnalyzerWithConfigs builds an analyzer whose collapse threshold can vary per path prefix. defaultThreshold applies when no CollapseConfig in configs matches; configs are checked longest-prefix-wins at walk time.

configs is copied so the caller can reuse or mutate the slice without affecting the analyzer.

func (*PathAnalyzer) AnalyzePath

func (ua *PathAnalyzer) AnalyzePath(p, identifier string) (string, error)

func (*PathAnalyzer) FindConfigForPath added in v0.0.275

func (ua *PathAnalyzer) FindConfigForPath(path string) CollapseConfig

FindConfigForPath returns a value copy of the CollapseConfig whose Prefix matches `path` with the longest match. Falls back to the analyzer's default config (Prefix:"/") when no per-prefix override applies, so the result is always meaningful — there is no "no match" signal.

Returning by value keeps the analyzer's internal state immutable from callers. NewPathAnalyzerWithConfigs already makes a defensive inbound copy of `configs`; this is its outbound twin. Without it, `cfg := analyzer.FindConfigForPath(p); cfg.Threshold = 1` would silently mutate the analyzer's threshold map for every future call.

type SegmentNode

type SegmentNode struct {
	SegmentName string
	Count       int
	Children    map[string]*SegmentNode
}

func (*SegmentNode) IsNextDynamic

func (sn *SegmentNode) IsNextDynamic() bool

Jump to

Keyboard shortcuts

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