1

I'm trying to create a simple web-app (for personal use, but also trying to learn some things along the way). If the stack is important, I'm using:

  • SvelteKit for Frontend
  • Netlify Functions for the API
  • Supabase for the DB (not auth, just DB)

I'm trying to setup an authentication flow that does the following:

  • A user enters their email.
  • I check in the DB if they have an account.
    • If they do, I also check if they have any passkeys or TOTPs setup.
      • If passkey is setup, I aim to allow the user to skip entering the password.
      • If passkey is not setup, I want to ask the user to enter the password. If TOTP is setup, I wish to ask them to enter the TOTP as well.
    • If they don't have an account, they would be prompted to signup.

Now, I'm not sure what kind of data to return to the client if passkeys or TOTPs are setup. For example, should I return something like (high-level example):

{
  "passkeys": [{
    "id": 456,
    "name": "1Password"
  }],
  "totps": [{
    "id": 789,
    "name": "Authy"
  }],
  "user_id": 123
}

OR something as simple as:

{
  "passkeys": true,
  "totp": true,
  "user_id": 123
}

OR not return anything? If I don't return anything, I don't know how would I determine what UI to show on the frontend. If I return either of the two options, not sure if that's good from a security standpoint.

I tried asking "AI" about it and the advice was, sort of mixed. At first, it said not to reveal any such data to the client. But when I asked how to determine the state on the frontend, it asked me to choose option 2 from the above. I was then referring to: https://simplewebauthn.dev/docs/packages/server#authentication which says that I need to return some data from the server that would help "identifying" the passkey (allowCredentials). So my question to AI was that, if I'd anyways have to send some data to identify the passkey back to the client, then what's the point of choosing option 2 as opposed to option 1. The AI then started circling amongst its answers.

Since this is a personal application that I don't intend to publicise or anything, my target audience is likely just me and I don't anticipate any high requirements for security, but I want to learn how to implement a typical auth flow without using any auth library, which is why I'm asking about this.

EDIT 1: I forgot to mention that I also checked one service that implements this: Okta and they seem to send some kind of data back to the client. So I guess that's okay?

EDIT 2: Now that I think about it, maybe server-rendering a page would solve this? Instead of having to send the data to the client, I can generate a page on the server with the required input (like asking for passkey if enabled, or asking for password) and send that to the client. But even that will technically let an attacker know if a user has enabled passkey or not. Not sure if that's concerning or not.

1
  • 1
    It doesn’t really make sense to spend your time trying to perfect implementation details when this is a personal project to learn how 2FA systems work. Start with a simple prototype, try it out and compare it with state-of-the-art implementations. If you want to use 2FA in production, then definitely go with a library which has been professionally developed and reviewed. Even small bugs in an authentication system can have a major security impact, so you shouldn’t rely on a personal prototype.
    – Ja1024
    Commented Jun 18 at 21:47

1 Answer 1

0

In general, you want to return only as much information as necessary (principle of least privilege). If your UX goal is such that "make users click a button or otherwise indicate their preferred credential type the first time they log in on a new client" is unacceptable, and you don't mind some user enumeration risk (you can mitigate it with rate-limiting the login screen), you can do something like the above, but revealing the actual names of the passkeys might be a bit more than you want to do. Remember, you don't yet know who this person is!

Beyond avoiding revealing such user-specific details, I think you can probably just go with whatever works. While "what information do I return to the client?" can be an important security question, in this case I don't really think it is, since all you're doing with it is choosing which UI to show a pre-authenticated user. The only other security consideration that I see here is the usually-minor threat of permitting an anonymous person to query your server for "is somebody with this email address a user, and if so, what kind of credentials do they use?", and while user enumeration is not usually a big risk, it is sometimes worth making more difficult than that.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .