Detect SIM Swap Fraud With Enterprise-level Security Checks
Published on September 26, 2024

Introduction

In this tutorial, you’ll learn how to use the Vonage SIM Swap API 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 where criminals deceive 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 Vonage SIM Swap API?

The Vonage SIM Swap API 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. Built on open standards from the CAMARA project, an open-source initiative within the Linux Foundation, the Vonage SIM Swap API provides a reliable and efficient way to enhance the security of applications that use 2FA.

Prerequisites

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 API 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.

The user logins and verifiies their identity via the front end. The front end communicates with the Vonage Communication Services that that check SIM Swap details with the Communication Service Providers.Overview Diagram

Project Architecture

For your reference, this is how the project directory will look like. 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 some npm packages, including dotenv, axios, and express to handle environmental variables, HTTP requests, and server operations, respectively.

npm install dotenv axios express

Structure your App

We will import and initialize the dependencies and tell Express to read the static files from the public folder.

// server.js

require("dotenv").config();
const path = require("path");
const express = require("express");
const axios = require("axios");
const app = express();

app.use(express.json());
app.use(express.static("public"));

SIM Swap API Authentication

Vonage Network API calls require a valid access token, which is used to authenticate and authorize access to the APIs when communicating with Communication Service Providers (CSPs). To obtain this access token, you must authenticate with Vonage using a JSON Web Token (JWT).

A JWT is a compact, self-contained JSON token that securely transmits information between parties. This JWT is used to authenticate with Vonage's APIs, and once authenticated, you can obtain the access token needed for API calls to the CSPs.

You can generate the JWT using the Vonage Server SDK or Vonage's JWT Generator. After generating the JWT, add it to your environment variables (${process.env.JWT}) as shown in the code snippet below: 

Before making a SIM Swap check, you must authenticate with Vonage's servers:

// server.js

async function authenticate(phone, scope) {

  const authReqResponse = await axios.post(

    authReqUrl,

    {

      login_hint: phone,

      scope: scope,

    },

    {

      headers: {

        Authorization: Bearer ${process.env.JWT},

        "Content-Type": "application/x-www-form-urlencoded",

      },

    }

  );

  const tokenResponse = await axios.post(

    tokenUrl,

    {

      auth_req_id: authReqResponse.data.auth_req_id,

      grant_type: "urn:openid:params:grant-type:ciba",

    },

    {

      headers: {

        Authorization: Bearer ${process.env.JWT},

        "Content-Type": "application/x-www-form-urlencoded",

      },

    }

  );

  return tokenResponse.data.access_token;

}

SIM Swap Checks

Using the access token you generated, you can use the SIM Swap API to check SIMs. The SIM Swap API verifies the activation date of a SIM card on the mobile network through two endpoints:

  • Has a SIM swap occurred during the last n hours? (/check)

  • When did the last SIM swap occur? (/retrieve-date)

The phoneNumber variable is the phone number you want to check; it's what the user inputs as login.

The MAX_AGE variable corresponds with the maximum number of days you want to check if the SIM was swapped. The hours to be checked are from 1 to 2400 (optional; the default is 240).

If the response is successful, the boolean value returned in the swapped field indicates whether a SIM swap has been performed during the specified period.

async function checkSim(phoneNumber) {
  const accessToken = await authenticate(phoneNumber, scope);
  try {
    const response = await axios.post(
      simSwapApiUrl,
      {
        phoneNumber: phoneNumber,
        maxAge: process.env.MAX_AGE,
      },
      {
        headers: {
          Authorization: `Bearer ${accessToken}`,
          "Content-Type": "application/json",
        },
      }
    );
    return response.data.swapped;
  } catch (error) {
    console.error(
      "SIM swap check error:",
      error.response?.data || error.message
    );
    throw error;
  }
}

Build the Login

To implement the login, we will create a post endpoint called /login that checks whether the input username or password credentials are correct.

// server.js
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 them to the server endpoints created to handle the login and SIM Swap checks. Your server handles responses from the SIM Swap API 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 environment variables in the code snippet below. Refer to Michael's blog post for an explanation of using environment variables in Node.js.

# Use this URL to generate a new JWT: https://developer.vonage.com/en/jwt
JWT=your_jwt_token

# Number of hours to check SIM Swap events
MAX_AGE=72

# Phone Number you'll use the SIM Swap API
PHONE_NUMBER=+123456789

Build the Frontend

Create an index.html HTML page where users can input their phone number to check for a SIM swap. There is one form for the user to input their credentials, in addition to a modal that once the login submission has gone through correctly if a SIM Swap pairing has occurred, a modal pops up with 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.js

Navigate to the page, e.g., localhost:3000, and enter your login credentials, providing the username as a phone number. If that number has been swapped, you'll get a warning and won't be able to log in. Otherwise, you can log in and see your fake bank overview page.

Conclusion

Congratulations, you've reached the end of this tutorial! You've learned to use the SIM Swap API to detect if your users' phone numbers were swapped in the last few days. What you learned today is essential to safeguarding your online accounts and preventing SIM swapping attacks, which can lead to SIM swap fraud.

Understanding how sim swapping works and how it affects personal information is fascinating. By implementing multi-factor authentication methods and being aware of standard 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 strange activity. Also, be careful with your social media and online accounts to avoid putting yourself at risk.

If you have questions, join the Vonage Community Slack or message us on X.

Further Reading

Amanda CavallaroDeveloper Advocate

Ready to start building?

Experience seamless connectivity, real-time messaging, and crystal-clear voice and video calls-all at your fingertips.