T05 · Unauthorized Access and Privilege Escalation
- Location
- api/app/api/routes/auth.py:25
- Finding
- Magic-Link Token Disclosure Enables Authentication Bypass<![CDATA[ ## Vulnerability Details **File Location**: `api/app/api/routes/auth.py:25-66` **Vulnerability Type**: Authentication token disclosure and account takeover **Risk Level**: Critical ### Vulnerable Code ```python token = create_magic_link_token() expires_at = datetime.now(timezone.utc) + timedelta( minutes=settings.magic_link_expire_minutes ) try: magic_link = MagicLink( email=request.email, token=token, expires_at=expires_at, ) creator_query = select(Creator).where(Creator.email == request.email) creator_result = await db.execute(creator_query) creator = creator_result.scalar_one_or_none() if not creator: creator = Creator(email=request.email) db.add(creator) await db.flush() db.add(magic_link) await db.commit() if email_service.is_configured(): await email_service.send_magic_link( to_email=request.email, token=token, frontend_url=settings.frontend_url, ) return MagicLinkResponse( success=True, message="Check your email for the sign-in link.", ) return MagicLinkResponse( success=True, message=f"Magic link created. Token: {token} (dev only - don't expose in production)", ) except Exception as e: await db.rollback() raise HTTPException(status_code=500, detail=f"Failed to create magic link: {str(e)}") ``` ### Technical Analysis The application returns a valid magic-link token directly in the HTTP response whenever the email service is not configured. This behavior is controlled only by `email_service.is_configured()` and is not restricted to a development or test environment. Production orchestration permits an empty `RESEND_API_KEY`, so a production instance can enter this insecure branch. Because callers can supply an arbitrary email address, an unauthenticated attacker can request a token for another creator's email address and use i ...[truncated 992 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Never return authentication tokens in an API response from the magic-link request endpoint. - Explicitly gate any development-only behavior using a dedicated test setting, and reject startup if that setting is enabled in production. - In production, fail closed when the email service is unavailable. - Require successful delivery through a verified email channel before allowing token redemption. - Add per-IP and per-email rate limits to the magic-link request and verification endpoints. - Return the same generic response for existing and non-existing accounts. - Record token issuance and redemption events for abuse detection. - Consider storing only a cryptographic hash of each magic-link token. - Invalidate previously issued unconsumed tokens when a new token is generated. ]]>
