
Detect SIM Swap Fraud With Enterprise-level Security Checks
Time to read: 6 minutes
Introduction
In this tutorial, you’ll learn how to use the SIM Swap feature from Vonage Identity Insights to strengthen the security of a typical web app login by detecting potential SIM swap fraud.
What is SIM Swap Fraud?
SIM swap fraud is a malicious technique in which criminals trick mobile providers into transferring a victim’s phone number to a SIM card under their control. Once they have hijacked the phone number, they can bypass two-factor authentication (2FA), granting them access to sensitive accounts such as personal emails, bank accounts, or any application that relies on phone-based verification. This fraud exploits a vulnerability in the 2FA process, making it a significant threat to account security and personal data protection. Learn more about SIM swap fraud in this Norton's article.
What is the SIM Swap feature from Vonage Identity Insights?
The SIM Swap feature from Vonage Identity Insights is a powerful API designed to mitigate the risks of SIM swap fraud. By communicating directly with network operators (Communication Service Providers (CSPs), the API can detect if a user’s phone number has been recently ported to a new SIM card. This detection mechanism helps to prevent account takeovers by identifying suspicious activity related to SIM card changes. The SIM Swap feature from Vonage Identity Insights provides a reliable and efficient way to enhance the security of applications that use 2FA.
Prerequisites
Vonage API Account To complete this tutorial, you will need a Vonage API account. If you don’t have one already, you can sign up today and start building with free credit. Once you have an account, you can find your API Key and API Secret at the top of the Vonage API Dashboard.
Note: The Network APIs are only available in the following Communication Service Providers (CSPs) and countries, and the list of countries is expanding soon.
Overview
I've prepared an example of a typical bank web application login page for today's tutorial. When the SIM Swap Insight checks with the mobile carriers to see if any recent changes have been made to the SIM's phone number, the user cannot log in if such changes have occurred. Otherwise, they'll be able to log in to their account.
The user logs in and verifies their identity via the front end. The front end sends this information to the server, which then communicates with Vonage Communication Services to check SIM Swap details with the Communication Service Providers.
Overview Diagram
Project Architecture
For your reference, this is how the project directory will look. You can find the complete code on GitHub.
[node_modules]
[public]
client.js
style.css
[views]
main.html
index.html
.env
server.js
package-lock.json
package.json
private.key
Set Up Your Development Environment
To begin, you'll need Node.js and npm installed on your machine. You'll also need to install npm. To begin, you'll need Node.js and npm installed on your machine. You'll also need to install some npm packages, including @vonage/identity-insights, dotenv, express, and nodemon to handle environment variables, HTTP requests, and server operations.
npm install Structure your App
We'll import and initialize our dependencies and tell Express to serve static files from the public folder. Authentication with Vonage is handled automatically by the IdentityInsights SDK client when you provide your Application ID and private key; no manual JWT or token management is required.
// server.js
require("dotenv").config();
const path = require("path");
const express = require("express");
const { IdentityInsights } = require("@vonage/identity-insights");
const fs = require("fs");
const app = express();
app.use(express.json());
app.use(express.static("public")); Initialize the Vonage Identity Insights Client
Next, read your credentials from environment variables and instantiate the IdentityInsights client. The SDK handles all authentication internally; it generates the necessary tokens using your Application ID and private key, so you don't need to manage JWTs manually.
Your VONAGE_PRIVATE_KEY environment variable can be set to either the file path of your private.key file (e.g., ./private.key) or the raw key string itself. The code below handles both cases:
const users = {
user1: { password: "123", phoneNumber: process.env.PHONE_NUMBER }
};
const APPLICATION_ID = process.env.VONAGE_APPLICATION_ID;
const PRIVATE_KEY = process.env.VONAGE_PRIVATE_KEY;
const PERIOD = process.env.PERIOD;
if (!APPLICATION_ID || !PRIVATE_KEY) {
console.error("VONAGE_APPLICATION_ID or VONAGE_PRIVATE_KEY not set");
process.exit(1);
}
const keyContent = fs.existsSync(PRIVATE_KEY)
? fs.readFileSync(PRIVATE_KEY, "utf8")
: PRIVATE_KEY;
if (!keyContent) {
console.error(
"INVALID private key. Check if the file exists or the environment variable is correctly set"
);
process.exit(1);
}
const identityClient = new IdentityInsights({
applicationId: APPLICATION_ID,
privateKey: keyContent,
});
SIM Swap Checks
Using the identityClient you just initialized, you can call the SIM Swap Insight to check a phone number. The SIM Swap Insight verifies the activation date of a SIM card on the mobile network through two fields:
latest_sim_swap_at: date and time in UTC ISO 8601 of the latest SIM swap performed
is_swapped: indicates whether the SIM card has been swapped during the specified period
The phoneNumber variable is the phone number you want to check; it's what the user inputs at login. The PERIOD variable specifies the maximum number of hours to check whether the SIM was swapped (1 to 2400; default is 240).
If the response is successful, the boolean value in the isSwapped field indicates whether a SIM swap occurred during the specified period.
async function checkSim(phoneNumber) {
try {
const resp = await identityClient.getIdentityInsights({
phoneNumber: phoneNumber,
purpose: "FraudPreventionAndDetection",
insights: {
format: {},
originalCarrier: {},
currentCarrier: {},
simSwap: {
period: parseInt(PERIOD),
},
},
});
return resp.insights?.simSwap?.isSwapped === true;
} catch (error) {
console.warn("Identity Insights SDK call failed:", error && error.message);
}
} Build the Login
To implement the login, we'll create a POST endpoint called /login that checks whether the input username and password credentials are correct, and then runs a SIM swap check before granting access.
app.post("/login", async (req, res) => {
try {
const { username, password } = req.body;
const user = users[username];
if (user && user.password === password) {
const simSwapped = await checkSim(user.phoneNumber);
if (simSwapped) {
return res.status(401).json({ message: "SIM Swapped" });
} else {
res.json({ message: "Success" });
}
} else {
res.status(401).json({ message: "Invalid username or password" });
}
} catch (err) {
console.error("Error during login:", err);
res.status(500).json({ message: "Error processing request." });
}
});
Build the Client
The client.js file will get the information relevant to HTML elements and send it to the server endpoints created to handle the login and SIM Swap checks. Your server handles responses from the SIM Swap Insight and relays that information to the user through your front end. If the user's SIM has been swapped recently, inform them and suggest immediate actions, like contacting their mobile carrier.
Create the Environment Variables File
Create a .env file for your project and add the following environment variables. Your VONAGE_PRIVATE_KEY can be either the path to your private key file (e.g., ./private.key) or the raw key content as a string. Refer to Michael's blog post for an explanation of how to use environment variables in Node.js.
# Period in hours to check SIM Swap events
PERIOD=72
# Phone Number you'll use for the SIM Swap Insight
PHONE_NUMBER=+990123400
VONAGE_APPLICATION_ID=
VONAGE_PRIVATE_KEY=
Build the Frontend
Create an index.html page where users can input their credentials to log in. There is one form for the user to input their username and password, plus a modal that appears if a SIM swap has been detected, displaying the message: "Warning! A recent SIM swap was detected on your account. Access denied."
Test it Out
Add a port for the server to listen, for instance, 3000.
//server.js
app.listen(3000, () => {
console.log("Server is running on port 3000");
});Run the server JavaScript file to initialize the web application.
node server.jsNavigate to localhost:3000 and enter your login credentials. If the phone number associated with that account has been swapped recently, you'll get a warning and won't be able to log in. Otherwise, you can log in and see the bank overview page.
Conclusion
Congratulations, you've reached the end of this tutorial! You've learned how to use the Vonage Identity Insights SIM Swap Insight to detect if your users' phone numbers were swapped in the last few days. What you've learned today is essential for safeguarding online accounts and preventing SIM-swapping attacks that can lead to account takeovers and fraud.
Understanding how SIM swapping works and how it affects personal information is fascinating. By implementing multi-factor authentication methods and being aware of common social engineering tactics, you can better protect yourself and your users from these scams.
As mobile phones and 5G networks become more common, monitoring your security is even more important. Check your SIM card regularly for unusual activity, and be mindful of what personal information you share on social media and online accounts.
Have a question or something to share? Join the conversation on the Vonage Community Slack, stay up to date with the Developer Newsletter, follow us on X (formerly Twitter), subscribe to our YouTube channel for video tutorials, and follow the Vonage Developer page on LinkedIn, a space for developers to learn and connect with the community. Stay connected, share your progress, and keep up with the latest developer news, tips, and events!
Further Reading
Improve Your Multifactor Auth With Verify and SIM Swap APIs.
Try out the Network API Sandbox to start using the SIM Swap API.
