# React Native

{% hint style="success" %}
**Example**: <https://github.com/talsec/Free-RASP-ReactNative>
{% endhint %}

## 📝 Prerequisites

The freeRASP has the following prerequisites that must be met before starting.

### Android

freeRASP requires a minimum **SDK** level of **23**. React Native projects, by default, support even lower levels of minimum SDK. This creates an inconsistency we must solve by updating the minimum SDK level of the application:

* From the root of your project, go to `android` **>** `build.gradle`.
* In `buildscript`, update `minSdkVersion` to at least **23** (Android 6.0) or higher.

{% code title="android/build.gradle" %}

```gradle
buildscript {
    ext {
      minSdkVersion 23
    }
}
```

{% endcode %}

#### Raise Kotlin version

Since freeRASP 4.0.0, it is necessary to raise version of Kotlin in your project. This applies for projects running on RN < 0.77.&#x20;

* From the root of your project, go to `android` **>** `build.gradle` (or equivalent).
* In `buildscript.ext`, update `kotlinVersion` to at least **2.0.0** or higher.
* In `buildscript.dependencies`, specify the same version for`kotlin-gradle-plugin` .

```groovy
buildscript {
    ext {
        kotlinVersion = '2.0.0'
    }
    dependencies {
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.0")
    }
```

#### Enable Screenshot and Screen Recording Detection

To [detect screenshots](https://docs.talsec.app/freerasp/wiki/threat-detection/screen-capture#screenshot-detection) and [screen recordings ](https://docs.talsec.app/freerasp/wiki/threat-detection/screen-capture#screen-recording-detection), add the following permissions to your `AndroidManifest.xml` file inside the `<manifest>` root tag:

```xml
 <uses-permission android:name="android.permission.DETECT_SCREEN_CAPTURE" />
 <uses-permission android:name="android.permission.DETECT_SCREEN_RECORDING" />
```

{% hint style="warning" %}
Screenshot Detection is supported **on Android 14 (API level 34) and higher**. \
\
Screen Recording Detection is supported **on Android 15 (API level 35) and higher**.\
\
Application of **FLAG\_SECURE** on Android Window or calling `blockScreenCapture(true)` disables this callback.
{% endhint %}

To utilize active protection, you can use&#x20;

```jsx
import { blockScreenCapture } from 'freerasp-react-native';
await blockScreenCapture(true);
```

To receive whether the screen capture is blocked, you can use

```jsx
import { isScreenCaptureBlocked } from 'freerasp-react-native';
const response = await isScreenCaptureBlocked();
```

For more details about all these screen capture methods, see [screen-capture](https://docs.talsec.app/freerasp/freerasp/wiki/threat-detection/screen-capture "mention").

### iOS

freeRASP React Native plugin uses Pods. Navigate to the `ios` folder and run:

```bash
$ pod install
```

***

## 📦 Install the plugin

* Install the plugin using your preferred package manager<br>

  <pre class="language-bash" data-title="npm"><code class="lang-bash">npm install freerasp-react-native
  </code></pre>

  <pre class="language-bash" data-title="yarn"><code class="lang-bash">yarn add freerasp-react-native
  </code></pre>
* Navigate to the `ios` folder and run:<br>

  ```bash
  $ pod install
  ```

***

## ⚙️ Setup the Configuration for your App

To ensure freeRASP functions correctly, you need to provide the necessary configuration and initialize it. All required values must be filled in for the plugin to operate properly. Use the following template to configure the plugin. Detailed descriptions of the configuration options are provided[ on the API page](https://docs.talsec.app/freerasp/freerasp/integration/api#talsecconfig).

In the the entry point to your app, import freeRASP and add the code below.&#x20;

For Android apps, you must get your expected signing certificate hashes in Base64 form. You can go through[ this manual](https://docs.talsec.app/freerasp/freerasp/wiki/getting-signing-certificate-hash) to learn how to sign your app in more detail, including manual signing and using Google's Play app signing.&#x20;

FreeRASP provides a React Custom Hook that handles all required logic as registration of freeRASP, mounting and unmounting of listeners for you.

{% code title="App.tsx" %}

```tsx
import { useFreeRasp } from 'freerasp-react-native';

// app configuration
const config = {
  androidConfig: {
    packageName: 'com.awesomeproject',
    certificateHashes: ['mVr/qQLO8DKTwqlL+B1qigl9NoBnbiUs8b4c2Ewcz0k='],  // replace with your release (!) signing certificate hash(es)
    supportedAlternativeStores: ['com.sec.android.app.samsungapps'],
  },
  iosConfig: {
    appBundleId: 'com.awesomeproject',
    appTeamId: 'your_team_ID',
  },
  watcherMail: 'your_email_address@example.com', // for Security Reports, Talsec Portal, Updates
  isProd: true,
  killOnBypass: true,
};
```

{% endcode %}

{% hint style="info" %}
**Configuration Parameters**

* **`isProd`** - a boolean flag that determines whether the freeRASP integration is in the Dev or Release version. If you want to learn more about `isProd`, visit this [wiki section](https://docs.talsec.app/freerasp/freerasp/wiki/isprod-flag).
* **`killOnBypass`** - a boolean flag that enables the freeRASP in-SDK reaction to kill the application if it detects any unwanted manipulation with the callback mechanisms.
* **`watcherMail`** - By providing your watcherMail, you consent to receive security reports, product updates, and other essential communications from Talsec. [Learn more](https://docs.talsec.app/freerasp/freerasp/wiki/role-of-watchermail) about the role of `watcherMail`.
  {% endhint %}

***

## 👷 Handle detected threats

freeRASP executes periodical checks when the application is running. You can handle the detected threats using **listeners**. For example, you can log the event, show a window to the user or kill the application. See the [Threat detection](https://docs.talsec.app/freerasp/freerasp/wiki/threat-detection) in the wiki to learn more details about the performed checks and their importance for app security.

Threat reactions should be specified inside a JavaScript object.

<pre class="language-tsx"><code class="lang-tsx">// reactions for detected threats
const actions = {
  // Android &#x26; iOS
  <a data-footnote-ref href="#user-content-fn-1">privilegedAccess</a>: () => {
    console.log('privilegedAccess');
  },
  // Android &#x26; iOS
  <a data-footnote-ref href="#user-content-fn-2">debug</a>: () => {
    console.log('debug');
  },
  // Android &#x26; iOS
  <a data-footnote-ref href="#user-content-fn-3">simulator</a>: () => {
    console.log('simulator');
  },
  // Android &#x26; iOS
  <a data-footnote-ref href="#user-content-fn-4">appIntegrity</a>: () => {
    console.log('appIntegrity');
  },
  // Android &#x26; iOS
  <a data-footnote-ref href="#user-content-fn-5">unofficialStore</a>: () => {
    console.log('unofficialStore');
  },
  // Android &#x26; iOS
  <a data-footnote-ref href="#user-content-fn-6">hooks</a>: () => {
    console.log('hooks');
  },
  // Android &#x26; iOS
  <a data-footnote-ref href="#user-content-fn-7">deviceBinding</a>: () => {
    console.log('deviceBinding');
  },
  // Android &#x26; iOS
  <a data-footnote-ref href="#user-content-fn-8">secureHardwareNotAvailable</a>: () => {
    console.log('secureHardwareNotAvailable');
  },
  // Android &#x26; iOS
  <a data-footnote-ref href="#user-content-fn-9">systemVPN</a>: () => {
    console.log('systemVPN');
  },
  // Android &#x26; iOS
  <a data-footnote-ref href="#user-content-fn-10">passcode</a>: () => {
    console.log('passcode');
  },
  // iOS only
  <a data-footnote-ref href="#user-content-fn-7">deviceID</a>: () => {
    console.log('deviceID');
  },
  // Android only
  <a data-footnote-ref href="#user-content-fn-11">obfuscationIssues</a>: () => {
    console.log('obfuscationIssues');
  },
  // Android only
  <a data-footnote-ref href="#user-content-fn-12">devMode</a>: () => {
    console.log('devMode');
  },
  // Android only
  <a data-footnote-ref href="#user-content-fn-13">adbEnabled</a>: () => {
    console.log('adbEnabled');
  },
  // Android &#x26; iOS
  <a data-footnote-ref href="#user-content-fn-14">screenshot</a>: () => {
    console.log('screenshot');
  },
  // Android &#x26; iOS
  <a data-footnote-ref href="#user-content-fn-15">screenRecording</a>: () => {
    console.log('screenRecording');
  },  
  // Android only
  <a data-footnote-ref href="#user-content-fn-16">multiInstance</a>: () => {
    console.log('multiInstance');
  },
  // Android &#x26; iOS  
  timeSpoofing: () => {
    console.log('timeSpoofing');
  },
  // Android only
  locationSpoofing: () => {
    console.log('locationSpoofing');
  },
  // Android only
  unsecureWifi: () => {
    console.log('unsecureWifi');
  },
  // Android only
  automation: () => {
    console.log('automation');
  },
};
</code></pre>

## 👷 RASP Execution State Listener

freeRASP can also notify apps when initial checks are done using the raspExecutionStateActions callback:

{% code title="App.jsx/App.tsx" %}

```typescript
  const raspExecutionStateActions = {
    allChecksFinished: () => {
      console.log('allChecksFinished');
    },
  };
```

{% endcode %}

***

## 🛡️ Start freeRASP

Start freeRASP to detect threats by calling the `useFreeRasp` hook, below the created config and the callback handler:

```tsx
useFreeRasp(config, actions, raspExecutionStateActions);
```

{% hint style="info" %}
Please note that **useFreeRasp** Hook should be called **outside** **useEffect**.
{% endhint %}

When freeRASP initializes correctly, you should see `freeRASP initialized` message in the logs. Otherwise, you'll see a warning with a description of what went wrong.

{% hint style="info" %}
You can override this default behaviour by extending the **actions** object with **started** key (to change action after successful initialization), and **initializationError** key (to set up action after unsuccessful initialization)
{% endhint %}

{% hint style="info" %}
For the version you’re integrating, you can find the specific **dSYMs** for debugging in [Releases](https://github.com/talsec/Free-RASP-ReactNative/releases).
{% endhint %}

### Alternative: Initialize freeRASP in a Class component

Import methods from the freeRASP plugin:

```tsx
import {
  talsecStart,
  setThreatListeners,
  removeThreatListeners,
} from 'freerasp-react-native';
```

Override `componentDidMount()` method in the entry point to your app set listeners to threats and start freeRASP:

```tsx
async componentDidMount() {
  await setThreatListeners(actions);
  const response = await talsecStart(config);
  console.log(response); // freeRASP started
}
```

{% hint style="info" %}
*In this code snippet, `actions` is object with your reactions to threats and `config` is a freeRASP configuration object from previous parts of the readme.*
{% endhint %}

Override `componentWillUnmount()` method where you clean up the listeners:

```tsx
componentWillUnmount() {
  removeThreatListeners();
}
```

***

## 🌁 Enable source code obfuscation

The easiest way to obfuscate your app is via code minification, a technique that reduces the size of the compiled code by removing unnecessary characters, whitespace, and renaming variables and functions to shorter names. It can be configured for Android devices in `android/app/build.gradle` like:

```gradle
android {
    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
```

Please note that some other modules in your app may rely on reflection, therefore it may be necessary to add corresponding keep rules into proguard-rules.pro file.

If there is a problem with the obfuscation, freeRASP will notify you about it via `obfuscationIssues` callback.

Read more about why this is important in the[ wiki](https://docs.talsec.app/freerasp/freerasp/wiki/source-code-obfuscation).

***

## 🆔 (Optionally) Set External ID

The `externalId` allows you to send a custom identifier (such as a User ID) to the [Talsec Portal](https://my.talsec.app/). This identifier will be visible in the Dashboard, enabling you to correlate security incidents with specific users in your system.

```javascript
import { storeExternalId } from 'freerasp-react-native';

const yourCustomData = "user_123_456";

try {
    const result = await storeExternalId(yourCustomData);
    console.log("External ID successfully set:", result);
} catch (error) {
    console.error("Failed to set External ID:", error.message);
}

```

{% hint style="info" %}
**Requirements**

* **Allowed characters**: Only alphanumeric characters (a-z, A-Z, 0-9) and the following special characters: +, \_, -, /, :, =.
* If the ID contains any other characters, the promise will be rejected with an error message and the value will not be stored.
  {% endhint %}

***

## ☢️ (Optionally) Integrate freeMalwareDetection

**freeMalwareDetection** is a powerful feature designed to enhance the security of your Android application by quickly and efficiently **scanning for malicious or suspicious applications** (e.g. Android malware) based on **various blacklists and security policies**.&#x20;

It helps to detect apps with **suspicious package names, hashes, or potentially dangerous permissions**.

Visit the [freeMalwareDetection](https://docs.talsec.app/freemalwaredetection) repository to learn more about this feature! For the integration, refer to the [integration guide](https://docs.talsec.app/freemalwaredetection/integration-guide/malware-detection-configuration) for the React Native platform.

***

## 🖥️ Check Talsec Portal

Check out [data-visualisation-portal](https://docs.talsec.app/freerasp/freerasp/data-visualisation-portal "mention") and register using your [watcherMail](https://docs.talsec.app/freerasp/freerasp/wiki/role-of-watchermail) to see your data. If you integrated the SDK successfully, the application will be present **after a few hours**. The visualisations will be active later due to the bucketing mechanism.

{% hint style="warning" %}
You have to use the **same email for the Portal** as you used for the **watcherMail** parameter.
{% endhint %}

[^1]: Learn more: <https://docs.talsec.app/freerasp/wiki/threat-detection/detecting-rooted-or-jailbroken-devices>

[^2]: Learn more: <https://docs.talsec.app/freerasp/wiki/threat-detection/debugger-detection>

[^3]: Learn more: <https://docs.talsec.app/freerasp/wiki/threat-detection/emulator-detection>

[^4]: Learn more: <https://docs.talsec.app/freerasp/wiki/threat-detection/app-tampering-detection>

[^5]: Learn more: <https://docs.talsec.app/freerasp/wiki/threat-detection/detecting-unofficial-installation>

[^6]: Learn more: <https://docs.talsec.app/freerasp/wiki/threat-detection/hook-detection>

[^7]: Learn more: <https://docs.talsec.app/freerasp/wiki/threat-detection/device-binding-detection>

[^8]: Learn more: <https://docs.talsec.app/freerasp/wiki/threat-detection/secure-hardware-detection-keystore-keychain-secure-storage-check>

[^9]: Learn more: <https://docs.talsec.app/freerasp/wiki/threat-detection/system-vpn-detection>

[^10]: Learn more: <https://docs.talsec.app/freerasp/wiki/threat-detection/passcode>

[^11]: Learn more: <https://docs.talsec.app/freerasp/wiki/threat-detection/missing-obfuscation-detection-android-devices-only>

[^12]: Learn more: <https://docs.talsec.app/freerasp/wiki/threat-detection/developer-mode-detection-android-devices-only>

[^13]: Learn more: <https://docs.talsec.app/freerasp/wiki/threat-detection/adb-enabled-detection-android-devices-only>

[^14]: Learn more: <https://docs.talsec.app/freerasp/wiki/threat-detection/screen-capture#screenshot-detection>

[^15]: Learn more: <https://docs.talsec.app/freerasp/wiki/threat-detection/screen-capture#screen-recording-detection>

[^16]: Learn more:\
    [https://docs.talsec.app/freerasp/wiki/threat-detection/multi-instance-detection](https://docs.talsec.app/freerasp/wiki/threat-detection/multi-instance-detection-android-devices-only)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.talsec.app/freerasp/freerasp/integration/react-native.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
