Fix nil pointer panic in FinishRegistration when FindByID fails#48
Conversation
Agent-Logs-Url: https://github.com/amalgamated-tools/goauth/sessions/0971177f-1cdf-43f9-aa86-f9b4f7e68501 Co-authored-by: veverkap <22348+veverkap@users.noreply.github.com>
veverkananobot
left a comment
There was a problem hiding this comment.
✅ APPROVED
Critical bug fix: prevents nil pointer panic in FinishRegistration on database errors.
The Bug
FinishRegistration was silently discarding the error from Users.FindByID:
// Before (BUG)
user, _ := h.Users.FindByID(r.Context(), userID)On any transient DB failure, this passes nil into passkeyUser{user: user, ...}, whose methods then dereference u.user.ID, u.user.Email, etc. → guaranteed panic.
The Fix
Error is now properly propagated:
// After (correct)
user, err := h.Users.FindByID(r.Context(), userID)
if err != nil {
writeError(r.Context(), w, http.StatusInternalServerError, "failed to fetch user")
return
}Consistency Verification
✅ Matches BeginRegistration — same function handles FindByID errors identically (error → HTTP 500)
✅ Consistent with codebase — all other FindByID calls in passkey.go already propagate errors correctly
✅ Error message — matches pattern: "failed to fetch user"
✅ HTTP status — HTTP 500 is correct for transient DB failures
Test Coverage
✅ New test TestPasskey_finishRegistration_findByIDError:
- Mocks
FindByIDto return error ("db unavailable") - Verifies HTTP 500 response
- Proper WebAuthn config + challenge setup to reach the error path
Impact Assessment
✅ Severity: High (prevents crashes on DB errors)
✅ Risk: Low (straightforward error propagation, consistent with existing patterns)
✅ Scope: Minimal (single error path)
✅ No breaking changes: Error path was previously panic → now returns 500 (correct)
CI Status
✅ Analyze (actions, go) — SUCCESS
✅ CodeQL — SUCCESS
⏳ Go Tests, Greptile Review — in progress
Recommendation: Merge. This is a solid, minimal fix for a real crash bug.
There was a problem hiding this comment.
Pull request overview
Fixes a runtime panic in the passkey registration flow by correctly handling Users.FindByID failures in FinishRegistration, and adds a regression test to ensure the error path returns an HTTP 500.
Changes:
- Propagate
Users.FindByIDerrors inPasskeyHandler.FinishRegistrationand return HTTP 500 instead of proceeding with a nil user. - Add a unit test covering the
FindByIDerror case forFinishRegistration.
Show a summary per file
| File | Description |
|---|---|
handler/passkey.go |
Adds error handling around Users.FindByID in FinishRegistration to prevent nil dereference/panic. |
handler/passkey_test.go |
Adds a regression test asserting HTTP 500 when FindByID fails during FinishRegistration. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 2/2 changed files
- Comments generated: 0
Document all non-200 HTTP status codes returned by PasskeyHandler endpoints, including the 500 path in FinishRegistration when Users.FindByID fails (fixed in #48 to prevent a nil pointer panic). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* docs: add PasskeyHandler error response reference table Document all non-200 HTTP status codes returned by PasskeyHandler endpoints, including the 500 path in FinishRegistration when Users.FindByID fails (fixed in #48 to prevent a nil pointer panic). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * docs: scope 503 to ceremony endpoints, add invalid JSON 400 for BeginRegistration * docs: add credential/user lookup failure to FinishAuthentication 401 conditions --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Patrick Veverka <veverkap@users.noreply.github.com>
FinishRegistrationsilently discarded the error fromUsers.FindByID, passing a nil*auth.UserintopasskeyUser— whose methods dereferenceu.user.ID,u.user.Email, etc. — causing a guaranteed runtime panic on any transient DB failure.Changes
handler/passkey.go— propagate theFindByIDerror inFinishRegistration, returning HTTP 500 on failure (consistent withBeginRegistrationand every otherFindByIDcall in the codebase):handler/passkey_test.go— addsTestPasskey_finishRegistration_findByIDErrorcovering the new error path (asserts HTTP 500 whenFindByIDreturns an error).Greptile Summary
This PR fixes a nil pointer panic in
FinishRegistrationby propagating theFindByIDerror instead of silently discarding it, consistent withBeginRegistrationand every otherFindByIDcall in the file. A targeted test covering the new error path is also added.Confidence Score: 5/5
Safe to merge — the fix is minimal, correct, and consistent with existing patterns; the new test validates the error path directly.
The change is a single-hunk bug fix that eliminates a guaranteed runtime panic. It mirrors the identical error-handling pattern used in
BeginRegistrationand everywhere elseFindByIDis called in this file. The test is well-formed and covers exactly the new code path. No P0/P1 issues found.No files require special attention.
Important Files Changed
FindByIDerror inFinishRegistration, preventing nil dereference onpasskeyUsermethods; matches existing error-handling pattern throughout the file.TestPasskey_finishRegistration_findByIDErrorcovering the new error path; mock setup is correct and assertion verifies HTTP 500 is returned.Sequence Diagram
sequenceDiagram participant Client participant FinishRegistration participant ChallengeStore participant UserStore participant WebAuthn participant CredStore Client->>FinishRegistration: POST /passkeys/register/finish?session_id=X FinishRegistration->>ChallengeStore: GetAndDeleteChallenge(sessionID) ChallengeStore-->>FinishRegistration: challengeData / err alt challenge missing or expired FinishRegistration-->>Client: 400 Bad Request end FinishRegistration->>UserStore: FindByID(userID) UserStore-->>FinishRegistration: user / err alt err != nil (NEW PATH) FinishRegistration-->>Client: 500 Internal Server Error end FinishRegistration->>CredStore: ListCredentialsByUser(userID) CredStore-->>FinishRegistration: existingCreds FinishRegistration->>WebAuthn: FinishRegistration(waUser, sessionData, r) WebAuthn-->>FinishRegistration: credential / err alt verification failed FinishRegistration-->>Client: 400 Bad Request end FinishRegistration->>CredStore: CreateCredential(...) CredStore-->>FinishRegistration: stored / err FinishRegistration-->>Client: 201 Created (PasskeyCredentialDTO)Reviews (1): Last reviewed commit: "Fix nil pointer panic in FinishRegistrat..." | Re-trigger Greptile