Repository navigation
fix: preserve failing-container identity when applying exceptions - #199
Conversation
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars.
|
Result.SetExceptions matched containerName exceptions through GetResourceExceptions, which has no failing-container context and accepts the exception when any container in the workload has the excepted name. An exception for a benign sidecar therefore passed a finding raised for another container in the same pod. - Add GetResourceExceptionsForPaths and use it from ResourceAssociatedRule.setExceptions with every path recorded on the rule (failed, delete, review and fix paths). - When the failing containers are known, require the exception to cover all of them, so it cannot hide a container it does not name. - Decode ephemeral container names through JSON so typed slices resolve. Fixes kubescape#198 Signed-off-by: Karman Singh Talwar <flyingoffkarmansinghtalwar@gmail.com>
58d53d6 to
0507c65
Compare
matthyx
left a comment
There was a problem hiding this comment.
Approving at head 0507c65 (base main).
Need: Confirmed (#198). Result.SetExceptions used the workload-wide GetResourceExceptions, so a containerName exception for sidecar hid a failure on app. The precise matching from #169/#196 only ran in SetRuleResponsExceptions. Same class of bug that matthyx flagged in #169 review.
Soundness: The new GetResourceExceptionsForPaths reuses extractFailingContainerNames over failed/delete/review/fix paths. The "all failing containers must match" rule is conservative (errs toward reporting). Paths without a container index keep the old fallback. The typed-slice JSON decode for ephemeral containers is correct and consistent with GetContainers. No public API breakage. No duplicate or superseded PRs found (searched open/closed/merged PRs and issues; #169/#196 are prior related merges, not rejections).
Validation: I checked out the head and ran go build ./... and go test ./exceptions/ ./reporthandling/..., all ok. With the three source files reverted to main, the three new tests fail (TestSetExceptionsContainerNamePrecision, ...everyFailingNameMustMatch, TestEphemeralContainerNames_typedSlice), so they are real regression tests. CI at this head: build, DCO and GitGuardian pass (CodeRabbit skipped). I did not repeat the author's end-to-end kubescape runs.
Blockers: none. Nonblocking: the author plans a kubescape-side integration test after the bump, and no further tracking is needed. Two separate exceptions (one for app, one for sidecar) deliberately do not combine; this is documented in the PR.
Overview
Fixes #198.
Result.SetExceptionsapplies exceptions throughResourceAssociatedRule.setExceptions, and that function calledGetResourceExceptions.GetResourceExceptionshas no failing-container context, so acontainerNameexception matched whenever any container in the workload had that name. On a pod with a privilegedappand a plainsidecar, an exception forsidecartherefore passed C-0057. Kubescape applies exceptions only through this path, so the precise matching inSetRuleResponsExceptions(#169, #196) was never used during a scan.Changes:
exceptions.GetResourceExceptionsForPaths, a new exported function. It isGetResourceExceptionswith the failing containers resolved from the given paths by the existingextractFailingContainerNames.GetResourceExceptionsis unchanged.ResourceAssociatedRule.setExceptionspasses every path recorded on the rule to the new function:failedPath,deletePath,reviewPathandfixPath.path. Kubescape stores rule paths as delete, review and fix paths and leavesfailedPathempty, so reading onlyfailedPathwould still fall back to the workload-wide check.compareContainerName: when the failing containers are known, the exception must cover all of them. A rule result carries one status per resource, so an exception that names only some of the failing containers cannot pass the whole rule without hiding the others. A regex such asapp|sidecarstill covers several containers on purpose.ephemeralContainerNamesdecodes the list through JSON, asGetContainersalready does. Kubescape writes ephemeral containers back as a typed[]corev1.EphemeralContainerafter stripping env data. The old[]interface{}assertion returned nothing for that slice, so an exception naming an ephemeral container never matched.Behaviour that is unchanged:
containerName.alertOnlysemantics.SetRuleResponsExceptionsfor a single failing container.spec.hostNetwork. These still use the workload-wide fallback.How to Test
New tests:
TestSetExceptionsContainerNamePrecision(reporthandling/results/v1/resourcesresults) drivesResult.SetExceptionson a pod withsetup(init),app,sidecaranddebugger(ephemeral). It covers:containerName;app|sidecarregex;alertOnly;TestComparator_compareContainerName_everyFailingNameMustMatchandTestEphemeralContainerNames_typedSlice(exceptions).Before the fix, on
mainat142c5dd:After the fix, every subtest above passes:
go build ./...andgo test -race ./...pass, with all 18 packagesok.staticcheckreports nothing on the two changed packages, the same as onmain.End to end: I built kubescape master
90cbf064with a localreplacepointing at this branch and reran the scans from #198 (kubescape scan control C-0057 <pod> --severity-threshold high --format json --exceptions <file>):containerNameapp+sidecarsidecarapp+sidecarappapp+sidecarghostsidecarapp|sidecarsetupappsetupsetupdebuggerappdebuggerdebuggerapp+sidecar, DeploymentsidecarAlso with the patched build:
go test ./core/pkg/opaprocessor/ ./core/pkg/resultshandling/...passes.spec.hostNetwork, no container path) with asidecarexception still returnspassed, the same as before.Compatibility
GetResourceExceptionskeeps its signature and behaviour.SetRuleResponsExceptionsnow also needs every failing container to be covered. Its single-container tests are unchanged.appand one forsidecar, do not combine to cover a finding on both containers. A single exception has to name both, for example withapp|sidecar. This errs toward reporting the finding.After a release, kubescape needs an opa-utils bump to pick this up. I'll follow up there with an integration test through
updateResults.