You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
sec(api): RI-exchange approve/reject distinguish a missing record (404) from an existing one (403 wrong token) for unauthenticated callers #601
Found while reconciling the RI-exchange approve spec (#600). Observed through HandleRequest with a pending record that has a hashed token: an unauthenticated caller sending a token gets 403 'invalid approval token' (approve) / 'invalid rejection token' (reject) for an existing record and 404 'exchange record not found' for a missing one. Without a token: approve answers 403 'CSRF validation failed' for both existing and missing ids (no oracle), reject answers 400 'rejection token is required' for both. The purchase routes closed the same class in #435/#584/#589/#594 by answering 401 before the lookup. UUIDs are hard to guess, so exposure is small, same class as #435 and #597.
Acceptance: decide whether RI-exchange approve/reject should return one status and body for 'missing' and 'wrong token' to unauthenticated callers (and whether a 401 before the lookup is the right shape here, since these token routes currently never answer 401), implement with a regression test through HandleRequest comparing missing vs existing for no-session callers with a wrong token, and update openapi.yaml. Related: #435, #597, #600.
Decision (IAmJSD, acting owner, 2026-10-26): the emailed-token actions (approve, cancel, revoke, RI exchange approve/reject) all use one mapping:
403 for a wrong or invalid token;
410 for an expired link whose token matches;
409 when the action loses a race (someone else already approved, rejected or cancelled it);
a missing RI exchange answers like a wrong token (403), not 404, 500 or 401. The emailed token alone authorizes these routes, so they cannot ask for a login first.
This keeps the codes approve and cancel already return (the frontend already shows 410 as "link expired"). It is implemented by #1172 (revoke and RI exchange use 403/410/409) and #1175 (a missing exchange answers like a wrong token, for #601). Neither is merged yet; they go through the normal review and merge path. The remaining session-path leak cristim flagged on #1175 is tracked in #1428.
Posted by IAmJSD's agent at IAmJSD's request (acting owner while the maintainers are away).
Activity
IAmJSD commentedon Oct 20, 2026
Claiming: working on this
IAmJSD commentedon Oct 26, 2026
Decision (IAmJSD, acting owner, 2026-10-26): the emailed-token actions (approve, cancel, revoke, RI exchange approve/reject) all use one mapping:
This keeps the codes approve and cancel already return (the frontend already shows 410 as "link expired"). It is implemented by #1172 (revoke and RI exchange use 403/410/409) and #1175 (a missing exchange answers like a wrong token, for #601). Neither is merged yet; they go through the normal review and merge path. The remaining session-path leak cristim flagged on #1175 is tracked in #1428.
Posted by IAmJSD's agent at IAmJSD's request (acting owner while the maintainers are away).
Merge branch 'fix/issue-587' into fix/issue-601