fix: clone RouteBaseDirectives before per-policy append (#246)#249
Merged
Conversation
getCorazaDirectivesForTrafficProtectionPolicy seeded its per-policy directive list by aliasing the operator's shared RouteBaseDirectives slice, then appended to it. When the shared slice had spare capacity (cap > len), the append wrote into the shared backing array, leaking per-policy directives (SecRuleEngine mode, score thresholds, rule removals) into the base seen by other policies. Clone the base slice before appending, matching the safe precedent in internal/extensionserver/cache/index.go. Latent today: the builder is reached only under IsEPPEmissionEnabled(), off by default. Fixes #246
Add TestGetCorazaDirectivesDoesNotAliasRouteBaseDirectives: seed the shared base slice with spare capacity, build an Enforce policy, then build a second Observe policy and assert the first's SecRuleEngine token was not overwritten. Fails on the aliased code, passes with the slices.Clone fix.
scotwells
approved these changes
Jul 10, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
getCorazaDirectivesForTrafficProtectionPolicyseeded its per-policy directive list by aliasing the sharedRouteBaseDirectivesslice, thenappended to it. With spare capacity (cap > len) the append writes into the shared backing array — per-policy directives leak into the base seen by other policies.Fix
Defensive copy before appending, matching the existing safe precedent at
internal/extensionserver/cache/index.go:248(make+copy).Impact
Latent/dormant today — the builder is reached only under
IsEPPEmissionEnabled(), off by default (Coraza injected via the extension server'sPostTranslateModify, not EnvoyPatchPolicies). Fixes the corruption pre-emptively so enabling EPP emission doesn't ship a cross-policy config bug:SecRuleEngine On/DetectionOnly/Off, score thresholds, and rule removals could bleed across policies (order- and capacity-dependent).Tests
TestGetCorazaDirectivesDoesNotAliasRouteBaseDirectives— seeds the shared base slice with spare capacity, builds an Enforce policy, then builds a second Observe policy and asserts the first'sSecRuleEngine Onwas not overwritten toDetectionOnly.Confirmed to fail on the aliased code (the leak reproduces exactly) and pass with
slices.Clone:Verification
go build ./internal/controller/...— cleango vet ./internal/controller/...— cleango test ./internal/controller/ -run TestGetCorazaDirectives— okFixes #246. Related: #242.