Skip to content

Security fast-follow: SIWA review findings R1-R3#57

Merged
testtest126 merged 1 commit into
mainfrom
fix/siwa-review-findings
Jul 10, 2026
Merged

Security fast-follow: SIWA review findings R1-R3#57
testtest126 merged 1 commit into
mainfrom
fix/siwa-review-findings

Conversation

@testtest126

Copy link
Copy Markdown
Owner

Summary

PR #50 merged at afe32d2 before the rule-5 review's three required fixes could land on its branch, so main briefly carries them — this is the immediate fast-follow. ~20 lines of product code, exactly the reviewer's scope:

  • R1 (link overwrite / account takeover): resolveAppleUser now refuses to rebind an already-linked account to a different Apple ID (409 Conflict); re-presenting the same subject stays idempotent. Test proves the original binding survives a rebind attempt and still recovers the account.
  • R2 (bearer conflation): an Authorization header that fails verification now 401s instead of being treated as anonymous — an expired bearer can no longer silently demote a linking request into a fresh account bound to the user's Apple ID.
  • R3 (regression test for the founding incident): a well-formed JWT signed with the server's own HMAC key is asserted to be rejected by the live Apple verifier — the forgery class the original implementation accepted.

Non-blocking reviewer notes (nonce replay hardening, first-link race) are deliberately excluded per the orchestrator — tracked separately.

Test plan

  • Server suite 22/22 — including the three new tests (rebind → 409 with binding intact, invalid bearer → 401 with nothing created, own-key forgery → 401 on the live path)

🤖 Generated with Claude Code

…test

Addresses the three required findings from the rule-5 security review of
PR #50, which merged before this delta could land on its branch:

R1: the link path could rebind an already-linked account to a different
Apple ID — a stolen bearer would lock the real owner's Apple sign-in
out of recovery. Linking now requires the account to be unlinked (or
already linked to the same subject) and returns 409 otherwise.

R2: a presented-but-invalid bearer was treated as anonymous, silently
turning a guest's linking attempt into a fresh account permanently
bound to their Apple ID. An Authorization header that fails
verification now 401s; only a truly absent header proceeds anonymously.

R3: regression test for the founding incident — a well-formed JWT
signed with the server's own HMAC key must be rejected by the live
Apple verifier (the original implementation accepted exactly this).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
@testtest126 testtest126 merged commit 58ad316 into main Jul 10, 2026
3 of 5 checks passed
@testtest126 testtest126 deleted the fix/siwa-review-findings branch July 10, 2026 03:46
testtest126 added a commit that referenced this pull request Jul 10, 2026
Rule 4 rewritten: only the authoring session (or orchestrator on request)
merges; blocking verdicts and unresolved review threads must be checked
before merging. Rule 5 hardened: security PRs stay in draft until an
explicit 'Security review: APPROVE @ <head>' comment from a second
session, with BLOCKs posted as line-level review comments so branch
protection's conversation-resolution requirement gates the merge
mechanically. Adds the #28 deployment gate on open security issues and
releases the main-checkout single-writer hold.

Prompted by PR #50 and PR #57 both merging past a pending security
review; branch protection (green checks + conversation resolution,
admins included) is now active on main.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
testtest126 added a commit that referenced this pull request Jul 10, 2026
Bring the String Catalog branch up to date with time controls (#54),
rematch decline (#55/#65), Sign in with Apple (#57), and the online
resume banner (#66). Newly added user-facing strings are localized in
follow-up commits and re-extracted into the catalog.
@testtest126

Copy link
Copy Markdown
Owner Author

Security review: APPROVE @ 58ad316

Full findings and runtime evidence: #56 (comment) (verdict comment on #56, which is closed). Summary: R1 rebind guard (409, idempotent same-subject relink allowed, original binding survives attempted takeover), R2 strict bearer handling (present-but-invalid → 401 before account resolution), R3 incident-class forgery regression test (own-HMAC-signed well-formed JWT rejected via the live verifier path) — all verified in code and observed passing at this head. Non-blocking hardening remains tracked in #53.

🤖 Generated with Claude Code

testtest126 added a commit that referenced this pull request Jul 10, 2026
…te (#58)

Rule 4 rewritten: only the authoring session (or orchestrator on request)
merges; blocking verdicts and unresolved review threads must be checked
before merging. Rule 5 hardened: security PRs stay in draft until an
explicit 'Security review: APPROVE @ <head>' comment from a second
session, with BLOCKs posted as line-level review comments so branch
protection's conversation-resolution requirement gates the merge
mechanically. Adds the #28 deployment gate on open security issues and
releases the main-checkout single-writer hold.

Prompted by PR #50 and PR #57 both merging past a pending security
review; branch protection (green checks + conversation resolution,
admins included) is now active on main.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant