Should you stop using SMS OTPs for authentication now?
Yes, because they are vulnerable to attacks and can incur huge costs from telecom providers.
There you go; there's no need to read the rest of the article. However, isn't SMS OTP authentication also a very convenient and popular passwordless method?
Since there isn't a cut-and-dry answer, does this mean we have to look at this issue with nuance? Let's get started.
Why passwordless and OTP-based authentication became popular
In recent times, the move toward passwordless systems has been driven by the inherent weaknesses of traditional passwords, such as password reuse and weak password usage. OTP-based authentication, particularly through SMS, came up as a convenient alternative. In an SMS OTP authentication workflow, a random numeric or alphanumeric string is generated by a server and sent to a user's mobile device. The user inputs the OTP, which is then validated against the server's generated value. The simplicity of user experience within this workflow and high accessibility (of mobile phones) made SMS OTP authentication a very popular passwordless authentication solution.
However, while SMS-based OTP systems initially seemed to resolve password fatigue and provided an easy-to-deploy second factor of authentication, they've been challenged by both security concerns and reliability issues. Despite the technical simplicity of generating and verifying OTPs, the reliance on mobile carriers introduces vulnerabilities that app developers cannot always control, making SMS-based OTP systems an increasingly questionable choice.
Pros of SMS OTP authentication
From a technical perspective, SMS OTP offers several practical benefits:
Ease of implementation: Most SMS OTP solutions are easy to integrate using APIs provided by services such as Twilio and Vonage. These services handle OTP generation and delivery and provide APIs for server-side validation.
Reduced password dependency: SMS OTP eliminates the need for complex passwords, reducing attack vectors like credential stuffing or brute-force attacks. Passwords are replaced by short-lived tokens, reducing exposure.
Cost-effective for user coverage: Mobile phone penetration is nearly universal, meaning that users don't need additional devices or applications for SMS OTP. This can significantly lower the barriers to adoption in systems where basic security enhancements are needed.
Asynchronous delivery: SMS OTPs allow for asynchronous message delivery, which can be useful in low-bandwidth or high-latency environments where real-time authentication (like push notifications) may not be reliable.
Simpler UX: SMS OTPs allow users to have a simpler authentication experience as they do not need to memorize or manage more passwords.
Cons of SMS OTP authentication
The technical drawbacks of SMS OTP often outweigh its benefits, especially in the context of modern security concerns:
Vulnerable to SIM-swapping: Attackers can exploit weaknesses in mobile carriers' systems through SIM-swapping attacks, effectively taking control of the target's phone number. Once an attacker has access to the SMS stream, they can intercept OTPs, gaining unauthorized access.
Man-in-the-Middle (MITM) attacks: In certain cases, attackers can intercept SMS OTPs using malware or by exploiting vulnerabilities in the SS7 protocol, which governs how messages are exchanged in cellular networks. This introduces a significant attack vector outside the control of the app or system utilizing the OTP.
Delivery failures and latency: SMS delivery is dependent on mobile network reliability, which varies across geographies. Message delays or failures can degrade the user experience, especially in critical workflows such as multi-factor authentication (MFA).
No end-to-end encryption: SMS does not provide end-to-end encryption, meaning that messages are susceptible to interception at various points, whether through carrier vulnerabilities or rogue network infrastructure.
Replay attacks: While most OTP systems implement time-based restrictions, if the OTP isn't invalidated after first use or is used in conjunction with insecure session management practices, it opens the door for replay attacks.
Social engineering: One of the most common ways attackers bypass SMS OTP systems is through social engineering attacks. Attackers impersonate service providers or technical support teams and trick users into revealing OTPs sent to their phones. Since the user unwittingly gives the attacker the valid OTP, this renders the entire security process ineffective. SMS OTP solutions do not provide any built-in mechanism to defend against these types of attacks, leaving users vulnerable.
Alternatives to SMS OTP authentication
To overcome the limitations of SMS OTPs, several more secure and technically advanced alternatives are gaining traction:
TOTP (Time-based One-Time Password) via authenticator apps: Authenticator apps like Google Authenticator or Authy generate time-based tokens based on a shared secret (HMAC-based OTPs). This solution is more secure than SMS since it is decoupled from the cellular network, leveraging cryptographic algorithms to generate OTPs locally. TOTP systems are more resilient to man-in-the-middle attacks as they don't transmit OTPs over vulnerable networks. They have grown to become a very popular second factor of authentication.
Push-based authentication: Push notifications, which trigger real-time approval requests to a user's trusted device, can authenticate users without needing a code. Push-based methods use secure, encrypted communication channels between the client and server, reducing the attack surface. These systems are typically integrated via SDKs like Firebase Cloud Messaging (FCM) or Apple Push Notification service (APNs). The method is effective for mobile apps; however, it will not work for web apps without a mobile companion.
Magic links: Magic links are an increasingly popular alternative in passwordless authentication flows. When users attempt to log in, they receive a time-bound link via email, which authenticates them upon clicking. Since no credentials are exchanged during the login, magic links eliminate the risk of password-related attacks and are immune to phishing as long as the email system itself is secure.
Email-based OTPs: Email OTPs follow the same principle as SMS OTPs but are delivered via email. While email can still be vulnerable to phishing and interception, email-based OTPs reduce the risk of SIM-swapping and mobile network vulnerabilities. For improved security, emails can be encrypted and coupled with secure email providers, but the method remains vulnerable to phishing if the user's email account is compromised.
FIDO2/WebAuthn (Public Key Cryptography): The FIDO2/WebAuthn standard uses public key cryptography to authenticate users. Instead of sending a shared secret like an OTP, the authentication process involves signing a challenge with a private key stored in a secure element on the user's device (e.g., a YubiKey, fingerprint sensor, or any other hardware security module). The server validates the signature with the corresponding public key, making this method highly resistant to phishing and other common attacks. This method is designed to eliminate the weaknesses of passwords and OTPs entirely.
Passwordless authentication with Appwrite
Appwrite Authentication also features three passwordless authentication methods: magic links, email OTPs, and SMS OTPs, which can be integrated into applications seamlessly with Appwrite's client-side SDKs.
Magic URL authentication is a two-step process in Appwrite.
First, we initialize the login process by sending an email with the magic URL. If the email has never been used, a new account is also generated.
import { Client, Account, ID } from "appwrite";
const client = new Client()
.setEndpoint('https://cloud.appwrite.io/v1')
.setProject('<PROJECT_ID>');
const account = new Account(client);
const user = await account.createMagicURLToken(ID.unique(), '[email protected]');
After receiving the secret from an email, you can create a session for the user.
const urlParams = new URLSearchParams(window.location.search);
const secret = urlParams.get('secret');
const userId = urlParams.get('userId');
const user = await account.createSession(userId, secret);
Email OTP authentication is a two-step process in Appwrite.
First, we initialize the login process by sending an email. If the email has never been used, a new account is also generated.
import { Client, Account, ID } from "appwrite";
const client = new Client()
.setEndpoint('https://cloud.appwrite.io/v1')
.setProject('<PROJECT_ID>');
const account = new Account(client);
const sessionToken = await account.createEmailToken(
ID.unique(),
'[email protected]'
);
const userId = sessionToken.userId;
After receiving the secret (6-digit number) in the email, you can use it along with the returned user ID to confirm the user.
const session = await account.createSession(
userId,
'[SECRET]'
);
SMS OTP authentication is a two-step process in Appwrite.
First, we initialize the login process by sending an SMS. If the phone number has never been used, a new account is also generated.
import 'package:appwrite/appwrite.dart';
final client = Client()
.setEndpoint('https://cloud.appwrite.io/v1')
.setProject('<PROJECT_ID>');
final account = Account(client);
final sessionToken = await account.createPhoneToken(
userId: ID.unique(),
phone: '+14255550123'
);
final userId = sessionToken.userId;
After receiving the secret (6-digit number) in the SMS, you can use it along with the returned user ID to confirm the user.
final session = await account.createSession(
userId: userId,
secret: '[SECRET]'
);
Additionally, Appwrite offers a solution that allows developers to integrate any external authentication method with their Appwrite project.
Conclusion
So, now we know what SMS OTPs are good at and bad at. If your app solves a more casual use case, you are very much good to go with OTP authentication. However, if you have very sensitive data and higher security requirements, a multi-factor authentication solution using alternative methods like TOTPs and FIDO2/WebAuthn is the way to go.