Skip to content

gate-48 csrf-cochange matches a REMOVED COMMENT — nldesign is red for a docblock that only names the attribute #191

Description

@rubenvdlinde

What happened

gate-48 csrf-cochange is red on nldesign (development vs origin/beta, hydra-gates @main). Nothing about CSRF changed in that diff. The gate matched a removed line of prose inside a class docblock:

- * (#[PublicPage] + #[NoCSRFRequired]) and the response contract are owned by

That line is part of a docblock rewrite describing where the auth posture is owned. No attribute and no annotation was removed; the surrounding diff replaces one explanatory paragraph with another.

Why

The detector matches the token anywhere on any removed line:

_csrf_removed=$(git diff -U0 "${BASE_REF}...HEAD" -- 'lib/Controller/*.php' 2>/dev/null \
    | grep -E '^-.*(@NoCSRFRequired|#\[NoCSRFRequired\])' || true)

^-.* puts no constraint on code position, so a comment that names the attribute is indistinguishable from an attribute that was deleted.

This is the same defect class as #184 (gate-64 grepped a quoted string literal, so it matched comments and missed constants). A checker that greps a token rather than a code position fails in both directions.

Why this one is especially bad to leave

The fleet is currently being driven to green. The cheapest way to make this finding disappear is to reword a comment — which changes nothing about CSRF and teaches exactly the habit the gate exists to prevent. A gate that can be satisfied by editing prose is worse than no gate, because it manufactures the appearance of a security review.

Suggested fix

Require the token in a code position rather than anywhere on the line:

  • attribute form: after - and optional whitespace the content starts with #[, and the attribute list contains NoCSRFRequired;
  • legacy docblock form: after -, optional whitespace and an optional leading *, the content starts with @NoCSRFRequired.

The nldesign line fails both (its #[NoCSRFRequired] sits mid-sentence after (), while a genuine deletion of either form still matches.

Mutation check to include

The fixture needs both arms, or the fix is unfalsifiable:

  1. must stay green — a diff that only removes a comment line mentioning #[NoCSRFRequired] in prose (the nldesign line verbatim).
  2. must go red — a diff that removes a real #[NoCSRFRequired] attribute line with no frontend CSRF signal, and separately one that removes a real * @NoCSRFRequired docblock tag.

Arm 2 is the one that proves the fix did not simply disable the gate.

Measured on

hydra-gates @main (3438839), --app-dir nldesign --base origin/beta, scope 3118 files. nldesign is the only repo of the eight I surveyed where gate-48 fires at all, and its single finding is this false positive.

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