Skip to content

Security: Kratos auth hardcodes Verified=true, bypassing email verification #18

@chendingplano

Description

@chendingplano

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:

  1. IsAuthenticatedKratos (line ~1372) — Verified: true, // Kratos sessions imply verified
  2. IsAuthenticatedKratosFromRC (line ~1443) — Verified: true
  3. 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

  1. Sign up with a new email (e.g. chending0602@hotmail.com)
  2. Backend sends verification email — do NOT enter the code
  3. Log in with the same email
  4. 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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions