Every developer should assume hackers will exploit any public website with mobile and OTP login. Their favorite two exploits are -

  1. SMS Credits Exploit - This exploit applies when the website or app allows users to register using mobile OTP. The hackers use random phone numbers to sign up and raise OTPs. They intend to exhaust the SMS credits of the service because, for every sign-up attempt, the service triggers an OTP that consumes credit.
  2. Brute-force OTP Exploit - This exploit applies when the website or app allows users to log in using mobile OTP. If the hackers get a whiff of the mobile number of a genuine user who is signed up, they use that number to raise an OTP and then use brute force to guess the OTP and log into the user’s account. Guessing a four-digit OTP using brute force is child’s play. Even six digits aren’t too difficult, either. Any longer than 6, it becomes unfriendly for the user.

Every developer working on the Mobile Otp sign-up and login feature should protect against these exploits. There isn't one silver bullet to stop all the exploits; therefore, you need various mechanisms to be fully protected.

Mechanisms to protect against these exploits

  1. The most essential practice is that OTP has to be time-based. Ideally, the OTP expires in 1-3 minutes after being triggered. The resend OTP API should not resend OTP if an OTP has already been triggered and has not expired.
  2. Maintain a list of ISD codes in the configuration to not send OTPs. Often, hackers use numbers from third-world countries like Vietnam, Ethiopia, Bangladesh, etc. to sign up. So, if your application doesn’t expect or wants users of certain countries to sign up, you can add those ISD codes in the configuration and ensure your SMS service doesn’t send OTPs to those countries.
  3. We should limit the times a mobile number can raise OTP in a fixed time window. For example, up to 3 OTP requests are allowed every 60 minutes, and up to 8 are allowed in a 24-hour window. The developer must record every OTP attempt in the DB.
  4. The system should allow specific numbers to be blocked from receiving OTPs. This could be implemented using the isBlacklisted flag in the table where user account details are stored. This applies to Login scenarios and not sign-up.
  5. The system should automatically blacklist a number that has raised consecutively x number (say 20) of OTPs but has never logged in using any of them even once.
  6. Implement Captcha using CloudFlare Tunstile (recommended) or Google ReCaptcha. The captcha should be on the first step of the login and sign-up screen, where the user enters the mobile number.