Summary
Users can sign up with an email, skip the verification code, and still log in with full access. The backend hardcodes Verified: true for all Kratos sessions without checking the actual email verification status from Kratos identity data.
Root Cause
Three locations in go/api/auth/kratos.go set Verified: true unconditionally:
IsAuthenticatedKratos (line ~1372) — Verified: true, // Kratos sessions imply verified
IsAuthenticatedKratosFromRC (line ~1443) — Verified: true
KratosIdentityToUserInfo (line ~2624) — Verified: true
Additionally, AuthMiddleware in go/authmiddleware/auth.go never checks the Verified field, so even if it were set correctly, unverified users would still pass through.
Steps to Reproduce
- Sign up with a new email (e.g.
chending0602@hotmail.com)
- Backend sends verification email — do NOT enter the code
- Log in with the same email
- Result: Full access granted despite unverified email
Fix
go/api/auth/kratos.go
- Read actual verification status from
identity.VerifiableAddresses[].Verified (Ory SDK) instead of hardcoding true
- Add
isIdentityEmailVerified() for typed identity and isRawIdentityEmailVerified() for raw JSON map
go/authmiddleware/auth.go
- Add verification check in
AuthMiddleware — unverified users get redirected to /verification (HTML) or receive 403 with EMAIL_NOT_VERIFIED code (API)
- Exempt paths:
/verification, /api/v1/auth/verification, /api/v1/auth/logout, /api/v1/auth/me
Affected Projects
All projects using the shared auth library (tax/Mirai, ChenWeb)
Summary
Users can sign up with an email, skip the verification code, and still log in with full access. The backend hardcodes
Verified: truefor all Kratos sessions without checking the actual email verification status from Kratos identity data.Root Cause
Three locations in
go/api/auth/kratos.gosetVerified: trueunconditionally:IsAuthenticatedKratos(line ~1372) —Verified: true, // Kratos sessions imply verifiedIsAuthenticatedKratosFromRC(line ~1443) —Verified: trueKratosIdentityToUserInfo(line ~2624) —Verified: trueAdditionally,
AuthMiddlewareingo/authmiddleware/auth.gonever checks theVerifiedfield, so even if it were set correctly, unverified users would still pass through.Steps to Reproduce
chending0602@hotmail.com)Fix
go/api/auth/kratos.goidentity.VerifiableAddresses[].Verified(Ory SDK) instead of hardcodingtrueisIdentityEmailVerified()for typed identity andisRawIdentityEmailVerified()for raw JSON mapgo/authmiddleware/auth.goAuthMiddleware— unverified users get redirected to/verification(HTML) or receive 403 withEMAIL_NOT_VERIFIEDcode (API)/verification,/api/v1/auth/verification,/api/v1/auth/logout,/api/v1/auth/meAffected Projects
All projects using the shared auth library (tax/Mirai, ChenWeb)