Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(auth): prevent email enumeration during auth flows #1540

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

princesinghrajput
Copy link

@princesinghrajput princesinghrajput commented Feb 1, 2025

Description

This PR improves security by preventing email enumeration during authentication flows. Currently, the system exposes whether an email is registered through explicit error messages and different UI flows, which could be exploited by malicious users to discover valid user accounts.

Key Changes:

  1. Login Flow

    • Remove "user not found" error message
    • Always proceed to verification page regardless of email status
    • Send verification email silently only if user exists
    • Update verification page text to be ambiguous
  2. Registration Flow

    • Remove "user already exists" error message
    • Silently redirect to login flow if email exists
    • Send appropriate verification email (login vs register) based on status
    • Update verification page text to be consistent
  3. UI/UX Improvements

    • Use consistent messaging across both flows
    • Maintain smooth user experience while improving security
    • Update translations to use more generic language

Security Impact

This change prevents attackers from using the authentication flows to build lists of valid user accounts, which could be used for:

  • Targeted phishing attacks
  • Password spraying attacks
  • Social engineering attempts

The improved flow maintains the same user experience while removing information disclosure vulnerabilities.

Testing

The changes have been tested for:

  • New user registration
  • Existing user registration attempt
  • Login with existing email
  • Login with non-existent email
  • Verification code validation
  • Email delivery for both flows

Checklist

  • I have performed a self-review of my code
  • My code follows the code style of this project
  • I have commented my code, particularly in hard-to-understand areas

Summary by CodeRabbit

  • New Features

    • Enhanced email verification process with more precise messaging.
    • Improved user registration flow with conditional email sending.
  • Bug Fixes

    • Simplified login and registration error handling.
    • Updated email verification instructions for clarity.
  • Documentation

    • Refined localization strings for authentication-related messages.
    • Updated user-facing text to provide clearer guidance during account verification.

Improve security by not exposing whether an email exists during login and registration:
- Update login flow to always proceed to verification page
- Update registration flow to silently redirect to login if email exists
- Send appropriate verification emails (login vs register) without exposing status
- Update verification page text to be consistent and ambiguous
- Remove explicit error messages that could expose user existence
- Use generic email verification messaging throughout

This prevents malicious users from discovering which email addresses
are registered in the system while maintaining a smooth user experience.
Copy link

vercel bot commented Feb 1, 2025

@princesinghrajput is attempting to deploy a commit to the rallly Team on Vercel.

A member of the Team first needs to authorize it.

Copy link
Contributor

coderabbitai bot commented Feb 1, 2025

Walkthrough

This pull request focuses on refining the user authentication and email verification flow across multiple components. The changes primarily involve updating localization strings, modifying the login and registration processes, and improving the email verification user experience. The modifications simplify the authentication logic, remove explicit user existence checks, and provide more consistent messaging around email verification across different parts of the application.

Changes

File Change Summary
apps/web/public/locales/en/app.json - Updated requiredString format
- Modified loginVerifyDescription
- Added verifyEmailTitle and verifyEmailDescription
- Added authError message
apps/web/src/app/[locale]/(auth)/login/components/login-email-form.tsx - Removed user existence check
- Simplified redirection to verification page
apps/web/src/app/[locale]/(auth)/login/verify/page.tsx - Updated default text for verification description
apps/web/src/app/[locale]/(auth)/register/components/register-name-form.tsx - Added signIn import
- Modified error handling for user registration
apps/web/src/app/[locale]/(auth)/register/verify/page.tsx - Removed locale parameter from VerifyPage
- Updated translation keys
apps/web/src/auth.ts - Enhanced email sending logic
- Added conditional email template selection

Sequence Diagram

sequenceDiagram
    participant User
    participant LoginForm
    participant AuthSystem
    participant EmailService

    User->>LoginForm: Enter email
    LoginForm->>AuthSystem: setVerificationEmail(email)
    AuthSystem->>EmailService: Send verification email
    EmailService-->>User: Email with verification code
    User->>LoginForm: Enter verification code
    LoginForm->>AuthSystem: Verify code
    AuthSystem-->>User: Authentication result
Loading

Possibly related PRs

Poem

🐰 A Rabbit's Authentication Tale 🔐
Emails fly, no checks in sight,
Verification's path now smooth and bright.
Code simplified, messages clear,
Authentication's magic draws near!
Hop along, verification's here! 🚀


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0ac1d06 and 2d054b8.

📒 Files selected for processing (6)
  • apps/web/public/locales/en/app.json (2 hunks)
  • apps/web/src/app/[locale]/(auth)/login/components/login-email-form.tsx (1 hunks)
  • apps/web/src/app/[locale]/(auth)/login/verify/page.tsx (1 hunks)
  • apps/web/src/app/[locale]/(auth)/register/components/register-name-form.tsx (2 hunks)
  • apps/web/src/app/[locale]/(auth)/register/verify/page.tsx (2 hunks)
  • apps/web/src/auth.ts (1 hunks)
🔇 Additional comments (7)
apps/web/src/app/[locale]/(auth)/login/verify/page.tsx (1)

40-40: LGTM! Security improvement in messaging.

The updated message "If an account exists, a verification code will be sent to your email" effectively prevents email enumeration by not confirming whether an account exists, while maintaining clear communication with users.

apps/web/src/app/[locale]/(auth)/register/verify/page.tsx (2)

18-19: LGTM! Code simplification.

Removing the unused locale parameter simplifies the code without affecting functionality.


33-34: LGTM! Consistent messaging across auth flows.

The updated i18n keys and default text maintain consistent messaging across the application, which improves user experience while maintaining security.

Also applies to: 41-42

apps/web/src/app/[locale]/(auth)/login/components/login-email-form.tsx (1)

52-60: LGTM! Strong security improvement in login flow.

The changes effectively prevent email enumeration by:

  1. Removing the user existence check
  2. Maintaining consistent behavior regardless of email status
  3. Using clear code comments to explain the security-focused approach

This implementation aligns perfectly with the PR's security objectives.

apps/web/src/app/[locale]/(auth)/register/components/register-name-form.tsx (2)

52-57: LGTM! Improved security in registration flow.

The silent redirection of existing users to the login flow effectively prevents email enumeration while maintaining a smooth user experience.


53-57: Verify error handling for signIn and redirect.

Please ensure proper error handling for the signIn operation and subsequent redirect.

apps/web/public/locales/en/app.json (1)

306-309: LGTM! The localization changes effectively support email enumeration prevention.

The updated strings successfully maintain ambiguity about user existence while providing clear instructions to users.

apps/web/src/auth.ts Outdated Show resolved Hide resolved
- Add try-catch block around signIn call
- Add error message translation for authentication failures
- Only redirect to verify page on successful sign-in
@lukevella
Copy link
Owner

Thanks for picking this up @princesinghrajput

});

if (signInResult?.error) {
throw new Error(signInResult.error);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we just form.setError() here rather than throwing and catching the error?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@princesinghrajput looks like this is still unresolved?

);
});
} else {
// Send registration email
Copy link
Owner

@lukevella lukevella Feb 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the user doesn't exist we shouldn't send any email. It is not desirable or possible to complete a registration from the login form.

@lukevella
Copy link
Owner

There are some e2e tests that will need to be updated to get this merged. You can run them by:

# Switch to web directory
cd apps/web
# Run the tests and filter so that only the authentication tests run
yarn test:integration auth

If you're not planning on updating them let me know and I can plan to do that myself.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3dc7982 and 0be7ee2.

📒 Files selected for processing (3)
  • apps/web/src/app/[locale]/(auth)/login/components/login-email-form.tsx (1 hunks)
  • apps/web/src/app/[locale]/(auth)/register/components/register-name-form.tsx (2 hunks)
  • apps/web/src/auth.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/web/src/auth.ts
  • apps/web/src/app/[locale]/(auth)/register/components/register-name-form.tsx

@princesinghrajput
Copy link
Author

Thanks for the review @lukevella!

I've implemented all your suggestions:

  1. Added back the signIn() call in the login-email-form that was missing
  2. Changed the error handling to use form.setError() instead of throwing errors
  3. Removed the registration email sending for non-existent users during login flow

The changes maintain the security goal of preventing email enumeration while properly handling the authentication flow. Let me know if you'd like me to update the e2e tests as well.

"requiredString": "{name} is required",
"requiredString": "{name} is required",
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this change is necessary or relevant to this PR. Can you please revert this?

});

if (signInResult?.error) {
throw new Error(signInResult.error);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@princesinghrajput looks like this is still unresolved?

locale: true,
},
});
try {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this changes in this file should be reverted because:

  • There's no point in adding a try..catch if we are throwing the error in the catch statement.
  • Sending a registration email from the login form won't allow the user to register a new account. It can only be done from the registration form.

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.

2 participants