fix(security): restrict doggy-countdown route hostname - #2866
Conversation
…propose-fix-for-tenant-hostname-vulnerability-bgwbhh # Conflicts: # k8s/bases/infrastructure/cluster-policies/kustomization.yaml
Picked this up as a long-idle actionable PR (last push 2026-08-01, ~14 days; no active-work signal on Conflict — one file, resolved as a union. Taking either side alone would have been wrong, and the incoming side is the dangerous one to drop: Verified: both referenced policy files exist, no conflict markers remain, the policy base builds No behaviour on this branch changed — the merge only integrates |
✅
|
CI now runs 33 checks instead of 5, and one fails. Root-caused — the 36 "unresolved Flux Bringing the branch up to date widened the changed-path set, so The actual error is one line: Why this PR moves it. Confirmed it is this PR and not What is needed — and why I have not just pasted the new hash. That constant's own comment sets the So this is the remaining blocker, and it is a single well-scoped step: run that membership diff, and if Separately: the DIRTY merge state is cleared (see the previous comment) and every other check is |
The added Kyverno ClusterPolicy enters the fingerprinted authorization surface as an indirect authorization policy, so the aggregate value moved. Measured against main 44f14fa: 524 -> 525 documents, membership differing by exactly the one added ClusterPolicy, zero removed or renamed, and the remaining 524 byte-identical (negative control fired). The policy is a validate.deny rule that can only refuse admission; it creates no identity, binding, role, or policy document.
The new Kyverno Membership — measured against main Zero removed, zero renamed. After removing just that entry the remaining 524 documents are byte-identical to main's render — checked with a negative control that fired on a one-line perturbation, so the identical result is not vacuous. Nothing added, removed or renamed touches a Role, ClusterRole, RoleBinding, ClusterRoleBinding, ServiceAccount or IAM document. Direction of the change — the added policy is a single Corroboration — two independent renderers agree on the value: the required CI job on the approved toolchain, and a local render on kubectl v1.36.1 with the same embedded kustomize v5.8.1. Agreement across a kubectl patch difference is what rules out a renderer-version artifact. One trap recorded in the code comment while verifying this: Ablation on the approved constant: flipping one hex digit fails the test; restoring it passes. |
Code Coverage OverviewLanguages: Go Go / code-coverage/goThe overall coverage in commit 2991e54 in the Show a code coverage summary of the most covered files.
|
@coderabbitai review |
|
|
|
Warning Review limit reached
Next review available in: 54 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Repository YAML (base), Organization UI (inherited) Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (5)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Design collision with #2740 — flagging rather than acting, since both approaches are defensible and #2740 was opened to close the same class of gap and carried an open [P1] asking for the boundary to That overlaps this PR, which adds a separate One concrete incompatibility, worth checking either way. This PR allows Suggestion, not a decision: consolidate on the single generalised policy and close this PR, since I have not closed anything here — the gap this PR fixes is real until #2740 merges, and picking |

Motivation
doggy-countdowntenant from claiming arbitrary hostnames on the shared platform Gateway, which combined withexternal-dnscould publish attacker-controlled names in the platform zone.Description
restrict-doggy-countdown-hostnamesthat enforcesHTTPRouteobjects in namespacedoggy-countdownto declare exactly one hostname:simba.${domain}, and denies hostname-less, mixed, or other hostnames.k8s/bases/infrastructure/cluster-policies/kustomization.yamlso it is applied with the platform cluster policies.tests/restrict-doggy-countdown-hostnames/includingresources.yaml(good and exploit variants) andkyverno-test.yamlto assert the intended hostname is allowed while exploit variants are rejected.Testing
python3 scripts/validate-naming.pywhich passed and reported naming conventions satisfied.python3 scripts/validate-embedded-json.pywhich parsed embedded JSON blobs cleanly.kyverno test ./tests, Kyverno v1.18.2) which executed the new fixtures plus existing ones and reported all tests passed (17 tests).ksail workload validatecould not be executed in the environment because KSail is not installed, so KSail-backed static validation was not run.Codex Task