[GH-ISSUE #749] Bug: User with empty email can be created using email OTP. Input validation is probably not performed. #17040

Closed
opened 2026-04-15 14:59:05 -05:00 by GiteaMirror · 0 comments
Owner

Originally created by @JosipPardon on GitHub (Dec 3, 2024).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/749

Describe the bug
User with empty email can be created using OTP. Input validation is probably not performed. authClient.emailOtp.sendVerificationOtp and authClient.emailOtp.sendVerificationOtp are problematic.

To Reproduce

auth-client.ts:
import { createAuthClient } from "better-auth/react";
import { emailOTPClient } from "better-auth/client/plugins";
export const authClient = createAuthClient({
  plugins: [emailOTPClient()],
});

auth.ts:
const prisma = new PrismaClient();
export const auth = betterAuth({
  database: prismaAdapter(prisma, {
    provider: "mysql",
  }),

  emailAndPassword: {
    enabled: false,
  },

  plugins: [
    emailOTP({
      async sendVerificationOTP({ email, otp, type }) {
        console.log(`Your OTP is ${otp}`); // for testing purposes
      }
    }),
  ],
});

page.tsx:
const [code, setCode] = useState("");
const [email, setEmail] = useState("");
const [codeSent, setCodeSent] = useState(false);
<button
  onClick={async () => {
    await authClient.emailOtp.sendVerificationOtp(
      {
        email: email,
        type: "sign-in", // or "email-verification"
      },
      {
        onSuccess: (ctx) => {
          setCodeSent(true);
        },
      }
    );
  }}
>
  sign in / sign up
</button>

and then: 
<input
  type="text"
  value={code}
  onChange={(e) => setCode(e.target.value)}
/>
<button
  onClick={async () => {
    const user = await authClient.signIn.emailOtp({
      email: email,
      otp: code,
    });
  }}
>
  confirm code
</button>

Expected behavior
When empty email is passed as input, user should not be created nor logged it. authClient.emailOtp.sendVerificationOtp should result in error, as well as authClient.signIn.emailOtp.

Originally created by @JosipPardon on GitHub (Dec 3, 2024). Original GitHub issue: https://github.com/better-auth/better-auth/issues/749 **Describe the bug** User with empty email can be created using OTP. Input validation is probably not performed. `authClient.emailOtp.sendVerificationOtp` and `authClient.emailOtp.sendVerificationOtp` are problematic. **To Reproduce** ``` auth-client.ts: import { createAuthClient } from "better-auth/react"; import { emailOTPClient } from "better-auth/client/plugins"; export const authClient = createAuthClient({ plugins: [emailOTPClient()], }); auth.ts: const prisma = new PrismaClient(); export const auth = betterAuth({ database: prismaAdapter(prisma, { provider: "mysql", }), emailAndPassword: { enabled: false, }, plugins: [ emailOTP({ async sendVerificationOTP({ email, otp, type }) { console.log(`Your OTP is ${otp}`); // for testing purposes } }), ], }); page.tsx: const [code, setCode] = useState(""); const [email, setEmail] = useState(""); const [codeSent, setCodeSent] = useState(false); <button onClick={async () => { await authClient.emailOtp.sendVerificationOtp( { email: email, type: "sign-in", // or "email-verification" }, { onSuccess: (ctx) => { setCodeSent(true); }, } ); }} > sign in / sign up </button> and then: <input type="text" value={code} onChange={(e) => setCode(e.target.value)} /> <button onClick={async () => { const user = await authClient.signIn.emailOtp({ email: email, otp: code, }); }} > confirm code </button> ``` **Expected behavior** When empty email is passed as input, user should not be created nor logged it. `authClient.emailOtp.sendVerificationOtp` should result in error, as well as `authClient.signIn.emailOtp`.
GiteaMirror added the locked label 2026-04-15 14:59:05 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#17040