DEV Community

Cover image for Integrating MobSF REST API in React js
Pramit Marattha for Aviyel Inc

Posted on

Integrating MobSF REST API in React js

Over the last decade, smartphone technologies have become more powerful and prevalent in each and every aspect, they are commonly used to access the internet, run apps, get an email, conduct financial and banking transactions, and various other things. The use of mobile devices for both personal and professional uses has skyrocketed. The introduction of mobile devices and the proliferation of mobile applications have tremendously aided mobility and flexibility. As a result, massive concerns about maintaining security while navigating the digital world have been raised.

Mobile device security is becoming more of a worry for consumers' privacy. Irrespective of how serious mobile device manufacturers are about a user's security and data privacy, using internet-based applications presents substantial hurdles in terms of resolving threats and vulnerabilities while safeguarding a user's privacy. The majority of software programs are created to do a specific task and are tailored for a particular set of devices, such as smartphones and tablets. Protecting data on mobile devices is a difficult task due to numerous threats and flaws.

The depth of mobile security.

Staying private these days is difficult, and our reliance on mobile technology makes it even more difficult. Personal social media profiles, emails, vital texts, and even bank account information are all stored on our very phones. Despite the fact that these data are frequently sensitive and may include useful information, we proceed to keep them on our smartphones. Furthermore, cell phones are used for the majority of business-to-business transactions. It's no secret that mobile technology is rapidly evolving. Hundreds of millions of people use the internet, with many of them relying heavily on their cell phones and smartphones.

The significance of mobile security is growing by the day and is now more essential than ever, Which is why developers have created and even open-sourced various mobile security frameworks. These kinds of tools is designed and created to mark and evaluate the efficiency of the mobile application, whether you run Android/ iOS or regardless of any platform. MobSF is one of the most useful, practical, and simple-to-use tools available. It's a completely free and open-source tool for evaluating the security of mobile/smartphone applications. MobSF offers superior pen-testing, malware analysis, and security assessment services.

Getting started with MobSF

Setting up MobSF

MobSF is an actively maintained open-source project. So, the documentation is very flexible. Hence, the most up-to-date information is always found on MobSF's official documentation website. MobSF can be set up and run in a number of different ways:

First method (which is highly recommended) :

The first approach to installing MobSF is to manually install all essential components before running the setup script for your Host Operating System.

Prerequisites requirements

MobSF is compatible with a variety of operating systems, but I'll be using Windows, so here are the minimum prerequisites you'll need to get started with MobSF on the windows platform.

Windows

  • Install Git
  • Install Python 3.8-3.9
  • Install JDK 8+ (NOTE: Dont forget to set JAVA_HOME as an global environment variable.)
  • Install Microsoft Visual C++ Build Tools
  • Install OpenSSL (non-light)
  • Download & Install wkhtmltopdf .
  • Add the folder that contains wkhtmltopdf binary to environment variable PATH.

So, once you've installed all of the prerequisites, you may move on to the installation stage.

Installing MobSF.

Simply copy and paste the following command into your VScode terminal to install MobSF on your local PC.

git clone https://github.com/MobSF/Mobile-Security-Framework-MobSF.git
Enter fullscreen mode Exit fullscreen mode

Mobsf Clone

It's now time to navigate into the cloned MobSF project folder.

cd Mobile-Security-Framework-MobSF
Enter fullscreen mode Exit fullscreen mode

Navigate Directory

Once you're inside the project directory, you'll need to install all of the packages and dependencies that the MobSF requires. Simply copy and paste the command below to accomplish this.

Once you're inside the project directory, you'll need to install all of the packages and dependencies that the MobSF requires. Simply copy and paste the command below to accomplish this.

Note: Before you begin, you must first have Python installed on your computer.

./setup.bat
Enter fullscreen mode Exit fullscreen mode

Mobsf setup

Once you've finished installing all of the requirements, your folder structure should look like this.

Folder Structure

After you've completed the setup, you can run the tool by following the steps oulined below:

run.bat 127.0.0.1:8000
Enter fullscreen mode Exit fullscreen mode

MobSF setup

Before running the setup script, make sure you've installed all of the prerequisites. If you run into any issues during the setup process, MobSF offers a variety of support options.

To determine whether or not your application is running. Go to your favourite browser and type in the following URL address.

127.0.0.1:8000
Enter fullscreen mode Exit fullscreen mode

or

localhost:8000
Enter fullscreen mode Exit fullscreen mode

You should see something like this after entering the URL.

MobSF dashboard

To learn more about MobSF click here: Installation Guide MobSF

The second method of installing MobSF:

If you only need to perform static analysis and not dynamic analysis, you may always use prebuilt MobSF docker images. To run prebuilt MobSF docker images, copy and paste the following commands into the command line:

docker pull opensecurity/mobile-security-framework-mobsf
Enter fullscreen mode Exit fullscreen mode

Docker pull

docker run -it --rm -p 8000:8000 opensecurity/mobile-security-framework-mobsf:latest
Enter fullscreen mode Exit fullscreen mode

Docker run

Note: Ensure that Docker is running on your computer.

Docker Desktop

On your Docker desktop, you should see something similar to this.
Docker desktop

You should see something similar on your Docker desktop. To determine whether or not your application is running. Go to your favourite browser and type in the following URL address.

127.0.0.1:8000
Enter fullscreen mode Exit fullscreen mode

You should see something similar to this after entering that URL.

Monsf selfhost

Let’s get started. The main purpose of this tutorial is to create a react application that can retrieve and display scan results as well as upload files directly to MobSF's analyzer using the Rest API functionality. To accomplish this, simply follow the instructions mentioned below.

Setting up React application

To begin, we'll use create-react-app to build the application's front-end. The user interface (UI) and its features will be created entirely from scratch. Let's get started on our application straight away.

Let's start with react and develop our application from scratcth. If Node.js is not already installed on your computer, the first step is to do so. So, go to the Node.js official website and download the most recent version. Now open your favorite code editor and create a new folder called client. We'll use the VScode code editor for this tutorial. Once you are done with it, type npx create-react-app into the integrated terminal which will create a react application in your current directory.

npx create-react-app .
Enter fullscreen mode Exit fullscreen mode

react application

Getting everything set up usually only takes a few minutes. Normally, we'd add packages to a project with npm, but in this case, we'll use npx, the package runner, which will download and configure everything for us so that we can get started right away with a great template. It's time to start our development server, so type npm start to launch our react application in the browser.

React app

So, this is how the boilerplate template initially appears. It's now time to investigate the create-react-app file and folder structure. The subdirectory node modules contains all of our node dependencies. Then there's the public folder, which mainly has the index.html file. When you open the file, it looks to be a standard HTML document with head, body, and meta tags, as you can see. Inside our body tag, there's a div with the id of root name, followed by the fallback noscript tag, which is only visible if the user's browser doesn't support javascript.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    <title>React App</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

So, where did the content come from? Remember that all of our source code is stored in the src folder, and react will inject it into the root div element.

Folder structure

Now, head over to our App.js file

import logo from './logo.svg';
import './App.css';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

In this scenario, we're simply importing react from react and logo from our logo using ordinary javascript. Following that, we have a normal javascript function called APP, which is known as a functional component in react, and this function returns a react-element that appears like HTML but is truly a jsx, as you can see there is a div tag with a className of APP, which we can't say class by itself because class is a reserved word in javascript, so we have to use className in jsx. And after that, we have the header and then the image, with our logo visible on the image source, which is actually a javascript variable that we imported at the top, so we must surround it with curly brackets in order to use the javascript within JSX, and then we have a paragraph, an anchor tag, and that's it for this component.

So, Now let’s look at the index.js file.

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);
Enter fullscreen mode Exit fullscreen mode

As you can see, we're importing react from react once more, along with "react-dom," the CSS stylesheet file, and finally, App from "App.js," which is the file we just discussed, and there's a service worker, which is needed to make your application operate totally offline. Then we call "ReactDom.render," which takes two arguments. The first parameter is the jsx object, which contains our user-defined components , and the second parameter is document.getElementById('root'), which targets the root div in our index.html file and is how we access the content in our webpage.

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);
Enter fullscreen mode Exit fullscreen mode

React boilerplate files cleanup

We need to clean up our projects by eliminating some of the files provided by create-react-app before we can start creating our app. This is how your files and folders should look after you've cleaned them up.

Folder structure

Adding and Installing some packages

This project will also necessitate the installation of a few third-party packages. Copy and paste the following command into your terminal.

Installing Bootstrap

npm install bootstrap
Enter fullscreen mode Exit fullscreen mode

Bootstrap installation

Installing Axios

npm install axios
Enter fullscreen mode Exit fullscreen mode

Axios

After you've installed all of your project's dependencies, your package.json file should look something like this.

{
  "name": "mobsf-react",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.16.4",
    "@testing-library/react": "^13.2.0",
    "@testing-library/user-event": "^13.5.0",
    "axios": "^0.27.2",
    "bootstrap": "^4.6.0",
    "react": "^18.1.0",
    "react-dom": "^18.1.0",
    "react-scripts": "5.0.1",
    "web-vitals": "^2.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

We can get started with MobSF and react integration now that our project and dependencies have been set up.

Integrating MobSF with React

Let's start by importing our bootstrap into our App.js file.

//App.js
import "bootstrap/dist/css/bootstrap.min.css";

function App() {
  return (
    <div className="App">
    Hello there! 
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

After that, make a file called httpRequest.js in the app folder and paste the following code into it.

//httpRequest.js
import axios from "axios";
export default axios.create({
  baseURL: "http://localhost:8000",
  headers: {
    "Content-type": "application/json",
    "Authentication": "a81e178ac6bb1e348e6eecea309c5f425c396057f5deb078be4a4e125278ce48"
  }
});
Enter fullscreen mode Exit fullscreen mode

Configuring a service for File Upload.

First, we import Axios as http from the httpRequest.js script/file that we crteated earlier, then we will prceed to utilize FormData to hold key-value pairs inside the upload() method. Using the add() method, we can create an object that corresponds to an HTML form, and then pass onUploadProgress to expose progress events.Next, we use Axios post() to send an HTTP POST request to the Rest APIs Server for uploading a apk, and get() method to send an HTTP GET request to obtain all the scan results. After you've done that, your code should look like this.

//services/Upload.js
import http from "../httpRequest";
const upload = (file, onUploadProgress) => {
  let formData = new FormData();
  formData.append("file", file);
  return http.post("/upload", formData, {
    headers: {
      "Content-Type": "multipart/form-data",
      Authorization:
      "a81e178ac6bb1e348e6eecea309c5f425c396057f5deb078be4a4e125278ce48",
    },
    onUploadProgress,
  });
};

export default {
  upload,
};
Enter fullscreen mode Exit fullscreen mode

Follow the steps mentioned below to learn more about the API endpoint supplied by MobSF. To do so, go to the MobSF home page and select "API DOCS" from the menu, as shown in the screenshot below.

MobSG dashboard

After that, you should be able to see something similar to this.

REST API docs

After that, you should be able to see something similar to this.
Now you can execute whatever actions you want, but for the purposes of this tutorial, we'll only do static analysis, upload the file using react, and obtain all of the scan findings using it, so you can expand this project and do dynamic analysis and a whole lot more with the MobSF REST API.

Create a Page for Upload Files and displaying Scan results.

Create a File Upload User Interface with a Progress Bar, a Button, and a basic Message. To do so, go to the component folder and create a component or file named "ApkUpload" within it. First, we import Upload: and create a React template with React Hooks (useState, useEffect). Note that we can use the services we developed previously, but for now, let's keep it simple and try to use this component to handle everything.

import React, { useState, useEffect } from "react";
const ApkUpload = () => {

  return (

  );
};
export default ApkUpload ;
Enter fullscreen mode Exit fullscreen mode

After configuring our react template, we use React Hooks approach to define the state used on our application:

const ApkUpload = () => {
  const [selectedFiles, setSelectedFiles] = useState(undefined);
  const [currentFile, setCurrentFile] = useState(undefined);
  const [progress, setProgress] = useState(0);
  const [message, setMessage] = useState("");
  const [fileDetails, setFileDetails] = useState([]);
  ...
}
Enter fullscreen mode Exit fullscreen mode

Next, we'll develop a handler to upload and parse the apk file, as well as submit a post request with the Authorization to Mobsf's Rest API, and don't forget to include a handleChange() function to handle input changes.

const ApkUpload = () => {
  ...
    const handleUpload = async () => {
        const data = new FormData();
        data.append("file", selectedFiles);
        try {
            const res = await axios.post(
                "http://localhost:8000/api/v1/upload",
                data,
                {
                    headers: {
                        "Content-Type": "multipart/form-data",
                        Authorization:
                            "a81e178ac6bb1e348e6eecea309c5f425c396057f5deb078be4a4e125278ce48",
                    },
                    onUploadProgress: (progressEvent) => {
                        setProgress(
                            parseInt(
                                Math.round(
                                    (progressEvent.loaded * 100) /
                                        progressEvent.total
                                )
                            )
                        );
                    },
                }
            );
        } catch (err) {
            if (err.response.status === 500) {
                setMessage("There was a problem with the server");
            } else {
                setMessage(err.response.data.message);
            }
        }
    };
 const handleChange = (e) => {
        setSelectedFiles(e.target.files);
        setCurrentFile(e.target.files[0]);
    };
  ...
}
Enter fullscreen mode Exit fullscreen mode

Let's make a get request inside our useEffect() hook to receive all the scan results.

Note: useEffect() method serves the same purpose as componentDidMount():

const ApkUpload = () => {
  ...
   useEffect(() => {
    axios.get("http://localhost:8000/api/v1/scans", {
    headers: {
      Authorization:
        "a81e178ac6bb1e348e6eecea309c5f425c396057f5deb078be4a4e125278ce48",
    },
  }).then(res => {
    setFileDetails(res.data.content);
  });

  },[]);
  ...
}
Enter fullscreen mode Exit fullscreen mode

Now lets work on the UI of the app. To do so, add the following code inside the return() block/statement:

const ApkUpload = () => {
  ...
  return (
    <div className="container">
            <div className="row">
                <div className="col-md-6">
                    <h1>Upload your APK Here!</h1>
                    <input
                        type="file"
                        name="file"
                        id="file"
                        onChange={handleChange}
                    />
                    <button
                        className="btn btn-primary"
                        onClick={handleUpload}
                        disabled={!selectedFiles}
                    >
                        Upload
                    </button>
                    <br />
                    <br />
                    <progress value={progress} max="100" />
                    <br />
                    <br />
                    <p>{message}</p>
                </div>
                <div className="col-md-6">
                    <h1>Uploaded Files</h1>
                    <ul className="list-group list-group-flush">
                    {/* pdf report download link */}
           {fileDetails &&
             fileDetails.map((file, index) => (
               <li className="list-group-item" key={index}>
                 <a href={file.APP_NAME}>{file.FILE_NAME}</a>
               <br/>
               <br/>
                 {/* colourfull bootstarp text */}
                 Analyzer: <span className="badge badge-light">
                        {file.ANALYZER}
                    </span> <br/>
                    Application name: <span className="badge badge-primary">
                        {file.APP_NAME}
                    </span><br/>
                    Application package name: <span className="badge badge-success">
                        {file.PACKAGE_NAME}
                    </span>  <br/>
                    Application File name:<span className="badge badge-danger">
                        {file.FILE_NAME}
                    </span> <br/>
                    Application Scan Type: <span className="badge badge-warning">
                        {file.SCAN_TYPE}
                    </span> <br/>
                    Scan date: <span className="badge badge-info">
                        {file.TIMESTAMP}
                    </span> <br/>
                    Application Version: <span className="badge badge-dark">
                        {file.VERSION_NAME}
                    </span> <br/> <br/>
                        </li>
                        ))}
                    </ul>
                </div>
            </div>
        </div>
    );
};
Enter fullscreen mode Exit fullscreen mode

In the code above, we use Bootstrap Progress Bar: To display List of scan files, we iterate over fileDetails array using map() function. Following is the reposne we got from the MobSF RestAPI.

We utilize Bootstrap Progress Bar in the code above and then we use the map() function to loop through the fileDetails array to display the List of scan files. The following is the output of the MobSF RestAPI response.

Bootstrap

On each file item, we use file.APP_NAME ,file.PACKAGE_NAME , file.VERSION_NAME attribute and so on and so forth for displaying the text/content.

Last but not least, remember to export the component:

const ApkUpload = () => {
  ...
}
export default ApkUpload ;
Enter fullscreen mode Exit fullscreen mode

Finally, import this component into your App.js file, and you should be able to upload the apk file. When you're finished, your App.js code should look like this.

//App.js
import "bootstrap/dist/css/bootstrap.min.css";
import ApkUpload from "./components/ApkUpload"

function App() {
  return (
    <div className="App">
    <div className="container-fluid">
      <div className="row">
        <div className="col-md-12">
          <ApkUpload />
        </div>
      </div>
    </div>
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Finally, type the following command into the terminal to restart your react server.

npm start
Enter fullscreen mode Exit fullscreen mode

npm start

Open your browser and navigate to the server URL where your react is presently running. You should see something similar to this.

upload APK

Now you can upload whatever Apk file you like, but make sure it's light and little in size.

Folder select

Upload description

Let's check our MobSF dashboard to see if the scanned application is there or not.

MobSF

MobSF

As you can see, both the analyzed apk application and our data were successfully obtained using the full capability of MobSF's Rest API.

Conclusion

Congratulations, you successfully uploaded and fetched all of the APK scan results using the full power of MobSF and react js. Let's recap what we did: first, we spun up and configured the MobSF server, then we explored the Rest API docs provided by MobSf, then we configured and set up our react application and added a few third-party packages, and finally, we configured and wrote a script to upload an apk file.After that, we used the Axios package to fetch the details of the scan result, then we used bootstrap to style our application to look even nice, and finally, we ran our server and our application was totally functional and successful.

Discussion (0)