Skip to content

fix(kubescape-bridge): a fingerprint collision with a previously filed theme silently adopts its issue #2934

Description

@devantler

🤖 Generated by the Agentic Engineer

Evidence

Raised as a P2 by Codex review on #2917 (scripts/kubescape-backlog-bridge/issues.go:687) and
confirmed by reading the code. It is a genuinely different path from the same-run collision
already guarded by errCollidingThemes, which is why the existing guard does not cover it.

planWrites builds claimedBy from the themes present in the current derivation, so it catches
two themes colliding within one run. The lookup byFingerprint[fp] then trusts the fingerprint
alone to identify a tracked issue. A theme filed by an earlier run is not in claimedBy, so a
later theme whose fingerprint collides with it is treated as that same theme and adopts its issue —
updating or reopening it under a different identity, with no errCollidingThemes raised.

Problem

The fingerprint is 64-bit, so a colliding pair is findable in roughly 2^32 trials. Someone able to
influence scanner input can file one key, then supply only the colliding key on a later run, and the
bridge silently rewrites the first issue's content and state under the second key. The audit history
of a security backlog entry is corrupted, and nothing reports an anomaly — the run looks entirely
successful.

Impact is bounded: it needs influence over scanner input and offline collision search, and it
corrupts tracking rather than granting access. It is filed as its own slice rather than fixed inline
because both viable fixes carry a data migration (below), which does not belong in the delivery PR
that surfaced it.

Why this is not a small fix

The tracked entry does not currently retain enough identity to verify a match:

  • **Surface:** is recoverable from the body (entrySurface parses it back), so a
    posture-vs-CVE collision is detectable cheaply.
  • The Key is only present in the issue title, which renderTitle truncates and digests once it
    exceeds GitHub's limit — so it is not reliably recoverable.

A Surface-only check would therefore close cross-surface collisions while leaving same-surface ones
open, and would read as complete while being partial. That is the worse outcome: a guard that looks
like it verifies identity but does not.

Options

  1. Retain theme identity in the entry — add an explicit identity marker to the rendered body
    alongside the existing fingerprint marker, and compare it before adopting a tracked issue.
    Existing issues predate the marker, so it needs an absent-marker path that does not re-file
    everything as duplicates.
  2. Widen the fingerprint to a collision-resistant length. Simpler to reason about, but it changes
    every existing marker, so without a migration every tracked issue is re-created as a duplicate —
    exactly the duplicate storm the listing budget exists to prevent.

Either way the migration is the substance of the work, not the comparison.

Acceptance criteria

  • A theme whose fingerprint collides with a previously filed entry of a different identity is
    refused rather than adopting that entry, and the refusal names both identities.
  • Already-filed issues carrying the current marker format keep working — no mass re-creation, proven
    by a test over entries written in the old format.
  • The guard is pinned by a test that fails when the identity comparison is removed (ablation, not
    just a passing assertion).

Rough size

Small-to-medium: the comparison is a few lines; the migration path and its tests are the bulk.

Activity

  1. coderabbitai commented on Aug 3, 2026

    @coderabbitai
    Contributor
    🔗 Related PRs

    #2404 - fix: tenant artifact verification rejects the dual signing identities from #2399 [merged]
    #2635 - fix(deploy): reboot stale nodes so containerd adopts refreshed GHCR auth [merged]
    #2821 - security: pin the tenant RGD cosign subject to actions and a fixed ref [merged]
    #2830 - feat(ci): publish Kubescape posture findings to Code Scanning [merged]
    #2876 - feat(security): derive themed, deduped backlog entries from live Kubescape findings [merged]


    📝 Issue Planner

    Check the box below or use the @coderabbitai plan command to generate an implementation plan and prompts that you can use with your favorite coding assistant.

    • Create Plan

    🧪 Issue enrichment is currently in open beta.

    You can configure auto-planning by selecting labels in the issue_enrichment configuration.

    To disable automatic issue enrichment, add the following to your .coderabbit.yaml:

    issue_enrichment:
      auto_enrich:
        enabled: false

    💬 Have feedback or questions? Drop into our discord!

  2. moved this to 📥 Backlog in 🌊 Project Boardon Aug 3, 2026
  3. self-assigned this
    on Aug 20, 2026
  4. added a commit that references this issue on Aug 20, 2026
  5. moved this from 📥 Backlog to 👀 In Review in 🌊 Project Boardon Aug 20, 2026
  6. moved this from 👀 In Review to ✅ Done in 🌊 Project Boardon Aug 21, 2026
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

Fields

No fields configured for Security.

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions