Skip to content

security(spp_change_request_v2): free diff-padding evades duplicate detection once #264 and #343 both land [Severity: Low-Medium] #346

Description

@gonzalesedwin1123

Follow-up from the cross-PR interaction analysis of the open security PRs (2026-07-24). This gap does not exist in either PR alone at this cost — it is created by the combination of #264 and #343, so it becomes real the moment both merge.

Finding

Combined effect: a user duplicating a pending CR (same registrant, same selected field, same proposed value) can add one throwaway edit to any other mapped detail field. The changed-field sets now differ → similarity scores 0.0 → duplicate detection is bypassed. Thanks to #264, the padding field is never applied, so the padding is free and side-effect-less.

Under #343 alone this padding had a real cost (the padded field would actually be written on apply). #264 removes that cost. Conflict detection is not evadable the same way — padding only grows proposed ∩ conflict_fields — this affects the duplicate-similarity path only.

Severity: Low-Medium

Requires an authenticated CR user editing their own draft CR. Duplicate detection is a warn-level control (it flags rather than blocks), so the impact is suppression of a reviewer warning, not direct approval bypass. Still, it is exactly the class of steering #343 set out to close.

Suggested fix

Score similarity on the intersection of the two changed-field sets (or on selected ∩ diff), rather than exact set equality — padding then cannot zero the score. Alternatively (or additionally), hardening the writability of detail fields post-creation would remove the free padding vector.

Best coordinated with #344, which covers the sibling sink (dynamic-approval routing) of the same "user-steerable inputs to detection/routing" root cause.

Source: internal/plans/security-prs-interaction-analysis.md (CR cluster review, 264×343). Related: #343, #264, #344.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions