require_role implements a threshold but reads as set membership #71
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Severity: LOW (latent trap, not currently exploitable)
The bug
backend/app/auth/session.py:65-73computes:It takes the minimum of the supplied roles and treats the hierarchy as monotonic. So
require_role(UserRole.reviewer, UserRole.admin)is exactly equivalent torequire_role(UserRole.reviewer).Every current call site happens to be monotonic, so nothing is broken today. But the variadic
signature reads like a set-membership test while implementing a threshold. A future call such
as
require_role(UserRole.viewer, UserRole.admin)— intending "viewers or admins, but notreviewers" — would silently admit reviewers.
Why it matters
#22 will expand the role model, which is exactly when this misfires, and there are no
authorization tests to catch it.
Fix
Rename to
require_min_role(role)taking a single role, making the threshold semanticsexplicit — or implement true set membership if that is the intent. Update all call sites.
Done when
References
backend/app/auth/session.py:65-73Fixed in
4333b5e. CI green.Replaced with
require_min_role(minimum)taking a single role, and all 14 call sites migrated.ROLE_ORDERis now a module-level constant rather than rebuilt inside the check on every request.Tested across the full 3x3 role matrix (viewer/reviewer/admin against each threshold), so the
semantics are pinned rather than assumed. The specific case that would have misfired —
require_role(viewer, admin)silently admitting reviewers — is now unrepresentable, because thesignature no longer accepts a set.