Skip to content

fix(kubescape): refuse exception patterns the bridge's matchability check cannot decide #4086

Closed

Description

@devantler

🤖 Generated by the Agentic Engineer (interactive Claude Code session)

Follow-up to the #2910 decision.

Evidence

The Kubescape backlog bridge rejects an exception pattern that can never match a non-empty value, because such a pattern counts as an applied exception while suppressing nothing (canMatchNonEmpty / analyse in scripts/kubescape-backlog-bridge/exceptions.go). On main at 140db93, the check misses patterns that can never match but use one of three constructs.

RED, each wrapped as the bridge wraps it (^(?:…)$):

Pattern Check says Actually
a\bb can match never matches
(?m)a^b can match never matches
(?:a$|b$)c can match never matches
c(?:^a|^b) can match never matches
(?:a$)+b can match never matches

The three constructs are:

  • \b / \B word boundaries
  • (?m) line anchors
  • a ^ or $ inside an alternative or a repetition, next to text that consumes input

Outside those constructs the check is exact. A differential test compared it with brute-force matching on 4,000 random patterns built from literals, character classes, ., * + ?, alternation, grouping, and ^/$ at the ends. It found 0 false rejections and 0 missed cases.

The real artifact (22 policies, 322 patterns) uses none of the three constructs. It holds:

  • 302 plain anchored literals
  • 9 bare .*
  • 11 using real regex: character classes with +, alternations of names, and one large "not in this list" pattern

Expected behaviour

Loading the exceptions artifact fails, naming the pattern and the construct, when a pattern uses one of the three constructs. Everything the bridge accepts is then decided exactly.

Acceptance criteria

  • A pattern containing \b, \B, a multi-line ((?m)) anchor, or a ^/$ that is not at the start or end of the pattern (or of one of its top-level alternatives) is refused with an error that names the construct.
  • RED/GREEN: each pattern in the table above is refused. ^a$|^b$, ^(kube-system|velero)$, the four ^crossplane:provider:…-[0-9a-f]+:system$ shapes, .* and the long "not in this list" pattern are all still accepted.
  • A differential test (random patterns from the accepted constructs, checked against brute-force matching) guards the check's exactness.
  • The comment on canMatchNonEmpty states the accepted constructs and that the check is exact for them.
  • The generated artifact on main still loads unchanged.

Size: S.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Fields

Priority

None yet

Effort

None yet

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions