0

I am building a token-based authentication API, and I have three main methods:

Register Method: It takes credentials (email, password, phone number) and creates the user, then sends an OTP message to the phone number provided in the credentials input. At this stage, I haven't implemented any login, session or token creation; I'm simply creating the user.

Verify: This method takes a phone number and a code. It checks the OTP code, and if it is correct, it will get the user data associated with that phone number from db and update its database column 'verify_phone_at' to 'verified' in order to mark the user as verified. Additionally, it will create the token. (here i created the token and verified the user depending on the input phone number)

Login Method: Ensures that the user is verified and creates a new token.

resendVerifyCode: It takes a phone number as credentials and resends the OTP message to that phone number.

The security concerns here are:
1- Verify Method: The user inputs his phone number, and a message is sent to that phone. It's possible that the phone number entered may be different from the one associated with the user's account in register stage because I don't have access to user data (haven't logged in yet to access the authenticated user). The only constraint is that the phone number must exist and be attached to an account, a user can input his friend's phone number, verify it, obtain a token, and access their friend's account without entering email or password just from verify the account.

How to solve this problem: Should I create session for the user after the creation account stage and only generate the token when the user verified his account?

1 Answer 1

1

The real question is why the verify operation authenticates the user?

The verify operation should only mark the phone as verified, and that's it.

The user session should only be created when the user logs in. Not during the verification operation.

Also, I don't really understand your concern:

It's possible that the phone number entered may be different from the one associated with the user's account

The OTP purpose is to ensure that the user entering the phone number really has access to that phone.

  1. If the user enters a wrong number during the registration operation; then they can't receive the OTP, and thus can't verify the number.
  2. If the user enters a wrong number during the verification operation; then the server knows that the OTP entered was not the one issued for this number, and thus can't verify the number.

In any case, if the user uses they friend's phone, you have no way of detecting that, so it will be the user's problem.

However, if their friend already has an account on your server, I assume that a phone number can only be linked to one account, so the server should refuse the phone during the registration operation. And there is no risk of an attacker accessing they friend's account.

5
  • I apologize for any ambiguity in my question. However, your answer was both satisfactory and informative. Thank you for clarifying the crucial aspects of OTP verification. Based on my understanding of your response, here's what I plan to do: When a user logs in and checks his credentials, I will allow him to log in before he confirms his phone number and I will create a session for him. However, I will implement a middleware to restrict his ability to perform any actions until he has successfully confirmed his phone number.
    – Lana Hanna
    Commented Sep 6, 2023 at 10:58
  • No need to apologize! Your plan seems fine. Also, if you want to avoid implementing the middleware (and creating a session), you can add a condition in your log in operation to check whether the user has verified their phone number and deny access if they don't.
    – Shireheart
    Commented Sep 6, 2023 at 11:38
  • "If the user enters a wrong number during the registration operation; then they can't receive the OTP", but this doesn't mean an attacker won't be able to. Number spoofing is a thing (lifewire.com/phone-number-being-spoofed-4774976). As well as SMS interception (offensive-wireless.com/sms-decryption) & (wired.com/story/gsm-decrypt-calls) which may be more or less feasible depending on the country / geo-location of the user & the encryption used (security.stackexchange.com/questions/11493/…).
    – aiootp
    Commented Sep 6, 2023 at 12:10
  • @aiootp is your first point a worry about sending unsolicited message? If so, then yes, the server should limit the number of SMS sent to a number. But for the concern of SMS interception, I wouldn't worry too much about it; it requires large amount of effort and is mostly a targeted attack. So unless the service is very sensitive, it shouldn't be a concern for most applications.
    – Shireheart
    Commented Sep 6, 2023 at 12:52
  • @Shireheart My points are generally about the insecurity of phone numbers & SMS for authentication, since it actually doesn't authenticate the user if the user isn't the only entity that can be reached by routing to their phone number. As you say, the severity & impact of impersonation is highly dependent on the user & application. I'd recommend against defaulting to trusting a demonstrably insecure protocol, but we may disagree.
    – aiootp
    Commented Sep 6, 2023 at 13:17

You must log in to answer this question.

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