Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
See the most frequent issues occurring during integration.
Currently, there are no commonly present issues solely for the Capacitor development platform. For more general issues or questions, visit FAQ page. You can also check out the Issues section of our GitHub repository, where you can report issues and view existing reports.
While most developers use debuggers to trace the flow of their program during its execution same tool can be attached to an application in an attempt to reverse engineer, check memory values, and steal confidential information. This method looks for specific flags to determine whether the debugger is active and offers the option to disable it.
Below are code snippets demonstrating debugger detection across various platforms:
// Android debugger detection
override fun onDebug() {
TODO("Not yet implemented")
}
// iOS debugger detection
case debugger
// Flutter
onDebug: () => print("Debugging")
// Cordova
debug: () => {
// Place your reaction here
}
// React Native
debug: () => {
// Place your reaction here
}
// Capacitor
debug: () => {
// Place your reaction here
}Explore the freeRASP wiki for practical guides on signing certificate hash, threat detection behavior, code obfuscation, and other technical details that help you understand and configure the SDK.
Welcome to the freeRASP wiki page!
This page provides additional information about the product. The main goal is to present clear and easily accessible content that will help you better understand freeRASP. We hope you find it helpful and informative.
How to Get the Signing Certificate Hash.
Information about .
Overview of .
We encourage you to explore the different sections of this wiki to gain a more comprehensive understanding of the freeRASP product and its features. If you have any questions or need further assistance, please feel free to reach out to our support team at support@talsec.atlassian.net.
See the most frequent issues occurring during integration.
The most frequent issues occurring during integration:
For more general issues or questions, visit page. You can also check out the , where you can report issues and view existing reports.
See the most frequent issues occurring during integration.
Currently, there are no commonly present issues solely for the Native iOS development platform. For more general issues or questions, visit page. You can also check out the , where you can report issues and view existing reports.
See the most frequent issues occurring during integration.
The most frequent issues occurring during integration:
For more general issues or questions, visit page. You can also check out the , where you can report issues and view existing reports.
Currently, there are no commonly present issues solely for the Capacitor development platform. For more general issues or questions, visit page. You can also check out the , where you can report issues and view existing reports.
Running an application inside an emulator/simulator allows an attacker to hook or trace program execution. For applications running inside an emulator, it is easy to inspect the system's state, reset it to a saved image, or monitor how the app operates. Keep in mind that not every emulator/simulator usage means an ongoing potential threat for the application.
Below are code snippets demonstrating emulator detection across various platforms:
The Secure Enclave and the Android Keystore system make it very difficult to decrypt sensitive data without physical access to the device. In that order, these keys need to be stored securely. freeRASP checks if the keys reside inside secure hardware.
Below are code snippets demonstrating missing hardware detection across various platforms:
Saving any sensitive data on a device without a lock / passcode makes them more prone to theft. With no user authentification device can be accessed and modified with minimal effort. freeRASP checks if the device is secured with any type of lock.
Below are code snippets demonstrating passcode detection across various platforms:
Android developer mode allows deeper system access and debugging capabilities that can bypass app security measures. Developer mode can enable settings that facilitate the installation of uncertified applications and the execution of potentially harmful code, posing significant risks to data integrity and app functionality. FreeRASP detects whether the developer mode is enabled.
Warning: This vulnerability is particularly critical on Android 12 and 13 devices with Developer Mode enabled. A local attacker with ADB shell access can execute arbitrary code within the context of any non-system app, granting them full access to the app’s private data files, AccountManager-stored credentials, and other privileged resources. This bypasses the Application Sandbox’s intended protections, which are designed to isolate app data even from device owners.
Below are code snippets demonstrating developer mode detection across various platforms:
Multi-instance refers to the ability to launch multiple instances of the same application—either intentionally (such as through app cloning or multi-user modes) or unintentionally (due to a malicious attack or system bug). Each instance may run in a separate process, which can lead to security, privacy, or data consistency issues—especially in sensitive applications like finance, messaging, or enterprise tools.
Currently, detection of multi-instance using is supported.
Below are code snippets demonstrating passcode detection across various platforms:
What is multi-instacing, why is it an issue and how to detect it?
Location spoofing is when an attacker (or malicious app) falsifies the device’s reported location or the location signals it trusts (e.g., GNSS/GPS, Wi‑Fi positioning, cellular location, or IP‑based geolocation), causing the OS and apps to receive incorrect location data.
Location spoofing in mobile apps is commonly used to bypass geofences and region locks, fake presence (e.g., on dating apps or games), create alibis (e.g., on social or parental control apps), or commit location‑based fraud (offers, check‑ins).
Below are code snippets demonstrating debugger detection across various platforms:
A lightweight, easy-to-integrate mobile Runtime Application Self-Protection (RASP) library. Detect app tampering, hooking, debugging, and reverse engineering attempts in real-time across native and cross-platform frameworks.
Protect your users from sideloaded threats. A comprehensive Android scanning module that identifies malicious apps, overlay trojans, and zero-day risks using powerful on-device behavioral heuristics and customizable blocklists.
Talsec Portal
Manage your applications, visualize real-time threat data, and generate configurations.
Comprehensive Wiki
Deep dive into specific security mechanisms and threat models.
Changelog
Track the latest SDK updates, new features, and patch notes.
Features Overview
Discover the full capabilities of the Talsec security suite.
Pricing Plans
Explore scaling options and premium enterprise features.
// Android emulator check
override fun onSimulator() {
TODO("Not yet implemented")
}
// iOS simulator detection
case simulator
// Flutter emulator and simulator detection
onSimulator: () => print("Simulator")
// Cordova emulator and simulator detection
simulator: () => {
// Place your reaction here
}
// React Native emulator and simulator detection
simulator: () => {
// Place your reaction here
}
// Capacitor emulator and simulator detection
simulator: () => {
// Place your reaction here
}// Android Keystore
override fun onSecureHardwareNotAvailable() {
TODO("Not yet implemented")
}
// iOS Secure Enclave
case missingSecureEnclave
// Flutter HW backed keystore not available and missing secure enclave detection
onSecureHardwareNotAvailable: () => print("Secure hardware not available")
// Cordova HW backed keystore not available and missing secure enclave detection
secureHardwareNotAvailable: () => {
// Place your reaction here
}
// React Native HW backed keystore not available and missing secure enclave detection
secureHardwareNotAvailable: () => {
// Place your reaction here
}
// Capacitor HW backed keystore not available and missing secure enclave detection
secureHardwareNotAvailable: () => {
// Place your reaction here
}// Android lock check
override fun onPasscode() {
TODO("Not yet implemented")
}
// iOS lock check
case passcode
// Flutter unlocked device and passcode detection
onPasscode: () => print("Passcode not set")
// Cordova unlocked device and passcode detection
passcode: () => {
// Place your reaction here
}
// React Native unlocked device and passcode detection
passcode: () => {
// Place your reaction here
}
// Capacitor unlocked device and passcode detection
passcode: () => {
// Place your reaction here
}// Android Developer mode detection
override fun onDevMode() {
TODO("Not yet implemented")
}
// Flutter Developer mode detection
onDevMode: () => print("Developer mode detected")
// Cordova Developer mode detection
devMode: () => {
// Place your reaction here
}
// React Native Developer mode detection
devMode: () => {
// Place your reaction here
}
// Capacitor Developer mode detection
devMode: () => {
// Place your reaction here
}// Android location spoofing check
override fun onLocationSpoofing() {
TODO("Not yet implemented")
}
// Flutter location spoofing detection
onLocationSpoofing: () => print("Location Spoofing detected")
// Cordova location spoofing detection
locationSpoofing: () => {
// Place your reaction here
}
// React Native location spoofing detection
locationSpoofing: () => {
// Place your reaction here
}
// Capacitor location spoofing detection
locationSpoofing: () => {
// Place your reaction here
}Every application can be easily modified and then resigned by an attacker. This process is known as application repackaging. There may be many reasons for application repackaging, whether it's adding new code, removing app protections, or bypassing app licensing. A modified/tampered application is often distributed using third-party stores or other side channels.
Talsec uses various checks to detect whether the application was tampered (e.g., changed package name, signing hash).
Make sure that you have integrated Talsec correctly (e.g., signing certificate hash). Otherwise, this check might be triggered very often.
Below are code snippets demonstrating app tampering detection across various platforms:
// Android tampering
override fun onAppIntegrity() {
TODO("Not yet implemented")
}
// iOS signature
case signature
// Flutter tampering and signature detection
onAppIntegrity: () => print("App integrity")
// Cordova tampering and signature detection
appIntegrity: () => {
// Place your reaction here
}
// React Native tampering and signature detection
appIntegrity: () => {
// Place your reaction here
}
// Capacitor tampering and signature detection
appIntegrity: () => {
// Place your reaction here
}App Data Migration detection identifies situations where application data is restored, transferred, and reused on a different physical device. This behavior can indicate that sensitive application state, credentials, or tokens have been migrated outside the original environment.
A new install of the application (e.g. in case of buying a new device and transfer the apps) is not detected.
On iOS, deviceID detects whether the device identifier has changed. It is triggered after the app is reinstalled if no other apps from the same vendor are installed. The value can also change when you install test builds with Xcode or distribute the app ad hoc.
Below are code snippets showing how this feature is reported across various platforms:
The freeRASP SDK contains public API, so the integration process is as simple as possible. Unfortunately, this public API also creates opportunities for the attacker to interrupt freeRASP SDK operations or modify the custom code in threat callbacks. All internal freeRASP classes are already obfuscated, so it is simple to distinguish freeRASP sources from the rest of the application code during the static analysis. In order for freeRASP to be as effective as possible, it is highly recommended to apply obfuscation to the final package/application, making the public API more difficult to find and also to make it partially randomized for each application so it cannot be automatically abused by generic hooking scripts.
Please follow the integration guide of your platform for more information about how to obfuscate the app.
Below are code snippets demonstrating missing obfuscation detection across various platforms:
// Android
override fun onObfuscationIssues() {
TODO("Not yet implemented")
}
// Flutter
onObfuscationIssues: () => print("Obfuscation issues")
// Cordova
obfuscationIssues: () => {
// Place your reaction here
},
// React Native
obfuscationIssues: () => {
// Place your reaction here
},
// Capacitor
obfuscationIssues: () => {
// Place your reaction here
},Detecting a running VPN service on mobile devices is critical for security-sensitive applications, as it can indicate potential privacy and security risks. VPNs can obscure the user’s actual IP address and route data through servers potentially under external control, which might interfere with geographical restrictions and bypass network security settings intended to protect data integrity and confidentiality. Such anonymising features could be exploited to mask illicit activities, evade compliance controls, or access services from unauthorised regions. FreeRASP checks whether the system VPN is enabled.
Below are code snippets demonstrating system VPN detection across various platforms:
// Android system VPN detection
override fun onSystemVpn() {
TODO("Not yet implemented")
}
// iOS system VPN detection
case systemVPN
// Flutter system VPN detection
onSystemVPN: () => print("System VPN detected")
// Cordova system VPN detection
systemVPN: () => {
// Place your reaction here
}
// React Native system VPN detection
systemVPN: () => {
// Place your reaction here
}
// Capacitor system VPN detection
systemVPN: () => {
// Place your reaction here
}ADB (Android Debug Bridge) Enabled is a power-user feature activated through the "USB Installation" option in the Developer settings. This state can signal potential security risks, such as apps being installed via USB, the device being connected to a man-in-the-middle (MiTM) proxy, or the device running as an emulator.
When ADB is enabled (either via USB or Wireless/Wi-Fi), it allows extensive access to the device, including pulling and pushing files, issuing shell commands, working with the activity manager (e.g., starting activities, broadcasting intents, modifying hidden Android settings, attaching a profiler to a process, or making an app debuggable), and managing packages. Additionally, it enables capturing screenshots, recording the screen, and other actions that can compromise app security and user privacy.
FreeRASP monitors and detects whether any form of ADB debugging is active on the device, providing protection against both physical and network-based debugging attempts.
Below are code snippets demonstrating ADB enabled detection across various platforms:
// Android ADB enabled detection
override fun onAdbEnabled() {
TODO("Not yet implemented")
}
// Flutter ADB enabled detection
onADBEnabled: () => print("ADB Enabled detected")
// Cordova ADB enabled detection
adbEnabled: () => {
// Place your reaction here
}
// React Native ADB enabled detection
adbEnabled: () => {
// Place your reaction here
}
// Capacitor ADB enabled detection
adbEnabled: () => {
// Place your reaction here
}// Android device binding check
override fun onDeviceBinding() {
TODO("Not yet implemented")
}
// iOS device binding methods
case deviceChange
case deviceID
// Flutter
// device binding and device change detection
onDeviceBinding: () => print("Device binding")
// device ID
onDeviceID: () => print("Device ID") // iOS only
// Cordova
// device binding and device change detection
deviceBinding: () => {
// Place your reaction here
}
// device ID
deviceID: () => { // iOS only
// Place your reaction here
}
// React Native
// device binding and device change detection
deviceBinding: () => {
// Place your reaction here
}
// deviceID
deviceID: () => { // iOS only
// Place your reaction here
}
// Capacitor
// device binding and device change detection
deviceBinding: () => {
// Place your reaction here
}
// deviceID
deviceID: () => { // iOS only
// Place your reaction here
}// Android multi instance check
override fun onMultiInstance() {
TODO("Not yet implemented")
}
// Flutter multi instance detection
onMultiInstance: () => print("Multi instance detected")
// Cordova multi instance detection
multiInstance: () => {
// Place your reaction here
}
// React Native multi instance detection
multiInstance: () => {
// Place your reaction here
}
// Capacitor multi instance detection
multiInstance: () => {
// Place your reaction here
}freeRASP for React Native is a bare React Native plugin. When installing freeRASP into a project that uses Expo SDK, there may be extra configuration needed.
To integrate freeRASP into the Expo projects, follow the instructions for React Native. After that, continue on this page.
We provide a plugin config that sets up the dependencies of freeRASP without the need to eject the Expo project. It is recommended to use the plugin config. However, manual setup is also possible.
Add the plugin config to your app.json and specify the minSdkVersion (use at least 23).
"plugins":[
[
"freerasp-react-native/app.plugin.js",
{
"android":{
"minSdkVersion":"23",
}
}
]
]Increase minSdkVersion
This can be done in two ways:
update the minSdkVersion property directly in android/build.gradle, or
use expo-build-properties plugin, which updates the property in the prebuild phase. .
Add maven dependency
open android/build.gradle (if you don't see the android folder, run npx expo prebuild -p android in terminal to create it)
add the following dependency under allprojects > repositories
This guide provides step-by-step instructions for getting the Base64-encoded signing certificate hash for your Talsec configuration.
All Android apps must be signed with a digital certificate before installation. The signing certificate SHA-256 hash in Base64 form - which we'll refer to as the hash for short, also known as a fingerprint -is the certificate's unique identifier, crucial for security and integrity. The Talsec SDK uses this hash for app tampering detection.
The first step is to determine which app signing method you're using.
If you're using Google Play App Signing, a very common practice for Android App Bundles (AAB) distribution, your upload key and distribution key are distinct. So, be sure to use the app signing certificate key from the Google Play Console. Proceed with the Google Play App Signing Method.
If you're managing your own signing key (Manual App Signing), you'll need to generate the hash yourself from your keystore, proceed with the Manual App Signing Method.
Continue with the method that matches your signing process ➡️
Google manages your app’s signing key and uses it to sign your application.
Watch the video walkthrough or continue with the step-by-step guide below:
To retrieve the SHA-256 hash in Google Play Console, follow these steps:
Open your app and navigate to Test and release > App integrity > Play app signing. Click on "Settings":
Under App signing key certificate, locate the "SHA-256 certificate fingerprint" (fingerprint = hash):
An example SHA-256 hash looks like this:
88:8c:7f:02:d6:2e:ed:3a:53:bb:9c:a6:6b:82:5c:0d:78:a8:e5:b6:b2:11:28:bc:f5:ac:67:c8:e0:a3:7c:5aYou'll need this value for the next step.
Convert the hash to Base64 format, as the SDK requires it in this format. Follow the steps in ➡️
You sign your Android application (APK) yourself using a private key that's stored in a keystore.
A common mistake is using the wrong signing key, which will cause the Talsec SDK to flag your app as a security risk. To avoid this, you must use the keystore that signs your app for public release.
Here’s the difference:
Debug Keystore: Created automatically by Android Studio. DO NOT USE THIS ONE. It is insecure and only for development purposes.
Release Keystore: The secure keystore you create and manage. USE THIS ONE. It's what permanently ties your app to you as the developer.
If you haven't created a release keystore yet, the will walk you through the process.
You can use tools like keytool or apksigner to retrieve certificate details, including the SHA-256 hash. Choose whichever is most convenient: get the hash from your signed release APK or directly from your release keystore:
This command will output the certificate details, including the SHA-256 hash, which will look something like this:
You'll need this value for the next step.
Convert the hash to Base64 format, as the SDK requires it in this format. Follow the steps in ➡️
To convert the hash to Base64 form, use an online tool like Base64 Encode:
After conversion, you'll receive a final Base64 string like this:
iIx/AtYu7TpAu5cma4JdDXio5bayFSi89axnyOCjfFo=Your work here is done. Insert it into your Talsec configuration.
Example of a Talsec freeRASP configuration in Flutter with the resulting string:
Learn how freeRASP detects rooted or jailbroken devices, emulators, hooks, app tampering, and other runtime threats, and how to choose the right in‑app response for your mobile security use case.
freeRASP performs several security checks to detect potential threats during runtime, each targeting specific attack vectors. Developers and business owners can determine the appropriate response to these incidents, whether by terminating the application, alerting the user, logging the incident details, or choosing to ignore it.
For a detailed explanation of each security check and guidance on selecting an appropriate response, please refer to the individual threat descriptions in the subsections. Remember, the ideal response will depend on your application's specific security needs and use cases.
(formerly Device Binding)
[Android devices only]
(Keystore/Keychain secure storage check)
[Android devices only]
[Android devices only]
(Screenshot and screen recording detection, block screenshot capture)
[Android devices only]
Rooting/jailbreaking is a technique of acquiring privileged control over the operating system of an Android/iOS device. While most users root their devices to overcome the limitations put on the devices by the manufacturers, it also enables those with malicious intent to abuse privileged access and steal sensitive information. Many different attack vectors require privileged access to be performed. Tools such as Magisk, Shamiko, Shad0w or Dopamine can hide privileged access and are often used by attackers.
Learn more about the root detection and jailbreak detection.
freeRASP uses various checks to detect whether the device is rooted or jailbroken. It detects not only rooted/jailbroken devices but also looks for the presence of their hiders (e.g., Magisk Hide, Shamiko, Shad0w, Dopamine).
From our data, around 0.5% - 1% of devices have traces of rooting and jailbreaking. Keep that in mind when choosing the appropriate reaction type.
Below are code snippets demonstrating root and jailbreak detection across various platforms:
// Root detection on Android
override fun onPrivilegedAccess() {
TODO("Not yet implemented")
}
// iOS jailbreaking detection
case jailbreak
// Flutter root and jailbreak detection
onPrivilegedAccess: () => print("Privileged access")
// Cordova root and jailbreak detection
privilegedAccess: () => {
// Place your reaction here
}
// React Native root and jailbreak detection
privilegedAccess: () => {
// Place your reaction here
}
// Capacitor root and jailbreak detection
privilegedAccess: () => {
// Place your reaction here
}The application can be analysed or modified even though its source code has not been changed, applying a technique known as hooking. This technique can be used to intercept system or application calls and then modify them. An attacker can exploit this by inserting new (often malicious) code or by altering existing one to obtain personal client data. The most well-known hooking frameworks are Frida, Xposed, or Cydia Substrate.
Below are code snippets demonstrating hook detection across various platforms:
// Android hook check
override fun onHooks() {
TODO("Not yet implemented")
}
// iOS hook detection
case runtimeManipulation
// Flutter hook and runtime manipulation detection
onHooks: () => print("Hooks")
// Cordova hook and runtime manipulation detection
hooks: () => {
// Place your reaction here
}
// React Native hook and runtime manipulation detection
hooks: () => {
// Place your reaction here
}
// Capacitor hook and runtime manipulation detection
hooks: () => {
// Place your reaction here
}Unsecure Wi‑Fi describes a situation where a device is connected to an open or poorly protected wireless network (for example an open hotspot, weak WPA, or a rogue access point), allowing an attacker to observe, intercept, or alter the device’s traffic and network behavior so the OS and apps communicate over an untrusted link.
Attackers can use unsecured Wi‑Fi to perform man‑in‑the‑middle attacks such as:
Eavesdrop on unencrypted traffic to harvest credentials and session cookies
Hijack or replay active sessions to gain unauthorized access
Present forged or untrusted certificates to perform HTTPS interception
Below are code snippets demonstrating unsecure wifi detection across various platforms:
Integrate freeRASP into your mobile app step by step, from prerequisites and SDK setup to threat callbacks, obfuscation.
The general flow of the integration can be decomposed into the following steps:
Conforming to the prerequisites, e.g. setting up Android minSdkVersion.
Adding the dependency.
Setting up the configuration for the application, e.g. package name or whether it is production or not (see ).
Handling the detected threats (callbacks).
Starting the SDK.
Enabling the source code obfuscation.
Registering in to see the data from your apps and compare it to global statistics.
Become familiar with and .
Looking at , to provide an additional layer of protection by detecting malware or suspicious applications.
Looking at if you are interested in more advanced solutions to protect your application and business.
Reading through and , if you are interested in more detailed information about internal workings.
The Dev version is intended for development purposes. It allows you to work on your app without interference from security features that could disrupt the process, e.g. if you would implement killing of the application on the debugger callback.
The Release version is meant for production and must always be used for your published app. It enables all security protections provided by freeRASP.
To configure this, set the isProd flag in freeRASP:
Release: isProd = true
Dev: isProd = false
⚠️Dev version disables some detections which won't be triggered during the development process:
Emulator/Simulator
Debugging
Tampering/Repackaging
Unofficial store/source
Choose the relevant section based on your app development platform:
freeRASP is a free mobile app protection SDK that detects rooting, jailbreak, hooking, tampering, emulators, and other runtime threats,and real-time security analytics via Talsec Portal.
freeRASP is a lightweight and easy-to-integrate mobile security library designed to detect potential threats during the application's runtime. It contains multiple security checks, each aimed to cover possible attack vectors to ensure a high level of application security.
freeRASP provides detection of potentially dangerous behaviour, including the following:
Using
See the most frequent issues occurring during integration.
The most frequent issues occurring during integration:
For more general issues or questions, visit page. You can also check out the , where you can report issues and view existing reports.
We would like to reflect on a few performance and telemetry-related topics that emerge occasionally.
Common Questions:
Why does it take too long to finish all the checks?
How to know when all checks are finished?
When are telemetry data transmitted?
Time spoofing attack is when an attacker (or malicious app) manipulates the device's clock or its time source (e.g. network, GPS, or NTP) to cause system apps to behave incorrectly.
Time spoofing in mobile apps is often used to extend or reuse expired tokens, OTPs, or sessions, bypass trial periods and usage quotas, and skip waiting or cooldown times for time‑restricted features, giving attackers or unauthorised users continued access or unfair advantages.
Below are code snippets demonstrating time spoofing detection across various platforms:
There are two possible values for this flag:
true
Indicates the Release version.
This is the default value when undefined.
The App Blocklists layer evaluates installed applications against a locally cached list of malicious identifiers. This deterministic check matches either the exact Package Name or the SHA-256 Hash of the installed application.
You can configure both types of identifiers simultaneously, or use only one by omitting the unused parameter.
This check extracts the application's unique package identifier (e.g., com.malicious.stealer) and compares it against a predefined list.
Execution: Performs a direct string comparison against the OS package manager's inventory.
Third-party services and APIs can authenticate the app before granting access.
false
Indicates the Dev version.
The Dev version of freeRASP is intended for usage during the development phase. It serves the purpose of segregating development and production data, as well as disabling certain checks that are not applicable during the development process. These checks include:
Emulator usage (onSimulator),
Debugging (onDebug),
Signing (onAppIntegrity),
Unofficial store (onUnofficialStore),
Obfuscation issues (onObfuscationIssues),
Developer mode (onDevMode),
ADB Enabled (onADBEnabled).
implementation 'com.aheaditec.talsec.security:TalsecSecurity-Community:9.6.0-NO_DB'Incidents that are triggered during the development (integration & testing) won't happen to a majority of users in the production.
Callbacks can be invoked slower if the freeRASP backend endpoint is overloaded. Data collection takes precedence. However, do not worry; the application will function as intended, and only callbacks might be a little delayed.
freeRASP's threat detection operates asynchronously and continuously. The Talsec.start(...) function merely initiates monitoring; it does not perform a synchronous, one-time scan that returns all results immediately. Actual threat detections are reported over time via callbacks.
freeRASP works smoothly in production, but it may be tricky to understand all the freeRASP concepts during development. During the integration and testing of the freeRASP, you may have observed that it took longer than expected to get results for all threats (callbacks). You want to get results quickly, respond to threats effectively, and ensure there is no noticeable jankiness in the UI interactions.
freeRASP has to do a lot of work once started. The cold boot is a really intensive moment when all detections must be performed, telemetry data transmitted, and callbacks to your app must be delivered (in this order).
Talsec team efforts and community contributions allow freeRASP to improve the performance and security trade-offs continually by tuning the asynchronous processes, network activity, and internal business logic. Like that time when the internal detector ordering was reworked to significantly speed evaluation based on this reported issue and the telemetry insights about the speed of detectors 👌.
Remember the phrase "It is darkest before the dawn"? The integration and testing of freeRASP are inherently accompanied by unintentional threat callbacks invoked by incorrect provisioning of the app's signature (appIntegrity callback), using a simulator for development, an unofficial store (because you haven't published it yet), and others. We've all been there.
It may also seem disconcerting to see that it takes too long until the last expected threat callback invokes. Yet, keep in mind that in production, these incidents won't happen for the genuine unaltered apps run in normal conditions. The performance impact will be negligible. On the contrary, the comfort of a potential attacker and performance degradation in adverse conditions is acceptable.
freeRASP collects security diagnostics data (read more in User Data Policies) in accordance with the Fair Usage Policy. Every detected threat is immediately synchronously logged to a common freeRASP backend. Latencies inflicted by the overload of the endpoint are unfortunate, but we continuously improve and scale as much as possible.
freeRASP is designed to provide continuous, real-time mobile application security by operating asynchronously in the background. Unlike traditional security scans that might perform a one-time check and deliver all results synchronously, freeRASP constantly monitors for potential threats. When you call Talsec.start(...), it does not execute an immediate, comprehensive scan that finishes and returns a full snapshot of your app's security status. Instead, this function simply initiates the monitoring service, allowing freeRASP to begin its ongoing vigilance.
Due to this asynchronous nature, any immediate attempt to retrieve the security status after Talsec.start(...) is called will likely yield an outdated result. Threat detections happen over time, in the background, and freeRASP communicates these detections through callbacks. These callbacks are functions you define that get triggered when a specific threat (such as a debugger being attached or a screenshot detected) is identified. It is these callbacks that are responsible for updating your application's understanding of the current security state.
It takes some time for freeRASP to actually detect threats and trigger its corresponding callbacks to report them, the callback solution provided for all freeRASP flavors ensures an accurate reflection of freeRASP's ongoing, dynamic threat detections.
// Android unsecure wifi detection
override fun onUnsecureWifi() {
TODO("Not yet implemented")
}
// Flutter unsecure wifi detection
onUnsecureWifi: () => print("Multi instance detected")
// Cordova unsecure wifi detection
unsecureWifi: () => {
// Place your reaction here
}
// React Native unsecure wifi detection
unsecureWifi: () => {
// Place your reaction here
}
// Capacitor unsecure wifi detection
unsecureWifi: () => {
// Place your reaction here
}Open network could be considered as safe, if VPN is enabled as well. You can detect active VPN using freeRASP.


// Android timeSpoofing check
override fun onTimeSpoofing() {
TODO("Not yet implemented")
}
// iOS timeSpoofing detection
case timeSpoofing
// Flutter time spoofing detection
onTimeSpoofing: () => print("Time spoofing detected")
// Cordova time spoofing detection
timeSpoofing: () => {
// Place your reaction here
}
// React Native time spoofing detection
timeSpoofing: () => {
// Place your reaction here
}
// Capacitor time spoofing detection
timeSpoofing: () => {
// Place your reaction here
}This project is provided as freemium software, i.e. there is a fair usage policy that imposes some limitations on the free usage. The SDK software consists of open-source and binary parts, which is the property of Talsec. The open-source part is licensed under the MIT License - see the LICENSE file on GitHub for details.
During build time, the SDK obtains a cached license token bound to your application/library package name/namespace and version. During the build process it outputs a clear breakdown of this setup directly to your console, for example:
============================================================
Talsec Plugin Configuration
============================================================
- Resolving default project config
- Project type: Application
- Package/namespace: com.example.app
- Version name: 1.0.0
- Free/Community plan
- SDK config: FreeConfig(sdkVersion=19.3.0, offlineToken=, platform=)
- Talsec plugin applied successfully
============================================================
License Check
============================================================
- Using online status
- License status: ALLOWEDif not already configured, add also:
"plugins":[
[
"freerasp-react-native/app.plugin.js",
{
"android":{
"R8Version":"8.3.37"
}
}
]
]echo "88:8C:7F:02:D6:2E:ED:3A:53:BB:9C:A6:6B:82:5C:0D:78:A8:E5:B6:B2:11:28:BC:F5:AC:67:C8:E0:A3:7C:5A" | tr -d ':' | xxd -r -p | base64maven { url 'https://www.jitpack.io' }maven { url "https://europe-west3-maven.pkg.dev/talsec-artifact-repository/freerasp" }Developer mode
ADB Enabled
Make sure that you use the Release version for the production.
Reverse engineering attempts.
Running hooking frameworks (e.g., Frida, Xposed or Shadow) and UI automation.
Tampering or repackaging the application.
Installing the app through untrusted methods/unofficial stores.
Running the app in various emulators or on device with unlocked bootloader.
Detect fake clones and multiinstancing (Parallel Space)
Screenshot and screen recording attempts.
Reactions to various attacks and detected security threats via an API (callback mechanism).
Simple integration.
System VPN , Location (GPS) Spoofing, Time Spoofing detections.
ADB, Developer Mode, USB debugging detections.
No significant effect on the app performance.
Data visualization with real-time security insights, global benchmarks, and detailed analytics
Weekly security report via email indicating the security status of devices and app integrity.
Fulfills requirements.
Limits of Fair Usage Policy (free up to 100k devices).
Data collection from your app to Talsec DB.
Security protections:
basic protection against root/jailbreak (including Magisk, Dopamine),
basic runtime reverse engineering controls,
basic runtime integrity controls.
No overlay and accessibility services misuse protection.
Access real-time security insights, global benchmarks, and detailed analytics!
📊 Real-Time Threat Monitoring: Gain insights into threat counts, types, and occurrences over time.
📈 Global Benchmarking: Benchmark your app's security against global statistics.
📚 Stay informed: Read the latest articles and documentation on app security best practices.
freeRASP is currently supported for:
🤖 Android smartphones, tablets, emulators, Android TVs, Wear OS, Android Auto
🍎 iPhones, iPads, simulators

Detection Constraint: This evaluation strictly matches the exact package name string. It does not detect malicious applications that have been repackaged or distributed under a different package identifier.
Result Flag: A positive match triggers the blocklist reason. This flag takes absolute precedence: it overrides any permission or installation source heuristics and immediately halts further evaluation for that specific application.
This check calculates the SHA-256 hash of the target application's entire APK file and compares it against a predefined list.
Execution: Reads the application's APK file from the device's storage to compute the cryptographic hash.
Result Flag: A positive match triggers the blocklist reason and immediately halts further evaluation for that specific application.
Performance Consideration
Defining at least one hash in your configuration increases the total duration of the background scanning process, as the SDK must perform read operations on the binary files of installed applications.
keytool -printcert -jarfile app.apk
// OR:
apksigner verify --print-certs app.apkSHA256: 88:8C:7F:02:D6:2E:ED:3A:53:BB:9C:A6:6B:82:5C:0D:78:A8:E5:B6:B2:11:28:BC:F5:AC:67:C8:E0:A3:7C:5A

Description of the freeRASP API
TalsecConfigSpecifies configuration for your app. See the table below for detailed description of the attributes.
appBundleIds
[String]
public static func start(config: TalsecRuntime.TalsecConfig)
The method used to start freeRASP's audit.
public static func blockScreenCapture(enable: Bool, window: UIWindow)
The method blocks the screen capture in specific UIWindow.
public static func isScreenCaptureBlocked(in window: UIWindow) -> Bool
The method returns whether the screen capture is blocked in specific UIWindow.
public static func storeExternalId(externalId: String)
The method stores an externalId into the logs for data collection.
func threatDetected(_ securityThreat: TalsecRuntime.SecurityThreat)
Notifier about detected threats.
func onAllChecksFinished()
Notifier about finished threats
Provides all types of threats detected by freeRASP. Read more about the meaning of the threats in the .
signature
jailbreak
debugger
See the most frequent issues occurring during integration.
The most frequent issues occurring during integration:
For more general issues or questions, visit FAQ page. You can also check out the Issues section of our GitHub repository, where you can report issues and view existing reports.
Learn Your Security Posture, Detect Threats, and Benchmark Your App
Access real-time security insights, global benchmarks, and detailed analytics!
Talsec Portal is a centralized dashboard that visualizes the security data collected by freeRASP from your app, giving you real-time insights into threats, incidents, and benchmarks—so if you're using freeRASP, this is where your app's security intelligence lives.
📊 Real-Time Threat Monitoring: Gain insights into threat counts, types, and occurrences over time.
📈 Global Benchmarking: Benchmark your app's security against global statistics.
📚 Stay informed: Read the latest articles and documentation on app security best practices.
Details about incidents:
Details about devices:
OS version
Screen lock
Biometrics
Hardware-backed Keystore
Real-time activity logs from the application, showing ongoing threats.
Visit the .
Run through the onboarding wizard and explore demo data.
Discover insights using demo applications and global security statistics.
Click on Login, then Sign Up.
Use the email address () associated with your TalsecConfig.
Create an Organization.
Now, you can view data for your applications. You can invite other users to your organization to see your data (see Organization Settings). The users can also add their applications to your organization to share their data.
The freeMalwareDetection SDK enables your Android application to identify potentially harmful applications installed on the same user device.
The SDK evaluates the device ecosystem using on-device metadata analysis — including app hash-based and package name-based blocklists, requested app permissions, and the source of installation. All scanning runs entirely on the device, ensuring that no application inventory or user data is ever transmitted to external servers.
It operates asynchronously in the background to avoid impacting your app's performance. High-risk findings are reported directly to your application via callbacks, allowing you to implement custom, context-aware security logic.
The Android application ecosystem and distribution models allow attackers to distribute malicious apps (often requesting sensitive permissions) designed to exploit or intervene in other applications on the device. Users are frequently tricked into sideloading these applications from untrusted sources via social engineering.
Such malware is often created and distributed specifically to target high-value applications. The freeMalwareDetection SDK defends against these threats by analyzing metadata and heuristic signals — evaluating requested permissions, installation sources, and known blocklists — entirely on the device, with no internet connection required.
To ensure a secure environment, the freeMalwareDetection SDK is specifically engineered to identify apps that facilitate activities such as:
Remote Access Trojans (RATs) & Overlays: Applications requesting aggressive permission sets to control the device remotely, draw fake UI layers (e.g., login screens) over your application, or read the content of the screen.
Communication Interception: Apps designed to make or accept calls, intervene in network communications, or act as SMS stealers to intercept incoming 2FA codes.
Accessibility Abuse & Keylogging: Malicious apps abusing Android Accessibility Services to autonomously click buttons on behalf of the user, approve background transactions, or log keyboard inputs.
To tackle these complex threats without compromising your app's UX, privacy, or battery life, the SDK provides the following core capabilities:
Customizable Blocklists: Easily define and manage multiple types of blocklists (e.g., hash-based or package name-based) to tailor malware detection to your specific threat model.
Asynchronous Scanning: All evaluations are performed in a low-priority background thread, ensuring minimum impact on your application's foreground performance.
100% On-Device Privacy: All scanning is completely self-contained. No app inventory, hashes, or behavioral data leaves the device.
The bootloader is the first component that runs when a device powers on, and a locked bootloader is the foundation of Android's Verified Boot and hardware root of trust. Bootloader detection identifies when the device bootloader is unlocked or when Verified Boot is otherwise compromised, meaning the device can no longer be trusted. The check relies on hardware-backed Key Attestation (Root of Trust) rather than easily spoofable system properties.
Attackers unlock the bootloader or weaken Verified Boot to:
Install custom firmware or a custom ROM, disabling OS-level security guarantees.
Gain root access and bypass integrity protections, allowing tampering with the app and other apps' data.
Prepare the environment for further tampering and dynamic analysis.
Below are code snippets demonstrating bootloader detection:
The freeRASP contains public API so that the integration process is as simple as possible. Unfortunately, this public API also creates opportunities for the attacker to use publicly available information to interrupt freeRASP operations or modify your custom reaction implementation in threat callbacks. In order for freeRASP to be as effective as possible, it is highly recommended to apply obfuscation to the final package/application, making the public API more difficult to find and also partially randomized for each application so it cannot be automatically abused by generic hooking scripts.
The majority of Android projects support code shrinking and obfuscation without any additional need for setup. The owner of the project can define the set of rules that are usually automatically used when the application is built in the release mode. For detailed guidance, explore the official documentation through these links: first reference and second reference.
Explore obfuscation, its types, and Talsec's practical approach—balancing developer experience, app performance, and attack resistance while minimizing drawbacks and ensuring cost-efficient mobile app security:
Automation detection identifies when the application is being controlled, analyzed, or interacted with by automated testing frameworks (specifically targeting Appium and UI Automator). This describes a situation where software, rather than a human, is driving the application's UI.
Attackers use automation tools to simulate user actions at high speed and scale to perform attacks such as:
Bot Farms: Automating actions like account creation, voting, or transaction execution to manipulate platform metrics or defraud the system.
Data Scraping: Automatically navigating the app to extract proprietary data, content, or user information.
Dynamic Analysis: Rapidly probing the application logic and UI flows to discover vulnerabilities or bypass security checks.
Below are code snippets demonstrating automation detection:
A valid business email is your key to the Talsec Portal and the critical security intelligence for your application. This is where your freeRASP data comes to life.
Don't use example or throw-away email. Enter your business email to ensure the access, security reports, and important product announcements.
We need to ensure that critical security information reaches the right person—or team—responsible for your app.
Invite Your Team: The business email you provide serves as the foundation for your Organization within the Talsec Portal. Once established, you can invite other developers, security analysts, and managers to a centralized dashboard.
Prevent Missed Threats: Imagine a new, widespread attack targeting apps like yours. A throwaway email address means you will miss the security alert, leaving your application and users vulnerable.
Secure Authentication: A valid email is our primary method for verifying your identity & app ownership to ensure that only authorized personnel can access your app's sensitive security data on the .
It’s Your Professional Identity: We treat you as a professional partner. A business email helps us to establish a proper communication channel with you.
Once you have successfully integrated the freeMalware Detection module and configured your detection settings, you should verify your setup.
To safely test the integration without exposing your development device to real malware, download our official test samples below. These APKs are completely harmless but are specifically designed to trigger the detection engine.
Once downloaded and sideloaded onto your test device, observe the malware callback. Based on your configuration, you can expect the following:
Detection Trigger: These samples request highly sensitive permissions (e.g., READ_SMS, BIND_ACCESSIBILITY_SERVICE) and are installed from outside a trusted source.
Expected Flags: The callback will report these applications with one or more of the following reasons:
installSource — the application was sideloaded from an untrusted installer.
suspiciousPermission — the application requests dangerous permission combinations matching your configured sets.
blocklist
Talsec is an academic-based and community-driven mobile security company. We deliver in-App Protection and a User Safety suite for Fintechs. We aim to bridge the gaps between the user's perception of app safety and the strong security requirements of the financial industry.
Talsec offers a wide range of security solutions, such as App and API protection SDK, monitoring services, and the User Safety suite. You can check out the offered products on our web.
Give us a ⭐: GitHub freeRASP
Follow to stay up to date with the news at Talsec:
Read articles about security issues and their prevention:
⚡️ Quick Start: AI-Assisted freeRASP Integration with Curated Prompt
This curated AI prompt is designed to get the freeRASP into your app to save you time. The AI cannot make security decisions for you.
➡️ Open your AI coding assistant & your IDE
➡️ Proceed with steps related to your AI coding assistant (see tabs below)
⚠️ Finally, read again and manually configure TalsecConfig and threat reactions
If you want to learn about the differences between freeRASP and BusinessRASP+, you’re in the right place. On this page, we’ll explore the key features and benefits of each option, compare their functionalities, and highlight how the BusinessRASP+ subscription can offer enhanced capabilities and support compared to the freeRASP plan. By the end, you’ll have a clear understanding of which solution best meets your needs and how to make the most of it.
freeRASP is a freemium product, which means there are . For using freeRASP, please refer to the .
and are premium products with a subscription model (which includes SW licenses, SLA, maintenance updates, and more) for SDKs. It is not SaaS, which means we don't introduce any dependency on third-party web services for your mobile solution.
Talsec doesn't collect any customer data within RASP+, while freeRASP SDK sends the diagnostical information to Talsec servers to provide clients with regular security reports and improve the product. You should consider adding Talsec to the list of Data Processors in case of freeRASP usage.
Here are the top 10 benefits of choosing a Talsec RASP+ Business subscription, which includes an SDK license, SLA, and additional services, compared to the freeRASP option.
For any questions, please refer to our or schedule a call with us by choosing a time slot on
Before configuring the freeMalware Detection module, ensure the application environment meets the following baseline technical prerequisites.
The freeMalware Detection module operates as an extension of the core security suite and cannot function standalone. You must complete the standard integration for your framework before proceeding.
By default, the detection engine successfully evaluates all standard, executable applications (packages with a MAIN
The freeMalwareDetection SDK utilizes a Defense-in-Depth architecture. Because no single scanning methodology can identify every type of threat without generating excessive false positives, the device environment is evaluated across multiple distinct analytical layers. This section documents the specific mechanisms the engine uses to evaluate installed applications.
The detection pipeline operates through two consecutive stages, scaling from fast, deterministic checks to complex, behavioral intelligence:
Fast matching of installed applications against your defined lists of forbidden package names and SHA-256 hashes.
Understand the freeRASP and freeMalwareDetection Fair Usage Policy (FUP), including free usage limits, data collection rules, and when you must upgrade to a commercial Talsec subscription.
& Fair Usage Policy
Version Number: 1.1
Effective Date: October 13, 2025
This Fair Usage Policy (“Policy”) is incorporated by reference into the Agreement and governs the permitted use of Talsec’s freeRASP (the “Service”) provided by Lynx SFT s.r.o. (“Talsec”, “Provider”, “we”, “us”, or “our”). By utilizing the Service, the Customer (“you”, “your”) agrees to abide by this Policy.
At Talsec, our commitment goes beyond just providing strong security solutions. We believe in continuously evolving our offerings by actively listening to community feedback and responding to the unique needs of developers. Our goal is not only to protect your applications but also to ensure that your insights and experiences shape our products.
We value your input because we understand that secure and effective development tooling is built through collaboration. Your voice, as a developer, is crucial to making our solutions more robust, dev-friendly, and aligned with real-world challenges.
We strive to deliver a flawless experience with our software. However, despite our best efforts, occasional bugs or issues may still arise. If you encounter any problems or notice anything that seems out of place, we encourage you to let us know.
If you have ideas that could enhance freeRASP or improve your developer experience, we want to hear from you. We value suggestions from the community, as they reflect real needs and practical experiences.
To share your idea, please open an enhancement issue on our GitHub repository. Your input helps us prioritize features and improvements that matter most to our users.
keytool -list -v -keystore /Users/johndoe/my-release-key.jks -alias my-release-app-aliasRunner.xcworkspaceOn the top bar, select Product -> Scheme -> Edit Scheme...
On the left side, select Build -> Pre-actions
Find the integration script and click the trash icon on the right side to remove it
Open the .flutter-plugins (in the root folder of the app), and get the address where the freerasp is installed.
Go to the given folder, and remove the freerasp folder file.
Delete the .symlinks folder from the project.
Run pub get
Run pod install to test it
Otherwise, no further setup is required.
Note: You need Xcode 15 to be able to build the application.
dependencies {
...
// Talsec dependency
implementation 'com.aheaditec.talsec.security:TalsecSecurity-Community-Flutter:<version>'
}-keepclasseswithmembernames,includedescriptorclasses class * {
native ;
}android:extractNativeLibs="true"<application
android:label="freerasp_example"
android:icon="@mipmap/ic_launcher"
android:extractNativeLibs="true">import {
setThreatListeners,
talsecStart,
removeThreatListeners,
} from 'freerasp-react-native';
...
useEffect(() => {
setThreatListeners(actions);
talsecStart(config);
return () => {
removeThreatListeners();
};
}, []);Google Play Compliant: The default malware detection works out-of-the-box without requiring extensive Google Play policy reviews. (Optional deep scanning via QUERY_ALL_PACKAGES is available for advanced enterprise use cases).
Android
Flutter
React Native
Capacitor
Cordova
Kotlin Multiplatform
// Android bootloader check
override fun onBootloader() {
TODO("Not yet implemented")
}
// Flutter bootloader detection
onBootloader: () => print("Bootloader detected")
// Cordova bootloader detection
bootloader: () => {
// Place your reaction here
}
// React Native bootloader detection
bootloader: () => {
// Place your reaction here
}
// Capacitor bootloader detection
bootloader: () => {
// Place your reaction here
}// Android automation check
override fun onAutomation() {
TODO("Not yet implemented")
}
// Flutter automation detection
onAutomation: () => print("Automation detected")
// Cordova automation detection
automation: () => {
// Place your reaction here
}
// React Native automation detection
automation: () => {
// Place your reaction here
}
// Capacitor automation detection
automation: () => {
// Place your reaction here
}Deep Scanning (Optional)
If the specific threat model requires auditing "headless" packages (e.g., background services, daemons, or UI-less plugins), the application must explicitly request broad package visibility.
To enable this deep scanning capability, add the following to your AndroidManifest.xml:
The freeMalware Detection module is inactive by default. It activates only when at least one detection parameter is explicitly provided — either via the V2 SuspiciousAppDetectionConfig API or the legacy V1 configuration fields.
Without a valid detection configuration, no scan is performed and no threat callback is triggered.
Play Store Policy Constraint
Google classifies QUERY_ALL_PACKAGES as a highly sensitive permission. Including this permission subjects the application to an extended Google Play Policy Review. A valid justification explaining why the application requires visibility into all installed device packages must be provided to the review team.
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />runtimeManipulationpasscode
simulator
missingSecureEnclave
systemVPN
deviceChange
deviceID
unofficialStore
screenshot
screenRecording
timeSpoofing
List of Bundle IDs for the app
["com.talsec.freerasp.demoapp"]
appTeamId
String
Apple Team ID for the signing of the app
"M8AK35..."
watcherMailAddress
String?
The value is automatically used for Security Reports, Product Updates, and Talsec Portal updates, learn more.
Mail has a strict form 'name@domain.com'.
"john@example.com"
isProd
Bool?
Defaults to true when undefined. If you want to use the Dev version to make the development process easier, set the parameter to false. Make sure that you have the Release version in the production (i.e. isProd set to true)!
true
Got any questions regarding the Talsec Portal? Feel free to reach out! You can use the chatbot on the Portal or write to us at portal@talsec.app.




Choose your AI assistant:
Create an Integration.md file inside your app folder.
Navigate to https://docs.talsec.app/freerasp/integration/android. In the top right corner, click the arrow next to the copy button and choose the "Copy page" option.
Paste the content into your newly created Integration.md file.
Afterwards start Cursor inside your app folder and run this prompt:
After a successful build of your app with freeRASP integrated, the LLM will provide you with the next integration steps.
Create an Integration.md file inside your app folder.
Navigate to. In the top right corner, click the arrow next to the copy button and choose the "Copy page" option.
Paste the content into your newly created Integration.md file.
Create an Integration.md file inside your app folder.
Navigate to. In the top right corner, click the arrow next to the copy button and choose the "Copy page" option.
Paste the content into your newly created Integration.md file.
Create an Integration.md file inside your app folder.
Navigate to. In the top right corner, click the arrow next to the copy button and choose the "Copy page" option.
Paste the content into your newly created Integration.md file.
CRITICAL: This AI integration is a starting point only. You MUST manually configure:
Signing certificate hash
Watcher email
Threat reactions
Commit your code before starting so you can review/rollback changes.
The following sections detail the exact evaluation logic, the required configuration, and the resulting incident flags. Review each layer to understand how to construct a comprehensive threat model for your application:
Exceeding this threshold constitutes a breach of this Policy and obliges the Customer to transition to a commercial subscription plan.
Talsec reserves the right to reference the Application’s name and logo in Talsec’s marketing communications, including, but not limited to, website sections such as “Trusted by”, presentations, and other promotional materials.
The Service collects and processes security telemetry and threat data. This data is used for product enhancement, operational improvements, and aggregated security insights. By using the Service, you consent to such data collection and processing practices.
No personally identifiable information is intentionally collected or processed.
App publishers should provide clear disclosure to users in compliance with Google Play and Apple App Store policies.
In the event of suspected or actual usage in breach of this Policy (including but not limited to exceeding limits, or interfering with data collection), Talsec may, at its sole discretion and without prejudice to any other remedies:
Suspend or terminate your license to use the Service,
Withhold or discontinue consolidated security reporting or related services,
Require immediate transition to a commercial subscription plan.
Talsec may revise this Policy at any time. Notice of material changes will be provided by publishing the updated Policy on the Service website. Continued use of the Service after posting will constitute acceptance of those changes.
Before submitting a new idea, we recommend reviewing our GitHub Projects board. This will help you see if your suggestion is already being worked on or if similar ideas have been proposed.
Are you looking for upcoming events, ways to engage on social media, or a quick overview of our key programs? This is the hub of our community! Visit the main go-to resource for staying connected with Talsec.
Integration
Integrate freeRASP for your platform
Security Reports
Learn about regular security reports
License
How is freeRASP licensed
Commercial Subscriptions
Get maximum protection for your app
User Data Policies
Learn how we process your data

Users can share a copy of the application on unofficial stores or various pirate forums. While some users download these copies to avoid paying for the product, they can include unknown and possibly dangerous modifications. Verifying an official installation consequently protects both the users and the owner. This reaction is also triggered, if you install the application through alternative ways like unofficial store or Xcode build.
Below are code snippets demonstrating detection of unofficial installation across various platforms:
// Android
override fun onUnofficialStore() {...}
// iOS
case unofficialStore
// Flutter
onUnofficialStore: () => print("Unofficial store")
// Cordova
unofficialStore: () => {
// Place your reaction here
}
// React Native
unofficialStore: () => {
// Place your reaction here
}
// Capacitor
unofficialStore: () => {
// Place your reaction here
}If you want to define which applications can install the application, insert its package name in the supportedAlternativeStores (or supportedStores on Flutter) parameter. If you publish on Google Play, Huawei AppGallery, App Store (iOS), and TestFlight (iOS), you don't need to assign anything, as they are already supported out of the box.
The application can also be installed by "cloning" apps, which users employ to transfer apps between devices. The following list comprises popular examples of such apps. By default, freeRASP categorizes them as installations from an unofficial store .
Finally, it's very common application gets installed through browser, file manager, cloud storage or various messaging apps. By default, freeRASP categorizes them as installations from unofficial store.
freeRASP requires a minimum iOS 13+.
From GitHub, Copy into your Application folder.
Drag & drop the Talsec folder to your .xcworkspace.
This page provides you with all the necessary information about for . Please read it carefully. If you have a question, don't hesitate to .
In this section, you will implement the imported freeRASP Action.
On your app's initial page, navigate to the UI Builder.
On the right panel, click on Actions.
Screenshot detection identifies when a screenshot is taken on a device. Screenshots can expose sensitive app data, such as user credentials, personal content, or confidential information, leading to privacy and security risks. By detecting screenshots, apps can take preventive measures, such as:
Obscuring sensitive content before the screenshot is captured.
Notifying users that a screenshot has been taken.
Logging events for security monitoring and analysis.
The evaluation mode determines how the SDK decides which applications constitute threats, based on the signals available at scan time.
The specific logic depends on your integration version:
Modern (V2) integrations: Explicitly controlled by the reasonMode parameter — choose between strict AND logic (HIGHEST_CONFIDENCE) or broad OR logic (ALL).
Information about collected data
The freeRASP and freeMalwareDetection modules collect anonymized security diagnostics data from apps. These data contain:
Application state and security.
Device state and security.
Anonymous app instance ID and device ID.
App Blocklists
Static identification mechanisms using package names and cryptographic hashes.
Behavioral Heuristics
Contextual analysis, installation source verification, and heuristic evaluation logic.
🗳️ Raise GitHub Enhancement Issue
Missing some feature? Let us know!
⚖️ GitHub Project Board
Explore ideas we plan to refine and implement.
Community [Apply to Join!]
Included by default, no action needed
Huawei AppGallery
Included by default, no action needed
Firebase App Distribution
dev.firebase.appdistribution
Samsung Galaxy Store
com.sec.android.app.samsungapps
Common on Samsung devices
Vivo App Store
com.vivo.appstore
Common on Vivo devices
HeyTap
com.heytap.market
Common on Realme and Oppo devices
Oppo App Market
com.oppo.market
Common on Oppo devices
GetApps
com.xiaomi.mipicks
Common on Xiaomi, Redmi and POCO devices
Samsung Cloud for Wear OS
com.samsung.android.scloud
OPPO Clone Phone
com.coloros.backuprestore
EasyShare (Vivo)
com.vivo.easyshare
Clone Phone (OnePlus)
com.oneplus.backuprestore
SHAREit (Lenovo)
com.lenovo.anyshare.gps
SHAREit Lite
shareit.lite
ShareMe (Xiaomi)
com.xiaomi.midrop
MIUI Backup (Xiaomi)
com.miui.backup
Phone Clone (Honor)
com.hihonor.android.clone
App Store (iOS)
Included by default, no action needed
TestFlight (iOS)
Included by default, no action needed
Mi Mover (Xiaomi)
com.miui.huanji
Phone Clone (Huawei)
com.hicloud.android.clone
Samsung Smart Switch
Google Play
com.sec.android.easyMover
Create the CLAUDE.md file in your app folder with the content from the link
Now, launch Claude in your app folder and type start. Grant the LLM the necessary permissions when prompted. After a successful build of your app with freeRASP integrated, the LLM will provide you with the next integration steps.
Create the AGENTS.md file in your app folder with the content from the link.
Now, launch Codex in your app folder and type start. Grant the LLM the necessary permissions when prompted. After a successful build of your app with freeRASP integrated, the LLM will provide you with the next integration steps.
Create the GEMINI.md file in your app folder with the content from the link.
Now, launch gemini cli in your app folder and type start. Grant the LLM the necessary permissions when prompted. After a successful build of your app with freeRASP integrated, the LLM will provide you with the next integration steps.








Integrate free RASP into `your app` folder, while following the guide inside `Integration.md`. Check that integration was done correctly by building the app with gradle files. You are **PROHIBITED** from modifying any code in the target app that is not explicitly mentioned in the guide. Do not refactor or "improve" unrelated existing logic.
Take a look at this link “https://raw.githubusercontent.com/talsec/Free-RASP-Android/refs/heads/master/FreeRASPDemoApp/app/src/main/java/com/aheaditec/talsec/demoapp/TalsecApplication.kt”, It is reference integration, please follow it, especially imports. Replace any TODO comments found in the integration steps (specifically within callbacks or event handlers) with executable print functions (e.g., Log.d or println) containing relevant logging text, ensuring the events are observable.
After the integration, mention to the user what he needs to do next, according to the guide. For the `expectedSigningCertificateHashBase64`, you must explicitly provide the link `https://docs.talsec.app/freerasp/wiki/getting-signing-certificate-hash` and instruct the user to follow that guide to obtain the correct hash for their certificate.In the General > Frameworks, Libraries, and Embedded Content choose Embed & Sign.
Note: In case you are using Carthage, the zipped version of the framework is included in the GitHub Releases.
To ensure freeRASP functions correctly, you need to provide the necessary configuration. 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.
In the AppDelegate import TalsecRuntime and add the following code (e.g., in the didFinishLaunchingWithOptions method.:
You can handle the detected events using handlers. For example, you can log the event, show a window to the user or kill the application. See the Threat detection to learn more details about the performed checks and their importance for app security.
Anywhere in your project (e.g. in AppDelegate), add the following code as an extension:
import TalsecRuntime
extension SecurityThreatCenter: SecurityThreatHandler {
public func threatDetected(_ securityThreat: TalsecRuntime.SecurityThreat) {
print("Found incident: \(securityThreat.rawValue)")
}
}Use the code above for handling these types of events:
public enum SecurityThreat: String, Codable, CaseIterable, Equatable {
/// app integrity / repackaging / tampering
case signature = "appIntegrity"
/// jailbreak
case jailbreak = "privilegedAccess"
/// debugger
case debugger = "debug"
/// runtime manipulation / hooks
case runtimeManipulation = "hooks"
/// disabled passcode
case passcode
/// [DEPRECATED] passcode change
case passcodeChange
/// simulator
case simulator
/// missing Secure Enclave
case missingSecureEnclave
/// device binding
case deviceChange = "device binding"
/// changed deviceID
case deviceID
/// unofficial store or Xcode build
case unofficialStore
/// Detected system VPN
case systemVPN
/// screenshot
case screenshot
/// screen recording and screen mirroring
case screenRecording
/// Time spoofing detected
case timeSpoofing
}To utilize active screen shot and screen capture (e.g. mirroring, screen recording) protection, you can use Talsec.blockScreenCapture(enable: Bool, window: UIWindow) with specific UIWindow on which it should be blocked. To receive whether the screen capture is blocked in the specific UIWindow, you can use the Talsec.isScreenCaptureBlocked(in window: UIWindow). For more details about all these screen capture methods, see Screen Capture.
You can use RaspExecutionState to get callback when are initial checks are finished:
Invoke the following method right after setting up the TalsecConfig in previous steps.
Check out Data Visualisation Portal and register using your 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.
let config = TalsecConfig(
appBundleIds: ["YOUR_APP_BUNDLE_ID"],
appTeamId: "YOUR TEAM ID",
watcherMailAddress: "your_email_address@example.com",
isProd: true
)extension SecurityThreatCenter: RaspExecutionState {
public func onAllChecksFinished() {
print("Initial checks done")
}
}...
let config = TalsecConfig(...)
Talsec.start(config: config)You have to use the same email for the Portal as you used for the watcherMail parameter.
In the newly opened window, click on On Page Load at the top.
Click Add Action (or + and then Add Action, if you already have an Action).
On the right panel, search for the runRASP Custom Action.
Select the runRASP Action.
The freeRASP Action requires several arguments to be filled to function. Some data are related to specific platforms.
If you are developing the application exclusively for one platform, you can omit the configuration part related to the other platform. If you don't want to provide configuration to an unrelated platform, provide an empty string:
Click the orange variable icon next to the Value label
Scroll down to Constants
Click Constant to expand the dropdown menu
Select Empty String
watcherMail is an email address designated for receiving security reports. Ensure that the email address follows the strict name@domain.com format.
isProd is 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.
packageName is a unique identifier for your Android application.
You can find the packageName value for your application in FlutterFlow settings:
Navigate to Settings and Integrations.
Locate and select App Details.
In the textbox labelled Package Name, you will find the package name associated with your application.
signingCertHash is a hash of the certificate of the key which was used to sign the application. The value of the hash must be encoded in Base64 form.
More about signing hash and how to obtain it in Getting Signing Certificate Hash.
supportedStore is a third-party app store to which your application is uploaded. By including this store, freeRASP considers it as trusted source.
To add a store, add the package name of the store to the supportedStore list.
bundleId is a unique identifier for your iOS application.
More about bundle ID and how to obtain one: FlutterFlow Documentation | App Deployment.
teamId is a unique identifier assigned to a development team enrolled in the Apple Developer Program.
You can find your teamId on the Apple Developer portal:
Go to the website: https://developer.apple.com/account.
Log in using the account that is used to sign and release your app.
Scroll down to the Membership details section.
Look for the line labelled "Team ID" - the value of your team will be displayed there.
The freeRASP Action offers multiple callbacks for handling threats. A callback is an Action that gets triggered when a threat is detected.
To implement callback:
Open Action Flow Editor with runRASP action.
Open one of the dropdown menus labelled "onX" on the right panel (X for a given type of reaction, for example, onAppIntegrity)
In the Action Flow Editor box, click on Open.
Implement your reaction.
Visit Threat Detection to learn more details about the performed checks and their importance for app security.
freeRASP for Flutter allows you to define multiple values for:
Signing certificate hash
Supported app store
Bundle ID
Due to FlutterFlow's limitations, the current implementation of freeRASP for FlutterFlow only allows you to specify a single value for each of these attributes. If want to provide more values, you can download the code and adjust those parameters manually (see Flutter)
Currently, freeRASP supports only Android and iOS. When running the application in the FlutterFlow web client, freeRASP will not be initialized.
The minimum required Android SDK level for freeRASP is 23. FlutterFlow applications have a minimum SDK level of 21 by default.
This creates some restrictions:
Deploying the application from the FlutterFlow web client is not possible.
Downloading the APK from the FlutterFlow web client is not supported.
To overcome these limitations, we recommend following these steps:
Download the code.
Manually raise the SDK level in the build.gradle file to 23.
Deploy the application using Google Play Console.
Raising SDK version
From the root of your project, go to android > app > build.gradle
In defaultConfig update minSdkVersion to at least 23 (Android 6.0) or higher
Check out Data Visualisation Portal and register using your 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.
android {
...
defaultConfig {
...
minSdkVersion 23
...
}
...
}Do NOT use solutions such as to provide the value of the package name! The package name has to be hardcoded.
You have to use the same email for the Portal as you used for the watcherMail parameter.
Screen recording detection helps identify when a device's screen is being recorded. Screen recordings can capture sensitive data, such as user interactions and proprietary app content. By detecting screen recordings, apps can:
Mask sensitive information during recording.
Alert users that their screen is being recorded.
Log events for further security analysis.
Screen capture protection prevents your app’s content from appearing in screenshots and screen recordings. When enabled, captured images and recordings display a black screen, protecting sensitive information.
To enable or disable protection dynamically, pass true or false.
To check whether screen capture is currently blocked in the application, use the following method:
In our article we explain how to block screenshots, screen recording, and remote access tools in mobile apps to protect user data. It discusses security threats such as built-in screenshot tools, remote desktop apps like TeamViewer, screen mirroring software, third-party recording apps, and ADB-based access.
// Android screenshot detection
override fun onScreenshot() {
TODO("Not yet implemented")
}
// iOS screenshot detection
case screenshot
// Flutter screenshot detection
onScreenshot: () => print("Screenshot capture detected")
// React Native, Capacitor and Cordova
screenshot: () => {
console.log('screenshot');
},// Android screen recording detection
override fun onScreenRecording() {
TODO("Not yet implemented")
}
// iOS screen recording and screen mirrorring (AirPlay) detection
case screenRecording
// Flutter screen recording detection and screen mirrorring detection
onScreenRecording: () => print("Screen recording detected")
// React Native, Capacitor and Cordova
screenRecording: () => {
console.log('screenRecording');
},// Android screen capture protection
Talsec.blockScreenCapture(activity, true)
// iOS screen capture protection
Talsec.blockScreenCapture(enable: true, window: UIWindow)
// Flutter screen capture protection
await Talsec.instance.blockScreenCapture(enabled: true)
// React Native
import { blockScreenCapture } from 'freerasp-react-native';
await blockScreenCapture(true);
// response: Screen capture is now Blocked
// Capacitor
import { blockScreenCapture } from 'capacitor-freerasp';
await blockScreenCapture(true);
// response: true
// Cordova
await talsec.blockScreenCapture(true);
// response: Screen capture is now Blocked// Android screen capture state
Talsec.isScreenCaptureBlocked()
// iOS screen capture state
Talsec.isScreenCaptureBlocked(in window: UIWindow)
// Flutter screen capture state
await Talsec.instance.isScreenCaptureBlocked()
// React Native
import { isScreenCaptureBlocked } from 'freerasp-react-native';
const response = await isScreenCaptureBlocked();
// response: true
// Capacitor
import { isScreenCaptureBlocked } from 'capacitor-freerasp';
const response = await isScreenCaptureBlocked();
//response: true
// Cordova
const response = await talsec.isScreenCaptureBlocked();
//response: trueLegacy (V1) integrations: Fixed OR logic — equivalent to ALL mode, not configurable.
The default and recommended mode. Flags an application only when multiple independent signals align — blocklist matches are always included, and scope-based results require a permission match as a second signal.
Blocklist match
Any
Yes — reason: blocklist
Permission config present, app matches
In scan scope
Prioritizes maximum coverage over false-positive reduction. Every application that enters the configured scan scope is flagged, regardless of permission results.
Blocklist match (hash or package name)
blocklist
In scan scope, no dangerous permissions
installSource
In scan scope, matches dangerous permission set
Which applications enter the scan scope depends on the configured scope type and trustedInstallSources. In the default configuration — scope SIDELOADED_ONLY, no trustedInstallSources — the SDK scans all applications that are not system or OEM apps. This includes applications installed from official stores such as Google Play, because official stores are not excluded by default.
To exclude applications installed from specific sources, configure trustedInstallSources with the relevant installer package names (for example, com.android.vending for Google Play).
Older versions of the SDK do not support the reasonMode parameter. The heuristic engine functions identically to the modern ALL mode — every application within the scan scope is flagged, regardless of whether it matched any permission set.
This frequently results in false positives for benign sideloaded tools. Migration to SuspiciousAppDetectionConfig is recommended to access HIGHEST_CONFIDENCE mode and reduce noise.
The appropriate response depends on the reason codes returned and your application's risk tolerance.
blocklist results are high-confidence. The application matches an explicit entry you or the SDK defined. Immediate action is justified.
installSource + suspiciousPermission results indicate a sideloaded application requesting a dangerous capability combination. The risk level depends on the specific permissions involved. Consider prompting the user or restricting access until the application is reviewed.
installSource alone (ALL mode only) means the application is within scope but showed no other indicators. Treat these as informational — use them to prompt user awareness rather than hard-blocking.
Applicability
The configurable evaluation logic described below is active starting from the following SDK versions:
Android: 18.1.0 | Flutter: 8.0.0 | React Native: 5.0.0 | Capacitor: 3.0.0
suspiciousPermission is never returned in isolation. Permission analysis runs only on applications already identified as being within the scan scope, so suspiciousPermission always appears alongside installSource.
Applicability
The fixed evaluation logic described below applies to SDK versions prior to the V2 update:
Android: <18.1.0 | Flutter: <8.0.0 | React Native: <5.0.0 | Capacitor: <3.0.0
Network data — the IP address of the request, and approximate location and network operator resolved from it server-side.
Approximate location (country, region, city) and network operator are resolved server-side from the IP address of the request, and are used to detect fraud and automated abuse.
This information allows Talsec to provide a security report, improve the freeRASP product and even the commercial RASP SDK, or prepare mobile security reports and articles.
All the data collected by the freeRASP is technical diagnostics information and anonymous, but depending on the regulations applied, it could be considered sensitive and/or personal data.
Talsec recommends adding the statement below to the dedicated privacy policy page of your app. You can also use the text below while filling in the Google Play Safety Section or similar for Apple App Store publishing.
Google Play requires all app publishers to declare how they collect and handle user data for the apps they publish on Google Play. They should inform users properly of the data collected by the apps and how the data is shared and processed. Google will reject the apps which do not comply with the policy.
The checks for the Google Play and details about data are specified above in Privacy Policy Statement.
Apple requires that all app developers disclose their data collection and handling practices for apps published on the App Store. Developers must clearly inform users about the data their apps collect, as well as how this data is shared and processed. Apps that do not adhere to Apple's data privacy guidelines will be rejected.
To comply with the policy, in the App Privacy section, it is important to check the following:
Identifiers -> Device ID -> App Functionality
It is an anonymous device identifier for the App vendor as per: https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor
Talsec Security SDK can not link the device identifier to the user
Diagnostics -> Performance Data -> App Functionality, Other Purposes, No for linking to the user
Diagnostics -> Other diagnostics data -> App Functionality, Other Purposes, No for linking to the user
Other data -> App Functionality, No for linking to the user
Security diagnostics data (such as jailbreak)
Location -> Coarse Location -> App Functionality, Other Purposes, No for linking to the user
Approximate location resolved from the IP address, used for fraud and abuse detection
Google Play’s User Data policy indicates that a prominent disclosure should be presented to the users in case of an app collecting personal or sensitive data.
Although freeRASP collects diagnostical data (anonymous and not user-related), you (as the app publisher) should consider adding a disclosure screen, describing why the security diagnostic data is needed, what data, and how the data is used.
Description of the freeRASP API
TalsecConfigSpecifies configuration for your app. See the table below for a detailed description of the attributes.
expectedPackageName
String
constructor(threats: ThreatDetected, deviceState: DeviceState? = null, executionState: RaspExecutionState? = null)
Listener for the threats detected by freeRASP.
fun registerListener(context: Context)
Registers your reactions to detected threats with freeRASP.
fun unregisterListener(context: Context)
Unregisters the reactions to detected threats.
fun start(context: Context, config: TalsecConfig, mode: TalsecMode? = TalsecMode.BACKGROUND)
The method used to start freeRASP's functionality. TalsecMode is an optional parameter that can be used to force the execution of freeRASP in FOREGROUND / BACKGROUND thread (default value is TalsecMode.BACKGROUND).
fun blockScreenCapture(activity: Activity, enable: Boolean)
The method used to block/unblock screen capture.
fun isScreenCaptureBlocked(): Boolean
The method used to know the state of screen capture blocking whether blocked or not.
fun storeExternalId(context: Context, externalId: String): ExternalIdResult
Validates and stores a custom identifier (External ID) for the user.
Requirements:
Allowed characters: Alphanumeric (a-z, A-Z, 0-9) and special characters: +, _, -
fun removeExternalId(context: Context)
Removes the previously stored External ID.
Sends callbacks to your app when a threat is detected. Read more about the meaning of the callbacks in the .
open fun onPrivilegedAccess()
open fun onDebug()
open fun onSimulator()
Provides device state listener to get additional information about device state. Read more about the meaning of the device state listeners in the .
open fun onPasscode()
open fun onSecureHardwareNotAvailable()
open fun onDevMode()
A class which represents a set of callbacks that are used to notify the application when state of executing RASP checks changes.
open fun onAllChecksFinished()
Represents the result of the storeExternalId operation.
class Success - Indicates that the externalId was successfully validated and stored.
class Error(val errorMsg: String) - Indicates that validation failed due to invalid characters. Contains a description of the error.
The Behavioral Heuristics layer evaluates applications that bypass static identity checks. Instead of looking for a specific signature, the SDK evaluates two primary behavioral vectors:
How these two vectors are logically combined depends entirely on your configured reasonMode, which is detailed in the section.
The Android OS tracks the installer package name for every installed application. The SDK evaluates this identifier against your explicitly defined list of trusted sources to determine if the application originates from a trusted source.
You can define exactly which applications are subjected to this check by adjusting the scan scope in your configuration:
SIDELOADED_ONLY (default): Excludes all system applications and OEM pre-installed bloatware. Focuses exclusively on user-installed and sideloaded packages.
SIDELOADED_AND_SYSTEM_EXCLUDE_OEM: Scans sideloaded and system apps, but explicitly excludes OEM apps.
SIDELOADED_AND_OEM: Scans sideloaded apps plus vendor/OEM pre-installed bloatware.
com.android.vending — Google Play Store
com.huawei.appmarket — Huawei App Gallery
com.google.android.packageinstaller — Default system package installer (indicates a direct APK sideload)
This check evaluates the specific system privileges of the target application. You can define multiple sets of dangerous permissions.
Structurally, the evaluation applies a logical AND to the permissions inside a single set, and a logical OR across different sets. An application must fully match at least one set to be flagged.
The SDK provides granular control over how permissions are evaluated. You can configure the engine to check:
Requested Permissions: Evaluates any permission declared in the app's AndroidManifest.xml, regardless of whether the user has granted it yet.
Granted Permissions: Evaluates only the permissions actively granted by the user.
If you populate both parameters, the engine applies a logical OR between them — the application is flagged if it matches either the requested sets OR the granted sets.
When configuring your permission sets, use fully qualified :
OTP Stealers: android.permission.READ_SMS, android.permission.RECEIVE_SMS, android.permission.RECEIVE_WAP_PUSH
Overlay Trojans & Keyloggers: android.permission.BIND_ACCESSIBILITY_SERVICE
For detailed execution logic, configuration modes, and a complete list of triggered result flags, refer to the following page:
This section provides a technical overview of the freeMalware Detection module's execution flow. Understanding this operational lifecycle is a critical prerequisite for a successful integration, as it defines precisely when vulnerability scans occur, how state is managed, and how threat results are dispatched to the application.
Upon initialization, the detection engine executes a strict, automated pipeline before delivering any threat telemetry. The process is designed to minimize battery consumption and optimize startup performance through asynchronous batch operations.
Handling Configuration Changes: On each launch, the engine checks whether the active detection configuration has changed since the last scan. If a change is detected, the internal cache of previously evaluated applications is purged, and all packages are re-evaluated from scratch against the updated definitions.
Asynchronous Batch Evaluation: The scanning process is offloaded to a background thread. For each installed application, the engine first checks whether it was already recorded in the safe cache from a previous scan, and — if not — whether it is explicitly trusted. Applications that satisfy either condition are skipped without further evaluation. Only the remaining applications are passed to the on-device malware evaluator, which requires no network connectivity.
Safe Cache & Trust Management: Only after the entire evaluation batch successfully completes are applications marked as benign recorded in a persistent internal cache. Explicitly trusted applications are bypassed at evaluation time but are not written to the cache, as they are re-identified on each launch. During subsequent launches (provided the configuration remains unchanged), cached applications are bypassed entirely, resulting in near-instantaneous initialization times. However, if the application is terminated before the background batch completes, the safe cache is not updated and the full scan will restart upon the next launch.
Threat Callback Dispatch: The final threat callback is dispatched on the main thread only after all installed applications have been successfully evaluated.
Because comprehensive background scanning is a resource-intensive operation, the detection engine limits its execution frequency.
Since the engine will not continuously re-notify the application of an existing threat upon resuming, the host application architecture must handle threat state retention.
To prevent users from bypassing your security screen by backgrounding and resuming the application, your UI logic must maintain awareness of the threat:
Persist the Threat State: When the callback fires, save a flag (e.g., isMalwareDetected = true) in your application's session memory.
Enforce on Resume: Whenever the application returns to the foreground (e.g., via Android's onResume, Flutter's AppLifecycleState.resumed, or React Native's AppState.currentState), check this saved flag. If the flag is true, immediately re-display your blocking UI.
Because the detection engine operates on a scanning schedule rather than real-time monitoring, it does not provide uninstallation hooks. If a user removes a malicious application, the SDK does not notify you directly; the threat will simply be omitted from the results of the next background scan.
To programmatically verify that the device environment is secure after a user claims to have remediated the threat, implement the following strategy:
Dynamic OS Validation: Utilize standard operating system APIs (such as Android's PackageManager) to actively query if the offending package name is still present on the system.
Description of the freeRASP API
Specifies configuration for your app. See the table below for detailed description of the attributes.
Cordova: 9.0.0 | KMP: 2.0.0
To utilize this logic, you must configure detection using the SuspiciousAppDetectionConfig (V2) API.
Cordova: <9.0.0 | KMP: <2.0.0
Yes — reasons: installSource + suspiciousPermission
Permission config present, no match
In scan scope
No
No permission config
In scan scope
No
installSource + suspiciousPermission
/:=Returns:
ExternalIdResult.Success if the ID is valid and stored, or ExternalIdResult.Error if the ID violates the requirements (the ID will not be stored).
open fun onAppIntegrity()open fun onUnofficialStore()
open fun onHooks()
open fun onDeviceBinding()
open fun onObfuscationIssues()
open fun onScreenshot()
open fun onScreenRecording()
open fun onMultiInstance()
open fun onLocationSpoofing()
open fun onTimeSpoofing()
open fun onUnsecureWifi()
open fun onAutomation()
open fun onBootloader()
open fun onMalware(packageInfo: List<SuspiciousAppInfo>)
open fun onAdbEnabled()open fun onSystemVpn()
Package name of the app.
"app.talsec.demo.freerasp"
expectedSigningCertificateHashBase64
Array<String>
Certificate hashes of your app. You must get your expected signing certificate hashes in Base64 form. You can go through this manual to learn how to sign your app in more detail, including manual signing and using Google's Play app signing.
arrayOf( "mVr/qQLO8DKTwqlL+B1qigl9NoBnbiUs8b4c2Ewcz0k=")
watcherMail
String?
The value is automatically used for Security Reports, Product Updates, and Talsec Portal updates, learn more.
Mail has a strict form 'name@domain.com'.
"john@example.com"
supportedAlternativeStores
Array<String>
Package names of the alternative stores on which you are publishing the application. The Google Play Store and Huawei AppGallery, are included internally. (You can assign just emptyArray()). For more information, visit the Detecting Unofficial Installation wiki page.
arrayOf( "com.sec.android.app.samsungapps")
isProd
Boolean?
Defaults to true when undefined. If you want to use the Dev version to make the development process viable, set the parameter to false. Make sure that you have the Release version in the production (i.e. isProd set to true)!. To simplify switching between debug and release version of freeRASP based on the build type, you can use BuildConfig.BUILD_TYPE.contains("Release", true) as a value for isProd.
true
killOnBypass
Boolean?
Defaults to false .
Determines whether the app should be killed within the SDK, if the callbacks are hooked or modified by an attacker.
true
SIDELOADED_AND_SYSTEM_AND_OEM: Scans all non-store apps — sideloaded, system, and OEM.
ALL: Evaluates every single application on the device, regardless of its origin.
unknown — Applications with a null installation source (ADB installs, local development builds)
android.permission.BIND_DEVICE_ADMINandroid.permission.SYSTEM_ALERT_WINDOWDroppers: android.permission.REQUEST_INSTALL_PACKAGES
Surveillance Spyware: android.permission.QUERY_ALL_PACKAGES
Local Testing Note
You can temporarily whitelist unknown or com.google.android.packageinstaller to bypass checks during local development via ADB, but these should never be whitelisted in production.
Information about the integrity of the app and the operating system. For example, rooting, running in an emulator, hooking framework usage, etc...
Category: Device or other identifiers
Data Type: Device or other identifiers
Information that relates to an individual device. For example, a device model and anonymous identifier to control that app instance executed on the original device that it was initially installed on. It is needed to combat threats like bots and API abuse.
Category: Location
Data Type: Approximate location
Approximate location and network operator, resolved from the device's IP address. Used for fraud prevention and abuse detection.

watcherMailwatcherMail.any AndroidConfig instance
iosConfig
IOSConfig?
Configuration for iOS apps
any IOSConfig instance
watcherMail
string
The value is automatically used for Security Reports, Product Updates, and Talsec Portal updates, .
Mail has a strict form 'name@domain.com'.
'john@example.com'
isProd
boolean?
Defaults to true when undefined. If you want to use the Dev version to make the development process easier, set the parameter to false. Make sure that you have the Release version in the production (i.e. isProd set to true)!. To simplify switching between debug and release version of freeRASP based on the build type, you can use BuildConfig.BUILD_TYPE.contains("Release", true) as a value for isProd.
true
killOnBypass
boolean?
Defaults to false. If set to true, the application will be terminated when the threat callbacks are suppressed or hooked.
true
Specifies configuration for instances of the app running on Android devices. See the table below for detailed description of the attributes.
packageName
string
Package name of the app.
'com.talsec.freerasp.demoapp'
Specifies configuration for instances of the app running on Android devices. See the table below for detailed description of the attributes.
appBundleId
string
Apple Bundle ID for the app
'com.talsec.freerasp.demoapp'
Specifies a set of callbacks that are used to notify the application when certain security threat is detected.
privilegedAccess
() => any
Callbacks for monitoring the execution state of RASP checks.
allChecksFinished
() => any
React Custom Hook responsible for starting freeRASP and setting up listeners
Sets up listeners for detected threats
Method is used to start freeRASP's audit. Returns 'freeRASP started'string when successful.
Unregisters threat listeners. Should be called only when the app is being terminated.
androidConfig
AndroidConfig?
Configuration for Android apps
Description of the freeRASP API
TalsecConfigSpecifies configuration for your app. See the table below for detailed description of the attributes.
androidConfig
AndroidConfig?
Specifies configuration for instances of the app running on Android devices. See the table below for detailed description of the attributes.
Specifies configuration for instances of the app running on iOS devices. See the table below for detailed description of the attributes.
Starts freeRASP with configuration provided in config.
Attaches instance of ThreatCallback to freeRASP. If ThreatCallback is already attached, current one will be detached and replaced with callback. When threat is detected, respective callback of ThreatCallback is invoked.
Sets a custom identifier (External ID) for the current installation. Throws ExternalIdFailureException if the format is invalid or storing fails.
Removes the previously set External ID. Throws ExternalIdFailureException if the removal fails.
A class which represents a set of callbacks that are used to notify the application when certain security threat is detected. Read more about the meaning of the callbacks in the .
A class which represents a set of callbacks that are used to notify the application when state of executing RASP checks changes.
Description of the freeRASP API
TalsecConfigSpecifies configuration for your app. See the table below for detailed description of the attributes.
androidConfig
AndroidConfig?
Specifies configuration for instances of the app running on Android devices. See the table below for detailed description of the attributes.
Specifies configuration for instances of the app running on Android devices. See the table below for detailed description of the attributes.
Specifies a set of callbacks that are used to notify the application when certain security threat is detected.
Method is used to start freeRASP's audit and set up listeners for threats.
Stores an external ID (e.g., User ID) to be sent with reports to the Talsec Dashboard.
Removes the stored external ID.
Description of the freeRASP API
TalsecConfigSpecifies configuration for your app. See the table below for detailed description of the attributes.
androidConfig
AndroidConfig?
Specifies configuration for instances of the app running on Android devices. See the table below for detailed description of the attributes.
Specifies configuration for instances of the app running on iOS devices. See the table below for detailed description of the attributes.
Specifies a set of callbacks that are used to notify the application when certain security threat is detected.
Specifies a set of callbacks that are used to notify the application about the state of freeRASP execution.
Method is used to start freeRASP's audit and set up listeners for threats. Returns { started: true } when successful.
Unregisters threat listeners. Should be called only when the app is being terminated.
Enables or disables screen capture blocking (Android only).
Checks if screen capture is currently blocked (Android only).
Stores an external ID (e.g., User ID) to be sent with reports to the Talsec Dashboard.
Removes the stored external ID.
This page is intended to provide quick answers to common questions.
Thank you for reading the freeRASP FAQ. If you didn't find the answer to your question, please do not hesitate to create a GitHub issue on the respective repository (preferably) or email support@talsec.atlassian.net.
Configuration for Android apps
any AndroidConfig instance
iosConfig
IOSConfig?
Configuration for iOS apps
any IOSConfig instance
watcherMail
String
The value is automatically used for Security Reports, Product Updates, and Talsec Portal updates, .
Mail has a strict form 'name@domain.com'.
'john@example.com'
isProd
bool?
Defaults to true when undefined. If you want to use the Dev version to make the development process easier, set the parameter to false. Make sure that you have the Release version in the production (i.e. isProd set to true)!. To simplify switching between debug and release version of freeRASP based on the build type, you can use BuildConfig.BUILD_TYPE.contains("Release", true) as a value for isProd.
true
killOnBypass
bool?
Defaults to false .
Determines whether the app should be killed within the SDK, if the callbacks are hooked or modified by an attacker.
true
packageName
String
Package name of the app.
'com.talsec.freerasp.demoapp'
bundleIds
List<String>
List of Bundle IDs for the app
com.talsec.freerasp.demoapp']
onPrivilegedAccess
VoidCallback?
onAllChecksFinished
VoidCallback?
Configuration for Android apps
any AndroidConfig instance
iosConfig
IOSConfig?
Configuration for iOS apps
any IOSConfig instance
watcherMail
string
The value is automatically used for Security Reports, Product Updates, and Talsec Portal updates, .
Mail has a strict form 'name@domain.com'.
'john@example.com'
isProd
boolean?
Defaults to true when undefined. If you want to use the Dev version to make the development process easier, set the parameter to false. Make sure that you have the Release version in the production (i.e. isProd set to true)!. To simplify switching between debug and release version of freeRASP based on the build type, you can use BuildConfig.BUILD_TYPE.contains("Release", true) as a value for isProd.
true
packageName
string
Package name of the app.
'com.talsec.freerasp.demoapp'
appBundleId
string
Apple Bundle ID for the app
'com.talsec.freerasp.demoapp'
privilegedAccess
() => any
Configuration for Android apps
any AndroidConfig instance
iosConfig
IOSConfig?
Configuration for iOS apps
any IOSConfig instance
watcherMail
string
The value is automatically used for Security Reports, Product Updates, and Talsec Portal updates, .
Mail has a strict form 'name@domain.com'.
'john@example.com'
isProd
boolean?
Defaults to true when undefined. If you want to use the Dev version to make the development process easier, set the parameter to false. Make sure that you have the Release version in the production (i.e. isProd set to true)!. To simplify switching between debug and release version of freeRASP based on the build type, you can use BuildConfig.BUILD_TYPE.contains("Release", true) as a value for isProd.
true
killOnBypass
boolean?
Defaults to false .
Determines whether the app should be killed within the SDK, if the callbacks are hooked or modified by an attacker.
true
packageName
string
Package name of the app.
'com.talsec.freerasp.demoapp'
appBundleId
string
Apple Bundle ID for the app
'com.talsec.freerasp.demoapp'
privilegedAccess
() => any
allChecksFinished
() => any
const startFreeRASP = async (config: TalsecConfig, actions: ThreatEventActions, raspExecutionStateActions?: RaspExecutionStateEventActions): Promise<{ started: boolean }>For applications requiring enhanced protection, compliance assurance, or long-term support, RASP+ offers extended capabilities and SLA-backed support.
To learn more about acceptable use and limitations, please refer to our .
com.heytap.market
There are also some services, which use package installer for distribution of the application, e.g. the App Center uses com.google.android.packageinstaller or com.android.packageinstaller.
See for more information.
Tampering
Unofficial store
Obfuscation Issues
Developer Mode
If you want to use the Dev version to disable checks, you need to set isProd parameter to false in TalsecConfig object instance. By default, the isProd parameter is set to true.
Periodic checks are performed regularly, at defined intervals (e.g. every X seconds or minutes).
Open Runner.xcworkspace in Xcode.
On the top bar select Product -> Scheme -> Edit Scheme....
On the left side select Build -> Pre-actions.
Find the integration script and click the trash icon on the right side to remove it.
Open the .flutter-plugins (in the root folder of the app), and get the address where the freeRASP is installed.
Go to the given folder, and remove the freerasp folder file.
Delete .symlinks folder from project.
Run pub get.
Run pod install to test it.
AppiCrypt AppiCrypt secures communication between your app and backend. It includes the results of the Talsec security audit, which you can verify server-side. This way, you can confirm that the device sending the request has passed the security checks before proceeding with further communication. Learn more about AppiCrypt here: .
build.gradle files for any afterEvaluate blocks and look for lines that change the compileSdkVersion. Remove or update them to ensure your project uses the correct SDK version required for the screen recording protection feature to compile successfully.You can also refer to the discussion and solution in .
certificateHashes
string[]
Certificate hashes of your app.
['mVr/qQLO8DKTwqlL+B1qigl9NoBnbiUs8b4c2Ewcz0k=']
supportedAlternativeStores
string[]
Package names of the alternative stores. If you publish on the Google Play Store and Huawei AppGallery, as these are already included internally. (You can assign just emptyArray()). For more information, visit the wiki page.
[ 'com.sec.android.app.samsungapps']
appTeamId
string
Apple Team ID used in the app
'M8AK35...'
debug
() => any
simulator
() => any
appIntegrity
() => any
unofficialStore
() => any
hooks
() => any
deviceBinding
() => any
deviceID
() => any
passcode
() => any
secureHardwareNotAvailable
() => any
obfuscationIssues
() => any
devMode
() => any
adbEnabled
() => any
systemVPN
() => any
malware
`(apps: SuspiciousAppInfo[]) => any
screenshot
() => any
screenRecording
() => any
multiInstance
() => any
timeSpoofing
() => any
locationSpoofing
() => any
unsecureWifi
() => any
automation
() => any
bootloader
() => any
certificateHashes
string[]
Certificate hashes of your app.
['mVr/qQLO8DKTwqlL+B1qigl9NoBnbiUs8b4c2Ewcz0k=']
supportedAlternativeStores
string[]
Package names of the alternative stores. If you publish on the Google Play Store and Huawei AppGallery, as these are already included internally. (You can assign just emptyArray()). For more information, visit the Detecting Unofficial Installation wiki page.
[ 'com.sec.android.app.samsungapps']
appTeamId
string
Apple Team ID used in the app
'M8AK35...'
debug
() => any
simulator
() => any
appIntegrity
() => any
unofficialStore
() => any
hooks
() => any
deviceBinding
() => any
deviceID
() => any
passcode
() => any
secureHardwareNotAvailable
() => any
obfuscationIssues
() => any
devMode
() => any
adbEnabled
() => any
systemVPN
() => any
malware
(apps: SuspiciousAppInfo[]) => any
screenshot
() => any
screenRecording
() => any
multiInstance
() => any
timeSpoofing
() => any
locationSpoofing
() => any
unsecureWifi
() => any
automation
() => any
bootloader
() => any
certificateHashes
string[]
Certificate hashes of your app.
['mVr/qQLO8DKTwqlL+B1qigl9NoBnbiUs8b4c2Ewcz0k=']
supportedAlternativeStores
string[]
Package names of the alternative stores. If you publish on the Google Play Store and Huawei AppGallery, as these are already included internally. (You can assign just emptyArray()). For more information, visit the Detecting Unofficial Installation wiki page.
[ 'com.sec.android.app.samsungapps']
appTeamId
string
Apple Team ID used in the app
'M8AK35...'
debug
() => any
simulator
() => any
appIntegrity
() => any
unofficialStore
() => any
hooks
() => any
deviceBinding
() => any
deviceID
() => any
passcode
() => any
secureHardwareNotAvailable
() => any
obfuscationIssues
() => any
devMode
() => any
adbEnabled
() => any
systemVPN
() => any
malware
(apps: SuspiciousAppInfo[]) => any
screenshot
() => any
screenRecording
() => any
multiInstance
() => any
timeSpoofing
() => any
locationSpoofing
() => any
unsecureWifi
() => any
automation
() => any
bootloader
() => any
Community [Apply to Join!]
Space for developer's creativity, community programs
signingCertHashes
List<String>
Certificate hashes of your app.
['mVr/qQLO8DKTwqlL+B1qigl9NoBnbiUs8b4c2Ewcz0k=']
supportedStores
List<String>
Package names of the alternative stores. If you publish on the Google Play Store and Huawei AppGallery, as these are already included internally. (You can assign just emptyArray()). For more information, visit the Detecting Unofficial Installation wiki page.
'com.sec.android.app.samsungapps']
teamId
String
Apple Team ID used in the app
'M8AK35...'
onDebug
VoidCallback?
onSimulator
VoidCallback?
onAppIntegrity
VoidCallback?
onUnofficialStore
VoidCallback?
onHooks
VoidCallback?
onDeviceBinding
VoidCallback?
onDeviceID
VoidCallback?
onPasscode
VoidCallback?
onSecureHardwareNotAvailable
VoidCallback?
onObfuscationIssues
VoidCallback?
onDevMode
VoidCallback?
onADBEnabled
VoidCallback?
onSystemVPN
VoidCallback?
onMultiInstance
VoidCallback?
onUnsecureWifi
VoidCallback?
onTimeSpoofing
VoidCallback?
onLocationSpoofing
VoidCallback?
onAutomation
VoidCallback?
onBootloader
VoidCallback?
void onMalwareDetected( List<SuspiciousAppInfo> suspiciousApps)
MalwareCallback?
🚨 freeRASP for Unity – Early Release [6/2025]
We’re excited to introduce freeRASP for Unity as a new flavor of our runtime protection library. As it’s still fresh, you may encounter some integration issues that need to be ironed out.
We’d love to hear about your experience—good or bad. Please or write us directly at support@talsec.app. Your feedback helps us make it better!
Example:
Ensure your development environment meets the following requirements:
Unity Editor version 6 or higher.
Minimum Android SDK level 23 or higher.
Open your Unity project. Right-click the Assets folder in the Project window and select Import Package -> Custom Package to import the downloaded file.
Create an empty GameObject in your primary Scene, or select an existing one. Create a script named Game.cs and drag it from the Project window onto your GameObject in the Hierarchy or Inspector window. Unity automatically calls the Start() method when the Scene loads. Implement the TalsecConfig object and initialize the freeRASP plugin within this method.
freeRASP evaluates the device environment and application binary for integrity violations. When a check detects an anomaly, the system triggers the corresponding method within the ThreatDetectedCallback interface.
freeRASP evaluates security checks in periodic cycles. When the system completes a full scan cycle without interruption, it triggers the onAllChecksFinished method within the RASPStatusCallback interface.
freeRASP utilizes native Android and iOS libraries to execute runtime security checks. You must configure platform-specific build settings to link these native dependencies correctly. Complete the Android Gradle configurations before compiling your final Android package, and complete the iOS framework setup after exporting your Unity project to Xcode.
Define the Talsec Maven repositories in your Gradle configuration to resolve the freeRASP Android dependencies. Add the following to your settings.gradle located in your Unity project at Assets/Plugins/Android/settings.gradle.
Some callbacks require additional permissions to function. In your Unity project, locate or create Assets/Plugins/Android/AndroidManifest.xml and add the relevant permissions inside the <manifest> root tag.
In Unity, navigate to File → Build Settings. Select iOS as the target platform and click Switch Platform. Then click Build to export the project as an Xcode project.
Download the native TalsecRuntime.xcframework asset from the freeRASP iOS GitHub Releases page.
Check out and register using your 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.
🚨 freeRASP for Unreal Engine – Early Release [10/2025]
We’re excited to introduce freeRASP for Unreal Engine as a new flavor of our runtime protection library. As it’s still fresh, you may encounter some integration issues that need to be ironed out.
We’d love to hear about your experience—good or bad. Please or write us directly at support@talsec.app. Your feedback helps us make it better!
The freeRASP has the following prerequisites that must be met before starting:
Supported Unreal Engine Versions: 5.1 or higher
Minimum Android Target SDK: API Level 23
Minimum iOS Deployment Target: 15.0
To install the plugin, download the latest release from the Releases page on GitHub.
Navigate to the on the GitHub repository.
Under the latest release (e.g., 1.1.0), find the Assets section.
Download the .zip or .tar.gz file, for example, Free-RASP-UnrealEngine-POC-1.1.0.zip
Enabling the plugin involves two steps: enabling it in the editor and verifying the dependency in the C++ build file.
In the main Unreal Engine menu, navigate to Edit -> Plugins.
In the left panel, find the Project -> Security category.
Some checks require additional permissions to work properly. If your app already has these permissions, you don't need to add them again.
Add the required permissions via Edit -> Project Settings → Platforms → Android → Extra Permissions.
With the plugin installed and enabled, it's time to write the code to initialize freeRASP and handle its threat notifications. This process involves preparing a C++ class, initializing the plugin at startup, and implementing a function to handle threats.
First you need to prepare a class to receive threat notifications. The recommended place for this is your APlayerController class, as it persists for the entire game session.
In your class's header file (.h), include the plugin's header and define the function that will act as the callback.
Example AFreeRASPPlayerController.h:
Initialization should occur as early as possible when the game starts. The BeginPlay()
Check out and register using your 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.
Example:
freeRASP requires a minimum SDK level of 23. To update the minimum SDK level of the application, follow these steps:
From the root of your project (or module level), go to the build.gradle.kts (Module :app).
Update minSdkVersion to at least 23 (Android 6.0) or higher.
android {
...
defaultConfig {
...
minSdk = 23
}
}Some checks require additional permissions in order to work properly. If your app already has these permissions, you don't need to add them again.
To and screen recordings , add the following permissions to your AndroidManifest.xml file inside the <manifest> root tag:
To detect location spoofing, add the following permissions to your AndroidManifest.xml file inside the <manifest> root tag:
To detect unsecure WiFi, add the following permissions to your AndroidManifest.xml file inside the <manifest> root tag:
Add the Talsec Artifact Registry to your project's settings.gradle.kts, set the version in libs.versions.toml, and configure the plugin in build.gradle.kts (Module: app).
Config via settings.gradle.kts:
Set version in version catalog via libs.versions.toml:
Configure the plugin via build.gradle.kts (Module: app):
To ensure freeRASP functions correctly, you need to provide the necessary configuration. All required values must be filled in for the SDK to operate properly. Use the following template to configure the plugin. Detailed descriptions of the configuration options are provided .
To guarantee protection starts immediately, initialize freeRASP inside the onCreate method of your Application subclass. If you don't have a custom Application class, create one extending Application:
Add a new subclass to AndroidManifest.xml, inside <application> tag:
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 to learn more details about the performed checks and their importance for app security.
Create a ThreatListener.ThreatDetected object and override the methods you want to handle. You don't need to override all methods; only implement the ones relevant to your app's security policy.
Optionally, you can use a device state listener to get additional information about the device state, like passcode lock and HW-backed Keystore state:
You can make sure that the obfuscation is enabled by checking the value of minifyEnabled property in your module's build.gradle file.
Read more about why this is important in the.
The externalId allows you to send a custom identifier (such as a User ID) to the . This identifier will be visible in the Dashboard, enabling you to correlate security incidents with specific users in your system.
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.
It helps to detect apps with suspicious package names, hashes, or potentially dangerous permissions.
Visit the repository to learn more about this feature! For the integration, refer to the for the Android platform.
Check out and register using your 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.
using UnityEngine;
public class Game : MonoBehaviour, ThreatDetectedCallback, RASPStatusCallback
{
void Start()
{
var config = new TalsecConfig
{
watcherMailAddress = "your_mail@example.com",
isProd = true,
androidConfig = new AndroidConfig
{
packageName = "com.example.app",
signingCertificateHashBase64 = new string[] { "your_hash_here" },
supportedAlternativeStores = new string[] { "com.sec.android.app.samsungapps" }
},
iosConfig = new IOSConfig
{
appBundleIds = new string[] { "com.example.app" },
appTeamId = "TEAM ID"
}
};
TalsecPlugin.Instance.setThreatDetectedCallback(this);
TalsecPlugin.Instance.setRASPStatusCallback(this);
TalsecPlugin.Instance.initTalsec(config);
}
}public void onPrivilegedAccess()
{
Debug.Log("Unity - Root/Jailbreak detected");
}
public void onAppIntegrity()
{
Debug.Log("Unity - Tamper detected");
}
public void onDebug()
{
Debug.Log("Unity - Debugger detected");
}
public void onSimulator()
{
Debug.Log("Unity - Emulator/Simulator detected");
}
public void onObfuscationIssues()
{
Debug.Log("Unity - Obfuscation issues detected");
}
public void onScreenshot()
{
Debug.Log("Unity - Screenshot detected");
}
public void onScreenRecording()
{
Debug.Log("Unity - Screen recording detected");
}
public void onUnofficialStore()
{
Debug.Log("Unity - Untrusted installation source detected");
}
public void onHooks()
{
Debug.Log("Unity - Hook detected");
}
public void onDeviceBinding()
{
Debug.Log("Unity - Device binding detected");
}
public void onPasscode()
{
Debug.Log("Unity - Unlocked device detected");
}
public void onPasscodeChange()
{
Debug.Log("Unity - Passcode change detected");
}
public void onDeviceID()
{
Debug.Log("Unity - Device ID detected");
}
public void onSecureHardwareNotAvailable()
{
Debug.Log("Unity - Hardware backed keystore not available");
}
public void onDevMode()
{
Debug.Log("Unity - Developer mode detected");
}
public void onADBEnabled()
{
Debug.Log("Unity - ADB enabled detected");
}
public void onSystemVPN()
{
Debug.Log("Unity - System VPN detected");
}
public void onMultiInstance()
{
Debug.Log("Unity - Multi instance detected");
}
public void onUnsecureWiFi()
{
Debug.Log("Unity - Unsecure WiFi detected");
}
public void onTimeSpoofing()
{
Debug.Log("Unity - Time spoofing detected");
}
public void onLocationSpoofing()
{
Debug.Log("Unity - Location spoofing detected");
}public void onAllChecksFinished()
{
Debug.Log("Unity - All checks finished");
}dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
repositories {
google()
mavenCentral()
maven { url 'https://jitpack.io' }
maven { url 'https://europe-west3-maven.pkg.dev/talsec-artifact-repository/freerasp' }
flatDir {
dirs "${project(':unityLibrary').projectDir}/libs"
}
}
}<uses-permission android:name="android.permission.DETECT_SCREEN_CAPTURE" />
<uses-permission android:name="android.permission.DETECT_SCREEN_RECORDING" /><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />You have to use the same email for the Portal as you used for the watcherMail parameter.
Extract the archive. Inside you will find the FreeRASPPlugin folder.
Copy the entire FreeRASPPlugin directory into your project's Plugins folder. If a Plugins folder doesn't exist at the root of your project, you will need to create it first.
The correct final directory structure should look like this:
Open your project's build configuration file, named <project_name>.Build.cs. Verify that the module name FreeRASPPlugin is added to the PublicDependencyModuleNames list.
It should look similar to this example:
HandleSecurityThreatHandleRASPExecutionStatusExample MyPlayerController.cpp:
Finally, implement the logic for the HandleSecurityThreat function itself. This part of the code decides what happens when a specific threat is detected.
Example FreeRASPPlayerController.cpp:
Next, implement the logic for the HandleRASPExecutionStatus function. This callback is triggered once freeRASP has completed all its security checks.
android.permission.DETECT_SCREEN_CAPTURE
android.permission.DETECT_SCREEN_RECORDINGandroid.permission.ACCESS_COARSE_LOCATION
android.permission.ACCESS_FINE_LOCATIONandroid.permission.ACCESS_FINE_LOCATION
android.permission.ACCESS_WIFI_STATE#pragma once
#include "CoreMinimal.h"
#include "GameFramework/PlayerController.h"
#include "FreeRASPPluginLibrary.h" // <-- 1. Include the header file
#include "FreeRASPPlayerController.generated.h"
/**
* Basic PlayerController class for a game
*/
UCLASS(abstract)
class AFreeRASPPlayerController : public APlayerController
{
GENERATED_BODY()
protected:
/** Input Mapping Contexts */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input", meta = (AllowPrivateAccess = "true"))
TArray<UInputMappingContext*> DefaultMappingContexts;
/** Input mapping context setup */
virtual void SetupInputComponent() override;
virtual void BeginPlay() override; // initialize FreeRASP here
UFUNCTION()
void HandleSecurityThreat(ThreatType ThreatType); // define this method to receive threat callbacks
UFUNCTION()
void HandleRASPExecutionStatus(RASPExecutionStatus RASPStatus); // define this method to receive RASP execution status callbacks
};You have to use the same email for the Portal as you used for the watcherMail parameter.
[YourProjectName]/
├── Content/
├── Source/
├── Plugins/ <-- Create if missing
│ └── FreeRASPPlugin/
└── YourProjectName.uprojectusing UnrealBuildTool;
public class freeRASP4 : ModuleRules
{
public freeRASP4 (ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
PublicDependencyModuleNames.AddRange(new string[] {
"Core",
"CoreUObject",
"Engine",
"InputCore",
"EnhancedInput",
"AIModule",
"StateTreeModule",
"GameplayStateTreeModule",
"UMG",
"FreeRASPPlugin" // <-- check if this line is added
});
}
}#include "AFreeRASPPlayerController.h" // Include your header file
#include "FreeRASPPluginLibrary.h" // Include the plugin header
void AFreeRASPPlayerController::BeginPlay()
{
Super::BeginPlay();
// Get the FreeRASP plugin library instance
if (UFreeRASPPluginLibrary* FreeRASPLib = GetGameInstance()->GetSubsystem<UFreeRASPPluginLibrary>())
{
// 1. Bind your function to the threat detection event
// The class name here MUST match the class you are in (e.g., AMyPlayerController)
FreeRASPLib->OnSecurityThreatDetected.AddDynamic(this, &AFreeRASPPlayerController::HandleSecurityThreat);
FreeRASPLib->OnRASPExecutionStatus.AddDynamic(this, &AFreeRASPPlayerController::HandleRASPExecutionStatus);
// 2. Prepare the configuration
// Important: These values are placeholders. Replace them with your actual data.
// iOS Configuration
TArray<FString> AppBundleIds;
AppBundleIds.Add(TEXT("com.game.bundle.id"));
FString AppTeamId = TEXT("1AB2C3");
// Android Configuration
FString PackageName = TEXT("com.talsec.free.rasp.game");
TArray<FString> SigningCertificates;
SigningCertificates.Add(TEXT("ilx/AtYu7TpAu5cma4JdDXio5bayFSi89axnyOCjfFo="));
TArray<FString> AlternativeStores;
AlternativeStores.Add(TEXT("com.samsung.android.apps.galaxyapp"));
// General Configuration
FString WatcherEmail = TEXT("your_email_address@example.com");
bool IsProduction = true; // Set to false for development builds
// 3. Initialize freeRASP
FreeRASPLib->InitializeTalsec(
AppBundleIds,
AppTeamId,
PackageName,
SigningCertificates,
AlternativeStores,
WatcherEmail,
IsProduction
);
}
}void AFreeRASPPlayerController::HandleSecurityThreat(ThreatType ThreatType)
{
UE_LOG(LogTemp, Warning, TEXT("Security threat detected: %d"), ThreatType);
switch (ThreatType) {
case ThreatType::OnPrivilegedAccess:
UE_LOG(LogTemp, Warning, TEXT("Privileged access threat detected"));
break;
case ThreatType::OnAppIntegrity:
UE_LOG(LogTemp, Warning, TEXT("App integrity threat detected"));
break;
case ThreatType::OnDebug:
UE_LOG(LogTemp, Warning, TEXT("Debug threat detected"));
break;
case ThreatType::OnSimulator:
UE_LOG(LogTemp, Warning, TEXT("Simulator threat detected"));
break;
case ThreatType::OnUnofficialStore:
UE_LOG(LogTemp, Warning, TEXT("Unofficial store threat detected"));
break;
case ThreatType::OnHookDetected:
UE_LOG(LogTemp, Warning, TEXT("Hook threat detected"));
break;
case ThreatType::OnDeviceBinding:
UE_LOG(LogTemp, Warning, TEXT("Device binding threat detected"));
break;
case ThreatType::OnDeviceID:
UE_LOG(LogTemp, Warning, TEXT("Device ID threat detected"));
break;
case ThreatType::OnObfuscationIssues:
UE_LOG(LogTemp, Warning, TEXT("Obfuscation issues threat detected"));
break;
case ThreatType::OnScreenshot:
UE_LOG(LogTemp, Warning, TEXT("Screenshot threat detected"));
break;
case ThreatType::OnScreenRecording:
UE_LOG(LogTemp, Warning, TEXT("Screen recording threat detected"));
break;
case ThreatType::OnPasscode:
UE_LOG(LogTemp, Warning, TEXT("Passcode threat detected"));
break;
case ThreatType::OnPasscodeChange:
UE_LOG(LogTemp, Warning, TEXT("Passcode change threat detected"));
break;
case ThreatType::OnSecureHardwareNotAvailable:
UE_LOG(LogTemp, Warning, TEXT("Secure hardware not available threat detected"));
break;
case ThreatType::OnDevMode:
UE_LOG(LogTemp, Warning, TEXT("Dev mode threat detected"));
break;
case ThreatType::OnADBEnabled:
UE_LOG(LogTemp, Warning, TEXT("ADB enabled threat detected"));
break;
case ThreatType::OnSystemVPN:
UE_LOG(LogTemp, Warning, TEXT("System VPN threat detected"));
break;
case ThreatType::OnMultiInstance:
UE_LOG(LogTemp, Warning, TEXT("Multi instance threat detected"));
break;
case ThreatType::OnUnsecureWifi:
UE_LOG(LogTemp, Warning, TEXT("Unsecure WiFi threat detected"));
break;
case ThreatType::OnTimeSpoofing:
UE_LOG(LogTemp, Warning, TEXT("Time spoofing threat detected"));
break;
case ThreatType::OnLocationSpoofing:
UE_LOG(LogTemp, Warning, TEXT("Location spoofing threat detected"));
break;
case ThreatType::Unknown:
UE_LOG(LogTemp, Warning, TEXT("Unknown threat detected"));
break;
}
}void AFreeRASPPlayerController::HandleRASPExecutionStatus(RASPExecutionStatus RASPStatus)
{
switch (RASPStatus) {
case RASPExecutionStatus::Finished:
UE_LOG(LogTemp, Warning, TEXT("RASP execution finished - all checks completed"));
break;
}
}To complete the installation, please restart the Unreal Editor to allow it to detect the new plugin.
Detailed explanations of each configuration option are available on the and pages.
Configuration Options: AppBundleIds, AppTeamId, PackageName, SigningCertificates, AlternativeStores, WatcherEmail and IsProduction
Set up the Configuration for your app with your values, which are explained in more detail in API.
private companion object {
private const val EXPECTED_PACKAGE_NAME = "app.talsec.demo.freerasp" // Don't use Context.getPackageName!
private val EXPECTED_SIGNING_CERTIFICATE_HASH_BASE64 = arrayOf(
"mVr/qQLO8DKTwqlL+B1qigl9NoBnbiUs8b4c2Ewcz0k="
) // Replace with your release (!) signing certificate hashes
private const val WATCHER_MAIL = "your_email_address@example.com"
private val SUPPORTED_ALTERNATIVE_STORES = arrayOf(
"com.sec.android.app.samsungapps"
// add other stores, such as the Samsung Galaxy Store
)
private val IS_PROD = true
private val KILL_ON_BYPASS = true
}import app.talsec.rasp.security.api.TalsecConfig
override fun onCreate() {
...
val config = TalsecConfig.Builder(
EXPECTED_PACKAGE_NAME,
EXPECTED_SIGNING_CERTIFICATE_HASH_BASE64)
.watcherMail(WATCHER_MAIL)
.supportedAlternativeStores(SUPPORTED_ALTERNATIVE_STORES)
.prod(IS_PROD)
.killOnBypass(KILL_ON_BYPASS)
.build()
}RaspExecutionState listener, to get information about state of check execution:
Modify initialization of ThreatListener:
override fun onCreate() {
...
// Register the listeners
// You can choose which listeners to register based on your needs:
// Option A: Listens only for threats detected
// ThreatListener(threatDetectedListener).registerListener(this)
// Option B: Listens for threats detected and device state
// ThreatListener(threatDetectedListener, deviceStateListener).registerListener(this)
// Option C: Listens for threats detected and execution state
// ThreatListener(threatDetectedListener, raspExecutionListener).registerListener(this)
// Option D: Listens for all threats, device state, and execution state
ThreatListener(threatDetectedListener, deviceStateListener, raspExecutionListener).registerListener(this)
}(Optional) Screen Capture & Recording Protection:
You can use freeRASP to detect screenshots (onScreenshot), screen recordings (onScreenRecording).
To actively prevent capture entirely (resulting in a black screen), use Talsec.blockScreenCapture(activity, true). You can verify the blocking status using Talsec.isScreenCaptureBlocked(). For more details, see .
Prerequisites: Detection features require Android 14+ (Screenshots) or Android 15+ (Recordings) and specific permissions. Please ensure you have added them as described in the section.
Implementation: We recommend integrating these methods at the Application level using ActivityLifecycleCallbacks to ensure they cover the entire app lifecycle:
<uses-permission android:name="android.permission.DETECT_SCREEN_CAPTURE" />
<uses-permission android:name="android.permission.DETECT_SCREEN_RECORDING" /><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
maven { url = uri("https://europe-west3-maven.pkg.dev/talsec-artifact-repository/plugin") }
}
}
...
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven { url = uri("https://europe-west3-maven.pkg.dev/talsec-artifact-repository/common") }
maven { url = uri("https://europe-west3-maven.pkg.dev/talsec-artifact-repository/freerasp") }
}
}
...pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
maven { url 'https://europe-west3-maven.pkg.dev/talsec-artifact-repository/plugin' }
}
}
...
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven { url 'https://europe-west3-maven.pkg.dev/talsec-artifact-repository/common' }
maven { url 'https://europe-west3-maven.pkg.dev/talsec-artifact-repository/freerasp' }
}
}
...[versions]
...
talsecPlugin = "1.0.0"
[libraries]
...
[plugins]
...
talsec-plugin = { id = "app.talsec.plugin", version.ref = "talsecPlugin" }plugins {
...
alias(libs.plugins.talsec.plugin)
}
android {
...
talsec {
sdkVersion = "19.3.0"
}
}
dependencies {
...
}class FreeRaspApplication : Application() {
override fun onCreate() {
super.onCreate()
}
}<application
android:name=".FreeRaspApplication"
/>import app.talsec.rasp.security.api.ThreatListener
import app.talsec.rasp.security.api.SuspiciousAppInfo
val threatDetectedListener = object : ThreatListener.ThreatDetected() {
override fun onPrivilegedAccess() {
println("onPrivilegedAccess")
}
override fun onDebug() {
println("onDebug")
}
override fun onSimulator() {
println("onSimulator")
}
override fun onAppIntegrity() {
println("onAppIntegrity")
}
override fun onUnofficialStore() {
println("onUnofficialStore")
}
override fun onHooks() {
println("onHooks")
}
override fun onDeviceBinding() {
println("onDeviceBinding")
}
override fun onObfuscationIssues() {
println("onObfuscationIssues")
}
override fun onScreenshot() {
println("onScreenshot")
}
override fun onScreenRecording() {
println("onScreenRecording")
}
override fun onMultiInstance() {
println("onMultiInstance")
}
override fun onUnsecureWifi() {
println("onUnsecureWifi")
}
override fun onTimeSpoofing() {
println("onTimeSpoofing")
}
override fun onLocationSpoofing() {
println("onLocationSpoofing")
}
override fun onAutomation() {
println("onAutomation")
}
override fun onBootloader() {
println("onBootloader")
}
override fun onMalware(packageInfo: List<SuspiciousAppInfo>) {
println("onMalware")
}
}import app.talsec.rasp.security.api.ThreatListener
val deviceStateListener = object : ThreatListener.DeviceState() {
override fun onPasscode() {
println("onPasscode")
}
override fun onSecureHardwareNotAvailable() {
println("onSecureHardwareNotAvailable")
}
override fun onDevMode() {
println("onDevMode")
}
override fun onAdbEnabled() {
println("onAdbEnabled")
}
override fun onSystemVpn() {
println("onSystemVpn")
}
}import android.app.Activity
import android.os.Bundle
import app.talsec.rasp.security.api.Talsec
import app.talsec.rasp.security.api.ScreenProtector
class FreeRaspApplication : Application() {
override fun onCreate() {
...
registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
override fun onActivityCreated(activity: Activity, bundle: Bundle?) {
Talsec.blockScreenCapture(activity, false)
}
override fun onActivityStarted(activity: Activity) {}
override fun onActivityResumed(activity: Activity) {
ScreenProtector.registerScreenCallbacks(activity)
}
override fun onActivityPaused(activity: Activity) {
ScreenProtector.unregisterScreenCallbacks(activity)
}
override fun onActivityStopped(activity: Activity) {}
override fun onActivitySaveInstanceState(activity: Activity, bundle: Bundle) {}
override fun onActivityDestroyed(activity: Activity) {}
})
}
}import app.talsec.rasp.security.api.Talsec
import app.talsec.rasp.security.api.TalsecMode
override fun onCreate() {
...
Talsec.start(this, config, TalsecMode.BACKGROUND)
}android {
...
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}android {
// ...
buildTypes {
getByName("release") {
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android.txt"),
"proguard-rules.pro"
)
}
}
}import app.talsec.rasp.security.api.Talsec
import app.talsec.rasp.security.api.ExternalIdResult
// pass your custom data (as @NonNull String)
val yourCustomData = "user_123-456"
val result = Talsec.storeExternalId(this, yourCustomData)
when (result) {
is ExternalIdResult.Success -> {
println("External ID successfully set.")
}
is ExternalIdResult.Error -> {
println("Failed to set External ID: ${result.errorMsg}")
}
}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.
Make sure that Talsec's maven dependency is at the last position.
You have to use the same email for the Portal as you used for the watcherMail parameter.
import app.talsec.rasp.security.api.ThreatListener
val raspExecutionListener = object : ThreatListener.RaspExecutionState() {
override fun onAllChecksFinished() {
println("onAllChecksFinished")
}
}Example:
The freeRASP has the following prerequisites that must be met before starting.
The Android implementation uses Kotlin serialization plugin; following line has to be added to the plugins block in platforms/android/build.gradle:
plugins {
id 'org.jetbrains.kotlin.plugin.serialization' version '1.7.10'
}freeRASP requires minSdkVersion level of >=23, targetSdkVersion level of >=31, compileSdkVersion level of >=34, and Kotlin support.
Since freeRASP 8.0.0, it is also necessary to raise version of Kotlin above 2.0.0 in your project.
Add the following lines to the config.xml file in your project root directory.
Then run the following command to apply the preferences:
To and , add the following permission to your Android Manifest (via config.xml):
To utilize active protection, you can use
To receive whether the screen capture is blocked, you can use
For more details about all these screen capture methods, see .
freeRASP plugin uses Swift. Install the following plugin to support Swift in your project.
Install the plugin using Cordova CLI
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.
For Android apps, you must get your expected signing certificate hashes in Base64 form. You can go through to learn how to sign your app in more detail, including manual signing and using Google's Play app signing.
In the the entry point to your app, import freeRASP and add the code below.
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 in the wiki to learn more details about the performed checks and their importance for app security.
Threat reactions can be specified inside a JavaScript object, which is then passed into the initialization function:
freeRASP can also notify apps when initial checks are done using the raspExecutionStateActions callback:
freeRASP can be started after the Cordova initialization is completed, for example, inside the onDeviceReady function in the index.js.
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 so:
Additionally, create or extend proguard-rules.pro in android/app folder and exclude Cordova’s specific classes that rely on package names from being obfuscated:
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.
The externalId allows you to send a custom identifier (such as a User ID) to the . This identifier will be visible in the Dashboard, enabling you to correlate security incidents with specific users in your system.
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.
It helps to detect apps with suspicious package names, hashes, or potentially dangerous permissions.
Visit the repository to learn more about this feature! For the integration, refer to the for the Cordova platform.
Check out and register using your 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.
The freeRASP has the following prerequisites that must be met before starting.
freeRASP for Android requires a minSdkVersion level of >=23 and a targetSdkVersion level of >=36. Some Capacitor projects, by default, support even lower levels of minimum and target SDKs. This creates an inconsistency we must solve by updating the SDK levels of the application:
From the root of your project, go to android > variables.gradle (or equivalent).
The following structure outlines the critical directories and files you will interact with during the integration. The project is divided into the shared module (logic) and platform-specific modules (configuration).
Pay attention to the highlighted files, as these are the exact locations where you will apply changes in the upcoming steps.
The freeRASP has the following prerequisites that must be met before starting:
Kotlin version: 2.2.0
Minimum Android Target SDK: API Level 23
The freeMalware Detection module is configured directly in code — no external files or API calls are required. Pass your detection parameters through SuspiciousAppDetectionConfig (V2 API) or via the legacy configuration fields (V1 API).

In ext, update minSdkVersion to at least 23 (Android 6.0) or higher.
Since freeRASP 2.0.0, it is necessary to raise version of Kotlin in your project.
From the root of your project, go to android > build.gradle (or equivalent).
In buildscript.ext, update kotlin_version to at least 2.0.0 or higher.
To detect screenshots and screen recordings , add the following permissions to your AndroidManifest.xml file inside the <manifest> root tag:
To utilize active protection, you can use
To receive whether the screen capture is blocked, you can use
For more details about all these screen capture methods, see Screen Capture.
freeRASP ships both a CocoaPods podspec and a Swift Package Manager manifest. Which one gets used is determined entirely by which package manager your Capacitor iOS project itself uses — there is no freeRASP-specific configuration.
This is the default when you run npx cap add ios (or for an existing ios project). Just sync as usual:
npx cap sync iosIf your iOS project was created with Capacitor's Swift Package Manager support:
npx cap add ios --packagemanager SPMnpx cap sync ios automatically adds CapacitorFreerasp as a local Swift Package dependency in CapApp-SPM/Package.swift — no manual wiring needed.
Switching an existing CocoaPods-based ios project to SPM (or back) is a Capacitor project-level migration, not a freeRASP-specific step. See for details.
Install the plugin using your preferred package manager
Synchronize the project files across native platforms
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.
For Android apps, you must get your expected signing certificate hashes in Base64 form. You can go through this manual to learn how to sign your app in more detail, including manual signing and using Google's Play app signing.
In the the entry point to your app, import freeRASP and add the code below.
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 in the wiki to learn more details about the performed checks and their importance for app security.
Threat reactions can be specified inside a JavaScript object, which is then passed into the initialization function:
freeRASP can also notify apps when initial checks are done using the raspExecutionStateActions callback:
Pass the configuration and reactions you set up in previous steps into startFreeRASP function.
Based on your framework, we recommend:
In React: Wrap this function in useEffect with an empty dependency array
In Vue: Call the method inside the mounted property
In Angular: Call the method inside the ngOnInit method
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 so:
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.
The externalId allows you to send a custom identifier (such as a User ID) to the Talsec Portal. This identifier will be visible in the Dashboard, enabling you to correlate security incidents with specific users in your system.
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.
It helps to detect apps with suspicious package names, hashes, or potentially dangerous permissions.
Visit the freeMalwareDetection repository to learn more about this feature! For the integration, refer to the integration guide for the Capacitor platform.
Check out Data Visualisation Portal and register using your 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.
ext {
minSdkVersion 23
}buildscript {
ext {
kotlin_version = '2.0.0'
} <uses-permission android:name="android.permission.DETECT_SCREEN_CAPTURE" />
<uses-permission android:name="android.permission.DETECT_SCREEN_RECORDING" />import { blockScreenCapture } from 'capacitor-freerasp';
await blockScreenCapture(true);import { isScreenCaptureBlocked } from 'capacitor-freerasp';
const response = await isScreenCaptureBlocked();$ npm install capacitor-freerasp$ npx cap syncimport { startFreeRASP } from 'capacitor-freerasp';
// app configuration
const config = {
androidConfig: {
packageName: 'com.capacitor.example',
certificateHashes: ['mVr/qQLO8DKTwqlL+B1qigl9NoBnbiUs8b4c2Ewcz0k='], // replace with your release (!) signing certificate hash(es)
supportedAlternativeStores: ['com.sec.android.app.samsungapps'],
},
iosConfig: {
appBundleId: 'com.capacitor.example',
appTeamId: 'yourTeamID',
},
watcherMail: 'your_email_address@example.com', // for Security Reports, Talsec Portal, Updates
isProd: true,
killOnBypass: true,
};// reactions for detected threats
const actions = {
// Android & iOS
privilegedAccess: () => {
console.log('privilegedAccess');
},
// Android & iOS
debug: () => {
console.log('debug');
},
// Android & iOS
simulator: () => {
console.log('simulator');
},
// Android & iOS
appIntegrity: () => {
console.log('appIntegrity');
},
// Android & iOS
unofficialStore: () => {
console.log('unofficialStore');
},
// Android & iOS
hooks: () => {
console.log('hooks');
},
// Android & iOS
deviceBinding: () => {
console.log('deviceBinding');
},
// Android & iOS
secureHardwareNotAvailable: () => {
console.log('secureHardwareNotAvailable');
},
// Android & iOS
systemVPN: () => {
console.log('systemVPN');
},
// Android & iOS
passcode: () => {
console.log('passcode');
},
// iOS only
deviceID: () => {
console.log('deviceID');
},
// Android only
obfuscationIssues: () => {
console.log('obfuscationIssues');
},
// Android only
devMode: () => {
console.log('devMode');
},
// Android only
adbEnabled: () => {
console.log('adbEnabled');
},
// Android & iOS
screenshot: () => {
console.log('screenshot');
},
// Android & iOS
screenRecording: () => {
console.log('screenRecording');
},
// Android only
multiInstance: () => {
console.log('multiInstance');
},
// Android & iOS
timeSpoofing: () => {
console.log('timeSpoofing');
},
// Android only
locationSpoofing: () => {
console.log('locationSpoofing');
},
// Android only
unsecureWifi: () => {
console.log('unsecureWifi');
},
// Android only
automation: () => {
console.log('automation');
},
// Android only
bootloader: () => {
console.log('bootloader');
},
}; const raspExecutionStateActions = {
allChecksFinished: () => {
console.log('All checks finished');
}
};// returns `true` if freeRASP starts successfully; you can ignore this value
const started = await startFreeRASP(config, actions, raspExecutionStateActions);android {
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}import { storeExternalId } from 'capacitor-freerasp';
const yourCustomData = "user_123-456";
const result = await storeExternalId(yourCustomData);
if (result) {
console.log("External ID successfully set.");
} else {
console.log("Failed to set External ID. Check if it contains allowed characters.");
}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.
You have to use the same email for the Portal as you used for the watcherMail parameter.
Minimum iOS Deployment Target: 13.0
To enable the SDK, you must configure your project to access the required repositories and native binaries across all target platforms.
Update the settings.gradle.kts file to include the necessary URLs within the dependencyResolutionManagement block.
// File: settings.gradle.kts
dependencyResolutionManagement {
...
mavenCentral()
maven { url = uri("https://jitpack.io") }
maven { url = uri("https://europe-west3-maven.pkg.dev/talsec-artifact-repository/freerasp") }
...
}Ensure that the XCFramework dependencies are correctly linked and available to the iOS target of your Kotlin Multiplatform project.
Navigate to the Assets section of GitHub Releases and download the Frameworks.zip archive. This package contains the required binaries:
TalsecRuntime.xcframework
TalsecBridge.xcframework
Once downloaded, unzip (extract) the archive.
Navigate to the iosApp directory via terminal and launch the project in Xcode using the following commands:
In Xcode, navigate to the Project Navigator (left sidebar) and select your project root.
Select your application Target (usually named iosApp).
Scroll down to the Frameworks, Libraries, and Embedded Content section and click the + button at the bottom of the list.
Declare the dependencies in the build.gradle.kts file of your :composeApp or :shared module (typically inside the commonMain source set):
Some checks require additional permissions in order to work properly. Add the following permissions to your AndroidManifest.xml file inside the <manifest> root tag. If your app already has these permissions, you don't need to add them again.
Screenshot and Screen Recording Detection
To enable detection for screenshots and screen recordings, include these required permissions:
Location Spoofing Detection
To enable detection for location spoofing, include these required permissions:
Unsecure WiFi Detection
To enable detection for unsecure WiFi, include these required permissions:
To ensure freeRASP functions correctly in a Kotlin Multiplatform environment, you need to provide the necessary configuration within the shared module. All required values must be filled in for the plugin to operate properly.
Create a Security Manager
It is recommended to encapsulate the configuration and initialization logic into a separate singleton object (e.g. SecurityManager). This keeps your UI code clean and makes the security logic reusable.
Create a new file in your common source set and define the configuration:
Once the configuration is ready, you need to start the monitoring service and listen for incoming threats.
Implement Monitoring Logic
Update your SecurityManager to start the freeRASP engine and handle the threatEvents flow.
Implement Execution State Monitoring
In addition to threat events, freeRASP provides a dedicated flow for monitoring the SDK execution lifecycle. Subscribe to raspExecutionStateEvents to know when all security checks have completed.
Initialize in Entry Point
Code obfuscation (minification) is a critical security step that reduces the size of the compiled code and renames classes and variables to make reverse engineering significantly more difficult.
To enable obfuscation for the Android target, update the build.gradle.kts file in your shared module (usually :composeApp or :androidApp):
👉 Read more about the importance of obfuscation in the wiki. 👈
The externalId allows you to send a custom identifier (such as a User ID) to the Talsec Portal. This identifier will be visible in the Dashboard, enabling you to correlate security incidents with specific users in your system.
freeMalwareDetection is a powerful feature designed to enhance the security of your Android application. It quickly and efficiently scans for malicious or suspicious applications (e.g., Android malware) based on various blacklists and security policies.
This feature helps to detect apps with suspicious package names, hashes, or potentially dangerous permissions.
To learn more about this feature and its integration, please refer to the official documentation.
Check out Data Visualisation Portal and register using your 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.
[YourProjectName]/
├───build.gradle.kts
├───settings.gradle.kts <-- Step 1: Add Dependency Repositories
├───gradle.properties
├───gradle/
│ └───libs.versions.toml
├───composeApp/
│ ├───build.gradle.kts <-- Step 1: Add Dependencies & Obfuscation
│ └───src/
│ ├───commonMain/
│ │ └───kotlin/ <-- Step 3: Create SecurityManager.kt
│ ├───androidMain/
│ │ ├───kotlin/
│ │ └───AndroidManifest.xml <-- Step 2: Add Android Permissions
│ └───iosMain/
│ └───kotlin/
└───iosApp/
├───iosApp.xcodeproj/ <-- Step 2: Link Frameworks in Xcode
├───iosApp/
│ ├───ContentView.swift
│ └───iOSApp.swift
├───TalsecBridge.xcframework/ <-- Step 2: Native iOS dependency
└───TalsecRuntime.xcframework/ <-- Step 2: Native iOS dependency// File: composeApp/build.gradle.kts
android {
...
buildTypes {
getByName("release") {
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(getDefaultProguardFile("proguard-android.txt"),
"proguard-rules.pro")
}
}
}val yourCustomData = "user_123_456"
scope.launch {
try {
FreeraspKMP.storeExternalId(yourCustomData)
} catch (e: FreeraspKMPException) {
println("Failed to set External ID: ${e.message}")
}
}
//To remove a previously stored identifier:
scope.launch {
FreeraspKMP.removeExternalId()
}You have to use the same email for the Portal as you used for the watcherMail parameter.
packageNames
Set/List<String>
null
Package identifiers to explicitly blocklist.
hashes
Set/List<String>
null
SHA-256 APK hashes to explicitly blocklist.
requestedPermissions
Set/List<List<String>>
The scan scope determines which installed applications are subject to heuristic evaluation.
SIDELOADED_ONLY (default)
Evaluates non-system, non-OEM applications not installed from a trusted source.
SIDELOADED_AND_OEM
Includes OEM pre-installed applications.
SIDELOADED_AND_SYSTEM_EXCLUDE_OEM
trustedInstallSources
Accepts a list of installer package names (e.g., com.android.vending for Google Play). Applications installed from these sources are excluded from scope-based evaluation.
The reason mode determines the logic used to decide which applications are surfaced as threats based on the available signals.
HIGHEST_CONFIDENCE (default)
Flags scope-based results only when a permission match is also present. Blocklist matches are always included.
ALL
Flags every application within the configured scan scope, regardless of permission results.
val config = TalsecConfig.Builder(packageName, certificateHash)
.blacklistedPackageNames(arrayOf("com.suspicious.app"))
.blacklistedHashes(arrayOf("755ee39ff11bad65193c4806cadb9cedda41e20663c35494cb7d4e9646ddcf21"))
.suspiciousPermissions(arrayOf(
arrayOf("android.permission.READ_SMS"),
arrayOf("android.permission.BIND_ACCESSIBILITY_SERVICE")
))
.whitelistedInstallationSources(arrayOf("com.android.vending"))
.build()final config = TalsecConfig(
androidConfig: AndroidConfig(
packageName: packageName,
signingCertHashes: [certificateHash],
malwareConfig: MalwareConfig(
blacklistedPackageNames: ["com.suspicious.app"],
blacklistedHashes: ["755ee39ff11bad65193c4806cadb9cedda41e20663c35494cb7d4e9646ddcf21"],
suspiciousPermissions: [
["android.permission.READ_SMS"],
["android.permission.BIND_ACCESSIBILITY_SERVICE"]
],
whitelistedInstallationSources: ["com.android.vending"],
),
),
);const config: TalsecConfig = {
androidConfig: {
packageName: 'com.example.app',
certificateHashes: ['...'],
blacklistedPackageNames: ['com.suspicious.app'],
blacklistedHashes: ['755ee39ff11bad65193c4806cadb9cedda41e20663c35494cb7d4e9646ddcf21'],
suspiciousPermissions: [
['android.permission.READ_SMS'],
['android.permission.BIND_ACCESSIBILITY_SERVICE'],
],
whitelistedInstallationSources: ['com.android.vending'],
},
};const config: TalsecConfig = {
watcherMail: 'your@email.com',
androidConfig: {
packageName: 'com.example.app',
certificateHashes: ['...'],
malwareConfig: {
blacklistedPackageNames: ['com.suspicious.app'],
blacklistedHashes: ['755ee39ff11bad65193c4806cadb9cedda41e20663c35494cb7d4e9646ddcf21'],
suspiciousPermissions: [
['android.permission.READ_SMS'],
['android.permission.BIND_ACCESSIBILITY_SERVICE'],
['android.permission.REQUEST_INSTALL_PACKAGES'],
],
whitelistedInstallationSources: ['com.android.vending'],
},
},
};const config: TalsecConfig = {
watcherMail: 'your@email.com',
androidConfig: {
packageName: 'com.example.app',
certificateHashes: ['...'],
malwareConfig: {
blacklistedPackageNames: ['com.suspicious.app'],
blacklistedHashes: ['755ee39ff11bad65193c4806cadb9cedda41e20663c35494cb7d4e9646ddcf21'],
suspiciousPermissions: [
['android.permission.READ_SMS'],
['android.permission.BIND_ACCESSIBILITY_SERVICE'],
['android.permission.REQUEST_INSTALL_PACKAGES'],
],
whitelistedInstallationSources: ['com.android.vending'],
},
},
};val config = freeraspConfig(
watcherMail = "your@email.com",
androidConfig = AndroidConfig(
packageName = packageName,
certificateHashes = listOf(certificateHash),
malwareConfig = MalwareConfig(
blacklistedPackageNames = listOf("com.suspicious.app"),
blacklistedHashes = listOf("755ee39ff11bad65193c4806cadb9cedda41e20663c35494cb7d4e9646ddcf21"),
suspiciousPermissions = listOf(
listOf("android.permission.READ_SMS"),
listOf("android.permission.BIND_ACCESSIBILITY_SERVICE")
),
whitelistedInstallationSources = listOf("com.android.vending")
)
)
)blacklistedPackageNames
Array/List<String>
Package identifiers to explicitly blocklist.
blacklistedHashes
Array/List<String>
final detectionConfig = SuspiciousAppDetectionConfig(
packageNames: ["com.suspicious.app"],
hashes: ["755ee39ff11bad65193c4806cadb9cedda41e20663c35494cb7d4e9646ddcf21"],
requestedPermissions: [
["android.permission.READ_SMS"],
["android.permission.BIND_ACCESSIBILITY_SERVICE"],
["android.permission.REQUEST_INSTALL_PACKAGES"]
],
grantedPermissions: [
["android.permission.BIND_ACCESSIBILITY_SERVICE"]
],
scanScope: ScanScope(
scopeType: ScopeType.sideloadedOnly,
trustedInstallSources: ["com.android.vending"]
),
reasonMode: ReasonMode.highestConfidence,
);
final config = TalsecConfig(
androidConfig: AndroidConfig(
packageName: packageName,
signingCertHashes: [certificateHash],
suspiciousAppDetectionConfig: detectionConfig,
),
);const config: TalsecConfig = {
androidConfig: {
packageName: 'com.example.app',
certificateHashes: ['...'],
suspiciousAppDetectionConfig: {
packageNames: ['com.suspicious.app'],
hashes: ['755ee39ff11bad65193c4806cadb9cedda41e20663c35494cb7d4e9646ddcf21'],
requestedPermissions: [
['android.permission.READ_SMS'],
['android.permission.BIND_ACCESSIBILITY_SERVICE'],
['android.permission.REQUEST_INSTALL_PACKAGES'],
],
grantedPermissions: [
['android.permission.BIND_ACCESSIBILITY_SERVICE'],
],
scanScope: {
scopeType: 'SIDELOADED_ONLY',
trustedInstallSources: ['com.android.vending'],
},
reasonMode: 'HIGHEST_CONFIDENCE',
},
},
};const config: TalsecConfig = {
watcherMail: 'your@email.com',
androidConfig: {
packageName: 'com.example.app',
certificateHashes: ['...'],
suspiciousAppDetectionConfig: {
packageNames: ['com.suspicious.app'],
hashes: ['755ee39ff11bad65193c4806cadb9cedda41e20663c35494cb7d4e9646ddcf21'],
requestedPermissions: [
['android.permission.READ_SMS'],
['android.permission.BIND_ACCESSIBILITY_SERVICE'],
['android.permission.REQUEST_INSTALL_PACKAGES'],
],
grantedPermissions: [
['android.permission.BIND_ACCESSIBILITY_SERVICE'],
],
scanScope: {
scopeType: 'SIDELOADED_ONLY',
trustedInstallSources: ['com.android.vending'],
},
reasonMode: 'HIGHEST_CONFIDENCE',
},
},
};const config: TalsecConfig = {
watcherMail: 'your@email.com',
androidConfig: {
packageName: 'com.example.app',
certificateHashes: ['...'],
suspiciousAppDetectionConfig: {
packageNames: ['com.suspicious.app'],
hashes: ['755ee39ff11bad65193c4806cadb9cedda41e20663c35494cb7d4e9646ddcf21'],
requestedPermissions: [
['android.permission.READ_SMS'],
['android.permission.BIND_ACCESSIBILITY_SERVICE'],
['android.permission.REQUEST_INSTALL_PACKAGES'],
],
grantedPermissions: [
['android.permission.BIND_ACCESSIBILITY_SERVICE'],
],
scanScope: {
scopeType: 'SIDELOADED_ONLY',
trustedInstallSources: ['com.android.vending'],
},
reasonMode: 'HIGHEST_CONFIDENCE',
},
},
};val detectionConfig = SuspiciousAppDetectionConfig(
packageNames = listOf("com.suspicious.app"),
hashes = listOf("755ee39ff11bad65193c4806cadb9cedda41e20663c35494cb7d4e9646ddcf21"),
requestedPermissions = listOf(
listOf("android.permission.READ_SMS"),
listOf("android.permission.BIND_ACCESSIBILITY_SERVICE"),
listOf("android.permission.REQUEST_INSTALL_PACKAGES")
),
grantedPermissions = listOf(
listOf("android.permission.BIND_ACCESSIBILITY_SERVICE")
),
scanScope = ScanScope(
scopeType = ScopeType.SIDELOADED_ONLY,
trustedInstallSources = listOf("com.android.vending")
),
reasonMode = ReasonMode.HIGHEST_CONFIDENCE
)
val config = freeraspConfig(
watcherMail = "your@email.com",
androidConfig = AndroidConfig(
packageName = packageName,
certificateHashes = listOf(certificateHash),
suspiciousAppDetectionConfig = detectionConfig
)
)Compatibility
The V2 configuration API is available from the following minimum SDK versions:
Android: 18.1.0 | Flutter: 8.0.0 | React Native: 5.0.0 |
Capacitor: 3.0.0 | Cordova: 9.0.0 | KMP: 2.0.0
val detectionConfig = SuspiciousAppDetectionConfig(
packageNames = setOf("com.suspicious.app"),
hashes = setOf("755ee39ff11bad65193c4806cadb9cedda41e20663c35494cb7d4e9646ddcf21"),
requestedPermissions = setOf(
setOf("android.permission.READ_SMS"),
setOf("android.permission.BIND_ACCESSIBILITY_SERVICE"),
setOf("android.permission.REQUEST_INSTALL_PACKAGES")
),
grantedPermissions = setOf(
setOf("android.permission.BIND_ACCESSIBILITY_SERVICE")
),
malwareScanScope = MalwareScanScope(
scanScope = ScopeType.SIDELOADED_ONLY,
trustedInstallSources = listOf("com.android.vending")
),
reasonMode = ReasonMode.HIGHEST_CONFIDENCE
)
val config = TalsecConfig.Builder(packageName, certificateHash)
.suspiciousAppDetectionConfig(detectionConfig)
.build()Compatibility
The legacy V1 API is only supported in SDK versions prior to the V2 update (listed below). It does not provide reasonMode control, requestedPermissions, or granular scan scoping, and defaults to ALL mode.
Android: <18.1.0
<preference name="GradlePluginKotlinEnabled" value="true" />
<preference name="GradlePluginKotlinCodeStyle" value="official" />
<preference name="GradlePluginKotlinVersion" value="2.0.0" />
<preference name="android-minSdkVersion" value="23" />
<preference name="android-targetSdkVersion" value="31" />
<preference name="android-compileSdkVersion" value="34" />$ cordova prepare android <platform name="android">
<config-file target="AndroidManifest.xml" parent="/*">
<uses-permission android:name="android.permission.DETECT_SCREEN_CAPTURE" />
<uses-permission android:name="android.permission.DETECT_SCREEN_RECORDING" />
</config-file>
</platform>await talsec.blockScreenCapture(true);const response = await talsec.isScreenCaptureBlocked();$ cordova plugin add cordova-plugin-add-swift-support --savecordova plugin add cordova-talsec-plugin-freerasp/* global cordova, talsec */
const config = {
androidConfig: {
packageName: 'com.example.helloapp',
certificateHashes: ['mVr/qQLO8DKTwqlL+B1qigl9NoBnbiUs8b4c2Ewcz0k='], // replace with your release (!) signing certificate hash(es)
supportedAlternativeStores: ['com.sec.android.app.samsungapps'],
},
iosConfig: {
appBundleIds: 'com.example.helloapp',
appTeamId: 'your_team_ID'
},
watcherMail: 'your_email_address@example.com', // for Security Reports, Talsec Portal, Updates
isProd: true,
killOnBypass: true
};// reactions to detected threats
const actions = {
// Android & iOS
privilegedAccess: () => {
console.log('privilegedAccess');
},
// Android & iOS
debug: () => {
console.log('debug');
},
// Android & iOS
simulator: () => {
console.log('simulator');
},
// Android & iOS
appIntegrity: () => {
console.log('appIntegrity');
},
// Android & iOS
unofficialStore: () => {
console.log('unofficialStore');
},
// Android & iOS
hooks: () => {
console.log('hooks');
},
// Android & iOS
deviceBinding: () => {
console.log('deviceBinding');
},
// Android & iOS
secureHardwareNotAvailable: () => {
console.log('secureHardwareNotAvailable');
},
// Android & iOS
systemVPN: () => {
console.log('systemVPN');
},
// Android & iOS
passcode: () => {
console.log('passcode');
},
// iOS only
deviceID: () => {
console.log('deviceID');
},
// Android only
obfuscationIssues: () => {
console.log('obfuscationIssues');
},
// Android only
devMode: () => {
console.log('devMode');
},
// Android only
adbEnabled: () => {
console.log('adbEnabled');
},
// Android & iOS
screenshot: () => {
console.log('screenshot');
},
// Android & iOS
screenRecording: () => {
console.log('screenRecording');
},
// Android only
multiInstance: () => {
console.log('multiInstance');
},
// Android & iOS
timeSpoofing: () => {
console.log('timeSpoofing');
},
// Android only
locationSpoofing: () => {
console.log('locationSpoofing');
},
// Android only
unsecureWifi: () => {
console.log('unsecureWifi');
},
// Android only
automation: () => {
console.log('automation');
},
// Android only
bootloader: () => {
console.log('bootloader');
},
}; const raspExecutionStateActions = {
allChecksFinished: () => {
console.log('All checks finished');
}
};import { Talsec } from 'cordova-talsec-plugin-freerasp'; // import of type declaration
declare var talsec: Talsec; // interface declaration for .ts projects
talsec.start(config, actions, raspExecutionStateActions)
.then(() => {
console.log('Talsec initialized.');
})
.catch((error) => {
console.log('Error during Talsec initialization: ', error);
});android {
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
}
}
}-keep class org.apache.cordova.** {*;}
-keep public class * extends org.apache.cordova.CordovaPlugin
-flattenpackagehierarchyimport { Talsec } from 'cordova-talsec-plugin-freerasp';
declare var talsec: Talsec;
const yourCustomData = "user_123-456";
const result = await talsec.storeExternalId(yourCustomData);
if (result) {
console.log("External ID successfully set.");
} else {
console.log("Failed to set External ID. Check if it contains allowed characters.");
}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.
Skip this step if you are using "cordova-ios": "^8.0.0" or newer
You have to use the same email for the Portal as you used for the watcherMail parameter.
These classes define the behavior of the freeRASP SDK. You must instantiate freeraspConfig to pass it into the start() method.
class freeraspConfig
The root configuration object required to initialize the SDK.
class AndroidConfig
Settings specific to the Android platform.
class IOSConfig
Settings specific to the iOS platform.
class MalwareConfig
Advanced configuration for the Malware Detection feature (Android only).
object FreeraspKMP
The main singleton object used to interact with the library.
start(config)
Initializes and starts the freeRASP protection.
addToWhiteList(packageName)
Adds a package name to the whitelist. Useful if the malware detector falsely flags a legitimate app.
blockScreenCapture(enable)
Enables or disables protection against screen recording and screenshots.
enable: Set to true to block capture, false to allow it.
isScreenCaptureBlocked()
Checks if screen capture blocking is currently active.
Returns: true if blocked, false otherwise.
getAppIcon(packageName)
Retrieves the icon of an installed application as a Base64 string.
Returns: Base64 encoded string of the icon.
storeExternalId(data)
Stores an external identifier (e.g., User ID) to correlate reports in the Talsec Dashboard.
removeExternalId()
Removes a previously stored external identifier.
All events inherit from sealed class FreeRaspEvent. They are emitted via the threatEvents flow.
For a detailed description of each event and its security implications, please refer to the .
class SuspiciousAppDetectionConfig
Advanced configuration for the Malware Detection feature (Android only).
For full details on ScanScope, ScopeType, and ReasonMode behavior, see the.
data class SuspiciousAppInfo
Found inside the payload of the Malware event.
data class PackageInfo
Contains metadata about an installed application.
<8.0.0<5.0.0Capacitor: <3.0.0 | Cordova: <9.0.0 | KMP: <2.0.0
null
Permission sets — flagged if all permissions in any set appear in the app's manifest.
grantedPermissions
Set/List<List<String>>
null
Permission sets — flagged if all permissions in any set are actively granted by the user.
malwareScanScope (Android) / scanScope (others)
MalwareScanScope / ScanScope
SIDELOADED_ONLY, no trusted sources
Controls which applications enter the scan. See Scan Scope below.
reasonMode
ReasonMode
HIGHEST_CONFIDENCE
Controls the detection decision logic. See Reason Mode below.
Includes system applications, excludes OEM.
SIDELOADED_AND_SYSTEM_AND_OEM
Includes all non-trusted applications regardless of origin.
ALL
Evaluates every installed application without exception.
SHA-256 APK hashes to explicitly blocklist.
suspiciousPermissions
Array/List<List<String>>
Permission sets — flagged if all permissions in any set are actively granted.
whitelistedInstallationSources
Array/List<String>
Trusted installer package names. Apps from unlisted sources are treated as sideloaded.
killOnBypasswatcherMail - By providing your watcherMail, you consent to receive security reports, product updates, and other essential communications from Talsec. Learn more about the role of watcherMail.
In the dialog window, click the Add Other... button at the bottom left, then select Add Files... from the pop-up menu to browse your local storage.
Locate and select both TalsecRuntime.xcframework and TalsecBridge.xcframework.
Once added, ensure that the Embed option for both frameworks is set to Embed & Sign.
start method from your main UI entry point (e.g., App.kt) using a LaunchedEffect. This ensures monitoring begins as soon as the app launches.cd iosApp
open iosApp.xcodeproj// File: build.gradle.kts (usually inside :composeApp or :shared)
kotlin {
...
sourceSets {
...
commonMain.dependencies {
...
implementation("com.aheaditec.talsec.security:freeRASP_KMP:1.1.0")
...
}
...
}
}<uses-permission android:name="android.permission.DETECT_SCREEN_CAPTURE" />
<uses-permission android:name="android.permission.DETECT_SCREEN_RECORDING" /><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />// File: composeApp/src/commonMain/kotlin/.../SecurityManager.kt
object SecurityManager {
private val config = freeraspConfig(
watcherMail = "your_email_address@example.com", // for Security Reports, Talsec Portal, Updates
androidConfig = AndroidConfig(
packageName = "your.package.name",
certificateHashes = listOf("mVr/qQLO8DKTwqlL+B1qigl9NoBnbiUs8b4c2Ewcz0k=")
),
iosConfig = IOSConfig(
bundleIds = listOf("your.bundle.id"),
teamId = "YOUR_TEAM_ID"
),
isProd = true,
killOnBypass = true
)
// Initialization logic will be added in the next step
suspend fun start(scope: CoroutineScope) {
// ...
}
}// File: composeApp/src/commonMain/kotlin/.../SecurityManager.kt
suspend fun start(scope: CoroutineScope){
FreeraspKMP.threatEvents.onEach { event ->
when (event) {
is FreeRaspEvent.AdbEnabled -> TODO()
is FreeRaspEvent.AppIntegrity -> TODO()
is FreeRaspEvent.Debug -> TODO()
is FreeRaspEvent.DevMode -> TODO()
is FreeRaspEvent.DeviceBinding -> TODO()
is FreeRaspEvent.DeviceID -> TODO()
is FreeRaspEvent.Malware -> TODO()
is FreeRaspEvent.MultiInstance -> TODO()
is FreeRaspEvent.ObfuscationIssues -> TODO()
is FreeRaspEvent.Passcode -> TODO()
is FreeRaspEvent.PrivilegedAccess -> TODO()
is FreeRaspEvent.ScreenRecording -> TODO()
is FreeRaspEvent.Screenshot -> TODO()
is FreeRaspEvent.SecureHardwareNotAvailable -> TODO()
is FreeRaspEvent.Simulator -> TODO()
is FreeRaspEvent.SystemVPN -> TODO()
is FreeRaspEvent.UnofficialStore -> TODO()
is FreeRaspEvent.Hooks -> TODO()
is FreeRaspEvent.LocationSpoofing -> TODO()
is FreeRaspEvent.TimeSpoofing -> TODO()
is FreeRaspEvent.UnsecureWifi -> TODO()
is FreeRaspEvent.Automation -> TODO()
is FreeRaspEvent.Bootloader -> TODO()
}
}.flowOn(Dispatchers.IO)
.launchIn(scope)
try {
FreeraspKMP.start(config)
// Optional: Configure additional protections
FreeraspKMP.blockScreenCapture(true)
} catch (e: Exception) {
println("Error starting freeRASP: ${e.message}")
}
}FreeraspKMP.raspExecutionStateEvents.onEach { event ->
when(event) {
is RaspExecutionStateEvent.AllChecksFinished -> TODO()
}
}.launchIn(scope)Support Limitations
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 FreeraspKMP.lockScreenCapture(true) disables this callback.


<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />// File: composeApp/src/commonMain/kotlin/.../App.kt
@Composable
fun App() {
MaterialTheme {
// Start security monitoring when the App composable enters the composition
LaunchedEffect(Unit) {
SecurityManager.start(this)
}
// ... Rest of your UI content
}
}Required. The email address where security reports will be sent.
isProd
Boolean
true
If true, the SDK runs in production mode. If false, strict checks are disabled for development.
killOnBypass
Boolean
true
If true, the app will terminate automatically when a critical threat (e.g., Hooking, Debugging) is detected.
List<String>
-
A list of expected signing certificate hashes (Base64 encoded).
supportedAlternativeStores
List<String>
[]
A list of allowed alternative app stores .
malwareConfig
MalwareConfig?
null
Optional configuration for the Malware Detection module.
String
-
The Apple Team ID associated with your developer account.
List<String>
[]
A list of certificate hashes for blacklisted apps.
suspiciousPermissions
List<String>
[]
A list of suspicious permission combinations.
whitelistedInstallationSources
List<String>
[]
A list of trusted installation sources (stores).
Detects if a Debugger is attached to the application.
Simulator
🤖 🍎
Detects if the app is running on an Emulator or Simulator.
AppIntegrity
🤖 🍎
Detects if the app signature or checksum has been tampered with.
UnofficialStore
🤖 🍎
Detects if the app was installed from an unrecognized source.
Hooks
🤖 🍎
Detects hooking frameworks (e.g., Frida, Xposed) injected into the process.
DeviceBinding
🤖 🍎
Detects if the device identity or cryptographic keys have changed.
Screenshot
🤖 🍎
Notification that a screenshot was taken.
ScreenRecording
🤖 🍎
Notification that screen recording is active.
Passcode
🤖 🍎
Detects if the device is not protected by a lock screen.
SecureHardwareNotAvailable
🤖 🍎
Detects if the hardware-backed keystore is unavailable.
SystemVPN
🤖 🍎
Detects if a system-wide VPN is active.
DeviceID
🍎
Indicates that the unique device identifier has changed or is inconsistent.
ObfuscationIssues
🤖
Detects if the code is not properly obfuscated (missing ProGuard/R8).
DevMode
🤖
Detects if Developer Options are enabled in settings.
AdbEnabled
🤖
Detects if USB Debugging (ADB) is active.
MultiInstance
🤖
Detects App Cloning (multiple instances running).
UnsecureWifi
🤖
Detects connection to an unencrypted Wi-Fi network.
TimeSpoofing
🤖🍎
Detects manual manipulation of system time.
LocationSpoofing
🤖
Detects attempts to falsify the device’s location to bypass geofences or fake presence.
Automation
🤖
Detects automation frameworks (e.g. Appium)
Bootloader
🤖
Detects that the device bootloader is unlocked or otherwise compromised.
Malware
🤖
Detects suspicious applications. Contains suspiciousAppInfo.
List<String>?
null
Certificate hashes of known malicious apps.
requestedPermissions
List<List<String>>?
null
Permission groups an app must request to be flagged as suspicious.
grantedPermissions
List<List<String>>?
null
Permission groups an app must be actively granted to be flagged as suspicious.
scanScope
ScanScope
ScanScope(ScopeType.SIDELOADED_ONLY)
Defines which installed apps are scanned.
reasonMode
ReasonMode
ReasonMode.HIGHEST_CONFIDENCE
Controls how detection reasons are reported.
permissions
List<String>
List of permissions declared by the suspicious app.
version
String?
The version of the app.
appIcon
String?
The app icon as a Base64 encoded string.
installerStore
String?
The store from which the app was installed.
androidConfig
AndroidConfig?
null
Configuration specific to the Android platform.
iosConfig
IOSConfig?
null
Configuration specific to the iOS platform.
watcherMail
String
packageName
String
-
The expected package name of the app.
bundleIds
List<String>
-
A list of expected Bundle IDs for the app.
blacklistedPackageNames
List<String>
[]
A list of package names that should trigger a malware alert.
threatEvents
SharedFlow<FreeRaspEvent>
A stream of security events detected by the SDK. Subscribe to this flow to react to threats in real-time.
raspExecutionStateEvents
SharedFlow<RaspExecutionStateEvent>
suspend fun start(config: freeraspConfig)suspend fun addToWhiteList(packageName: String)suspend fun blockScreenCapture(enable: Boolean)suspend fun isScreenCaptureBlocked(): Booleansuspend fun getAppIcon(packageName: String): Stringsuspend fun storeExternalId(data: String)suspend fun removeExternalId()PrivilegedAccess
🤖 🍎
Detects Root (Android) or Jailbreak (iOS) access.
Debug
AllChecksFinished
🤖 🍎
Confirms that the initialization is complete and all active security checks have been executed.
packageNames
List<String>?
null
Package names of known malicious apps.
packageInfo
PackageInfo
Detailed information about the detected application.
reasons
Set<String>
packageName
String
The unique package name (Application ID).
appName
String?
-
certificateHashes
teamId
blacklistedHashes
A stream of RASP execution lifecycle events. Subscribe to receive execution state updates such as AllChecksFinished.
🤖 🍎
hashes
The specific detection rule that triggered the alert (e.g., "Blacklisted Package" or "Suspicious Permissions").
The name of the app.
Example:
The freeRASP has the following prerequisites that must be met before starting:
Minimum SDK level: 23 or higher
Gradle version: 8.12.1 or higher
Compile SDK version: 36
Kotlin version: 2.1.0
Some versions of Flutter projects, by default, support lower levels of minimum SDK or Gradle version.
From the root of your project, go to android > app > build.gradle
In defaultConfig, update minSdkVersion property to at least 23 (Android 6.0) or higher.
From the root of your project, go to android > settings.gradle
In plugins
Update version of com.android.application
In older projects using imperative approach, the paths may be different:
From the root of your project, go to android > build.gradle
In dependencies , update version of com.android.tools.build:gradle dependecy to 8.8.1
Then you also need to update gradle wrapper:
From the root of your project, go to android > gradle> wrapper > gradle-wrapper.properties
In distributionUrl update version to 8.12.1
Some checks require additional permissions in order to work properly. If your app already has these permissions, you don't need to add them again.
To and screen recordings , add the following permissions to your AndroidManifest.xml file inside the <manifest> root tag:
To detect location spoofing, add the following permissions to your AndroidManifest.xml file inside the <manifest> root tag:
To detect unsecure WiFi, add the following permissions to your AndroidManifest.xml file inside the <manifest> root tag:
To utilize active protection, you can use
To check whether the screen capture is blocked, you can use:
For more details about all these screen capture methods, see .
By default, freeRASP's iOS binary is integrated as a vendored CocoaPods framework. Alternatively, you can integrate it as a Swift Package through Flutter's built-in Swift Package Manager support.
Select your preferred installation method below.
This is the default method — no extra configuration is required. Flutter resolves and installs the freerasp pod automatically when you build or run the app:
If you ever need to manually (re)install the pods, navigate to the ios directory and run the dependency installer:
Integrate freeRASP's iOS binary as a Swift Package using Flutter's built-in support. Flutter handles the Xcode project migration and package linking automatically.
Turn on Flutter's Swift Package Manager support:
Run the following command inside the project directory to add the freeRASP dependency:
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. Detailed descriptions of the configuration options are provided.
For Android apps, you must get your expected signing certificate hashes in Base64 form. You can go through to learn how to sign your app in more detail, including manual signing and using Google's Play app signing.
In the entry point to your app, import freeRASP and add the following code:
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 in the wiki to learn more details about the performed checks and their importance for app security.
freeRASP reacts to threats using ThreatCallback. Internally, each threat has its own callback (of VoidCallback type), which is called when a threat is detected.
Optionally, you can implement RaspExecutionStateCallback to listen whether initial checks were done or not:
Start freeRASP to detect threats just by adding this line below the created config and the callback handler:
In order to provide as much protection as possible, freeRASP enhances security measures by implementing ProGuard consumer rules, which obfuscate specific sections of the SDK. However, these rules are applied to your Android app code as well due to inheritance.
In certain cases, you may prefer to exclude this rule.
To remove the rule, you need to find freerasp in your cache folder. More about where to find the cache folder . Then navigate to the freerasp-X.Y.Z/android/build.gradle file and delete the line:
Read more about why obfuscation is important in the.
The externalId allows you to send a custom identifier (such as a User ID) to the . This identifier will be visible in the Dashboard, enabling you to correlate security incidents with specific users in your system.
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.
It helps to detect apps with suspicious package names, hashes, or potentially dangerous permissions.
Visit the repository to learn more about this feature! For the integration, refer to the for the Flutter platform.
Check out and register using your 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.
Example:
The freeRASP has the following prerequisites that must be met before starting.
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.
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.
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
To and , add the following permissions to your AndroidManifest.xml file inside the <manifest> root tag:
To utilize active protection, you can use
To receive whether the screen capture is blocked, you can use
For more details about all these screen capture methods, see .
By default, freeRASP's iOS binary is integrated as a vendored CocoaPods framework. Alternatively, you can integrate it as a Swift Package.
Select your preferred installation method below.
Navigate to the ios folder and run:
Integrate freeRASP's iOS binary as a Swift Package by gating the setup behind an environment variable in your Podfile.
Enforce dynamic frameworks when SPM is requested, and embed the package inside your existing post_install block:
Install the plugin using your preferred package manager
Navigate to the ios folder and run:
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.
In the the entry point to your app, import freeRASP and add the code below.
For Android apps, you must get your expected signing certificate hashes in Base64 form. You can go through to learn how to sign your app in more detail, including manual signing and using Google's Play app signing.
FreeRASP provides a React Custom Hook that handles all required logic as registration of freeRASP, mounting and unmounting of listeners for you.
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 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.
freeRASP can also notify apps when initial checks are done using the raspExecutionStateActions callback:
Start freeRASP to detect threats by calling the useFreeRasp hook, below the created config and the callback handler:
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.
Import methods from the freeRASP plugin:
Override componentDidMount() method in the entry point to your app set listeners to threats and start freeRASP:
Override componentWillUnmount() method where you clean up the listeners:
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:
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.
The externalId allows you to send a custom identifier (such as a User ID) to the . This identifier will be visible in the Dashboard, enabling you to correlate security incidents with specific users in your system.
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.
It helps to detect apps with suspicious package names, hashes, or potentially dangerous permissions.
Visit the repository to learn more about this feature! For the integration, refer to the for the React Native platform.
Check out and register using your 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.
Compare freeRASP and RASP+ features, pricing plans, and use cases, and discover how Talsec’s multi-layered app and API protection helps secure mobile apps, APIs, and users against modern threats.
L0 - Detect Attacks: Check app security state with & insights
L1 - Protect App: Pass pentests, combat reverse engineering, and comply with regulations with and
L2 - Protect Transactions: Combat API abuse, bots, web-scraping and MiTM with


<uses-permission android:name="android.permission.DETECT_SCREEN_CAPTURE" />
<uses-permission android:name="android.permission.DETECT_SCREEN_RECORDING" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />Update version of org.jetbrains.kotlin.android plugin to 2.1.0
android {
compileSdk 35
// ... some other declarations ...
defaultConfig {
minSdkVersion 23
// ... some other declarations ...
}
}plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "8.8.1" apply false
id "org.jetbrains.kotlin.android" version "2.1.0" apply false
}dependencies {
classpath 'com.android.tools.build:gradle:8.8.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12.1-all.zip<uses-permission android:name="android.permission.DETECT_SCREEN_CAPTURE" />
<uses-permission android:name="android.permission.DETECT_SCREEN_RECORDING" /><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />await Talsec.instance.blockScreenCapture(enabled: true)await Talsec.instance.isScreenCaptureBlocked()flutter run # or: flutter build ioscd ios
pod installflutter config --enable-swift-package-managerflutter pub add freeraspimport 'package:freerasp/freerasp.dart';
void main() {
// This line is important!
WidgetsFlutterBinding.ensureInitialized();
// create a configuration for freeRASP
final config = TalsecConfig(
/// For Android
androidConfig: AndroidConfig(
packageName: 'your.package.name',
signingCertHashes: [
'mVr/qQLO8DKTwqlL+B1qigl9NoBnbiUs8b4c2Ewcz0k='
], // Replace with your release (!) signing certificate hash(es)
supportedStores: ['com.sec.android.app.samsungapps'],
),
/// For iOS
iosConfig: IOSConfig(
bundleIds: ['YOUR_APP_BUNDLE_ID'],
teamId: 'M8AK35...',
),
watcherMail: 'your_email_address@example.com', // for Security Reports, Talsec Portal, Updates
isProd: true,
killOnBypass: true,
);
}import 'package:freerasp/freerasp.dart';
void main() {
// Setting up callbacks
final callback = ThreatCallback(
onAppIntegrity: () => print("App integrity"),
onObfuscationIssues: () => print("Obfuscation issues"),
onDebug: () => print("Debugging"),
onDeviceBinding: () => print("Device binding"),
onDeviceID: () => print("Device ID"),
onHooks: () => print("Hooks"),
onPasscode: () => print("Passcode not set"),
onPrivilegedAccess: () => print("Privileged access"),
onSecureHardwareNotAvailable: () => print("Secure hardware not available"),
onSimulator: () => print("Simulator"),
onSystemVPN: () => print("System VPN"),
onDevMode: () => print("Developer mode"),
onADBEnabled: () => print("USB debugging enabled"),
onUnofficialStore: () => print("Unofficial store"),
onScreenshot: () => print("Screenshot"),
onScreenRecording: () => print("Screen recording"),
onMultiInstance: () => print("Multi instance"),
onUnsecureWifi: () => print("Unsecure wifi"),
onLocationSpoofing: () => print("Location spoofing"),
onTimeSpoofing: () => print("Time spoofing"),
onAutomation: () => print("Automation detected"),
onBootloader: () => print("Bootloader unlocked or compromised"),
onMalware: (suspiciousApps) => print("Suspicous apps")
);
// Attaching listener
Talsec.instance.attachListener(callback);
}import 'package:freerasp/freerasp.dart';
void main() {
// Some other code...
final raspExecutionStateCallback = RaspExecutionStateCallback(
onAllChecksFinished: () => print("All checks finished")
// Attaching listener
Talsec.instance.attachExecutionStateListener(callback);
}void main() async {
// start freeRASP
await Talsec.instance.start(config);
}consumerProguardFiles 'consumer-rules.pro'// pass your custom data (as String)
final yourCustomData = "user_123-456";
try {
await Talsec.instance.storeExternalId(yourCustomData);
print("External ID successfully set.");
} on ExternalIdFailureException catch(e) {
print("Failed to set External ID: ${e.message}");
}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.
Requirement Xcode 15+ is required to build the application.
It is necessary that Flutter Bindings are initialized. This can be satisfied by calling WidgetsFlutterBinding.ensureInitialized(), as shown in the code snippet above.
You have to use the same email for the Portal as you used for the watcherMail parameter.
Reverting to CocoaPods
To revert to the default CocoaPods framework, disable Swift Package Manager and clean your build:
If your project was already migrated to SPM, you must also manually clean up the Xcode project:
buildscript.dependencieskotlin-gradle-pluginbuildscript {
ext {
minSdkVersion 23
}
}buildscript {
ext {
kotlinVersion = '2.0.0'
}
dependencies {
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.0")
} <uses-permission android:name="android.permission.DETECT_SCREEN_CAPTURE" />
<uses-permission android:name="android.permission.DETECT_SCREEN_RECORDING" />import { blockScreenCapture } from 'freerasp-react-native';
await blockScreenCapture(true);import { isScreenCaptureBlocked } from 'freerasp-react-native';
const response = await isScreenCaptureBlocked();cd ios
pod installplatform :ios, min_ios_version_supported
prepare_react_native_project!
# Swift Package Manager integration requires dynamically linked frameworks
use_freerasp_spm = ENV['FREERASP_USE_SPM'] == '1'
use_frameworks! :linkage => :dynamic if use_freerasp_spm
target 'YourApp' do
# ... your existing configuration ...
post_install do |installer|
# ... your existing post_install logic (react_native_post_install, etc.) ...
require_relative '../node_modules/freerasp-react-native/freerasp_spm.rb'
freerasp_embed_talsec_spm!(installer)
end
endnpm install freerasp-react-nativeyarn add freerasp-react-native$ pod installimport { 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,
};// reactions for detected threats
const actions = {
// Android & iOS
privilegedAccess: () => {
console.log('privilegedAccess');
},
// Android & iOS
debug: () => {
console.log('debug');
},
// Android & iOS
simulator: () => {
console.log('simulator');
},
// Android & iOS
appIntegrity: () => {
console.log('appIntegrity');
},
// Android & iOS
unofficialStore: () => {
console.log('unofficialStore');
},
// Android & iOS
hooks: () => {
console.log('hooks');
},
// Android & iOS
deviceBinding: () => {
console.log('deviceBinding');
},
// Android & iOS
secureHardwareNotAvailable: () => {
console.log('secureHardwareNotAvailable');
},
// Android & iOS
systemVPN: () => {
console.log('systemVPN');
},
// Android & iOS
passcode: () => {
console.log('passcode');
},
// iOS only
deviceID: () => {
console.log('deviceID');
},
// Android only
obfuscationIssues: () => {
console.log('obfuscationIssues');
},
// Android only
devMode: () => {
console.log('devMode');
},
// Android only
adbEnabled: () => {
console.log('adbEnabled');
},
// Android & iOS
screenshot: () => {
console.log('screenshot');
},
// Android & iOS
screenRecording: () => {
console.log('screenRecording');
},
// Android only
multiInstance: () => {
console.log('multiInstance');
},
// Android & iOS
timeSpoofing: () => {
console.log('timeSpoofing');
},
// Android only
locationSpoofing: () => {
console.log('locationSpoofing');
},
// Android only
unsecureWifi: () => {
console.log('unsecureWifi');
},
// Android only
automation: () => {
console.log('automation');
},
// Android only
bootloader: () => {
console.log('bootloader');
},
}; const raspExecutionStateActions = {
allChecksFinished: () => {
console.log('allChecksFinished');
},
};useFreeRasp(config, actions, raspExecutionStateActions);import {
talsecStart,
setThreatListeners,
removeThreatListeners,
} from 'freerasp-react-native';async componentDidMount() {
await setThreatListeners(actions);
const response = await talsecStart(config);
console.log(response); // freeRASP started
}componentWillUnmount() {
removeThreatListeners();
}android {
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}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);
}
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.
Place the require_relative and freerasp_embed_talsec_spm!(installer) calls inside your existing post_install do |installer| block — do not create a second one, as a duplicate hook will override the first.
You have to use the same email for the Portal as you used for the watcherMail parameter.
L3 - Protect Users: Combat social engineering, phishing, malware with and
Talsec offers enhanced features and benefits with our RASP+ plans, building on top of our freeRASP offering. Here’s what you can expect:
No limitations of freeRASP's Fair Usage Policy: Have an unrestricted number of app downloads* (beyond the 100k cap of freeRASP).
No Data Collection to Talsec Database: Your app's data is sent to your data collection services. You can even disable data collection.
FinTech Grade Security: Experience advanced security features and service-level agreements (SLAs) tailored for the financial technology sector.
Bypass Protection: RASP+ offers enhanced security with app-specific SDK customisation, while freeRASP uses a universal binary that is more susceptible to bypass.
Enhanced API Protection: Safeguard your APIs and benefit from risk scoring with our proprietary technology, .
For further details, please refer to the next page.
One of the most valued commercial features is AppiCrypt® - App Integrity Cryptogram.
It allows easy-to-implement API protection and App Integrity verification on the backend to prevent API abuse:
Bruteforce attacks
Botnets
API abuse by App impersonation
Session-hijacking
DDoS
It is a unified solution that works across all mobile platforms without dependency on external web services (i.e., without extra latency, an additional point of failure, and maintenance costs).
Malware Detection provides active in-app protection against both known & zero-day malware, ongoing malware campaigns, counterfeit app clones, and other risky and suspicious apps that could compromise user data or your backend services. It evaluates applications, highlights high‑risk findings, and reports them back to your mobile app for real‑time security decisions and logging.
Combination of robust on-device Offline Scanning for Suspicious and Risky Apps with an optional online App Reputation API verifying findings against malware DB, allows you to balance privacy, performance, and coverage according to your risk model.
freeRASP is freemium software, i.e. there is a Fair Usage Policy (FUP) that imposes some limitations on free usage.
For additional comparison details and information on planned features, please see the next page.
By teaming up with , the parent company of Norton and Avast, we bring you an unparalleled malware database. It continuously evolves, drawing top-tier threat intelligence from a massive network of 500 million global users.
You can try freeRASP and then upgrade easily to an enterprise service.
Learn more about commercial features at .
Open Xcode and remove the FlutterGeneratedPluginSwiftPackage reference from the Runner target in both Package Dependencies and Frameworks, Libraries, and Embedded Content.
Delete the Run Prepare Flutter Framework Script from the target's build pre-actions.
Run pod install inside the ios directory to restore the CocoaPods setup.
flutter config --no-enable-swift-package-manager
flutter cleanBest fit for
Low value apps and educational purpose
Try RASP+ and perform Penetration testing
Try advanced resilience and protection of App and APIs
Production usage
App Shielding SDK
freeRASP SDK is a free, easy-to-integrate runtime threat detection solution for small businesses and projects, supporting up to 100,000 device downloads. It helps you quickly grasp the main features, experiment, and try integrating Talsec SDKs. While it is a good threat detection tool, freeRASP’s limited resilience against bypasses and limited telemetry data collection make it unsuitable for commercial use in production, especially in regulated or privacy-sensitive domains.
RASP+ SDK delivers banking-grade security designed for professional, regulated, or high-risk apps needing maximum hardening. RASP+ is built to pass rigorous penetration tests, ensuring real-time detection and mitigation of attacks.
It guarantees compliance and robust defense.
RASP+ SDK delivers banking-grade security designed for professional, regulated, or high-risk apps needing maximum hardening. Its customizable SDKs include advanced threat prevention like AppiCrypt for API and Transaction Integrity protection. ✅ RASP+ is built to pass rigorous penetration tests, ensuring real-time detection and mitigation of attacks. It guarantees compliance and robust defense.
RASP+ SDK delivers banking-grade security designed for professional, regulated, or high-risk apps needing maximum hardening. Its customizable SDKs include advanced threat prevention like AppiCrypt for API and Transaction Integrity protection. RASP+ is built to pass rigorous penetration tests, ensuring real-time detection and mitigation of attacks. With strict privacy (no data sent to Talsec) ✅, it guarantees compliance and robust defense.
Resilience to Reverse Engineering and bypass
limited
advanced ✅
advanced ✅
advanced ✅
SDK obfuscation
limited (same for all users)
advanced (individual per build) ✅
advanced (individual per build) ✅
advanced (individual per build) ✅
Root & jailbreak protections
su, Magisk, Dopamine, KernelSU, HideMyApplist, Shamiko
basic
advanced ✅
advanced ✅
advanced ✅
Runtime reverse engineering controls
Debugger
Emulator / Simulator
Hooking and reversing frameworks (e.g. Frida, Magisk, XPosed, Cydia Substrate and more)
UI Automation
basic
advanced ✅
advanced ✅
advanced ✅
Runtime integrity controls
Tampering protection
Repackaging / Cloning protection
Device binding protection
Unofficial store detection
basic
advanced ✅
advanced ✅
advanced ✅
Device OS security status check
HW security module
Screen lock
Google Play Services availability
Huawei Mobile Services availability
Last security patch update
System VPN
Developer mode, ADB
Unlocked Bootloader
yes
yes
yes
yes
Anti-Spoofing & Misuse detection
Unsecure WiFi Detection
Location Spoofing
Time Spoofing
Multi-instance detection
yes
yes
yes
yes
Screen Capture protection
Block Screen Capture, Mirroring, Sharing
Detect Screenshot, Screen Recording
yes
yes
yes
yes
UI protection
Overlay protection
Accessibility services misuse protection
no
yes ✅
yes ✅
yes ✅
Penetration Test Ready
can be bypassed by professional
designed to sustain pentesting ✅
designed to sustain pentesting ✅
designed to sustain pentesting ✅
App Hardening Suite
for Strings Protection
Protect secrets in your code, third-party API keys, tokens, encryption keys, config files
On-the-fly key provisioning and rotation
no
no
yes ✅
yes ✅
Strong MitM and DNS spoofing protection
Decoupled certificate and app lifecycle
Pins never stored in app
no
no
yes ✅
yes ✅
AppiCrypt® - App Integrity Cryptogram
API protection and anti-API abuse
Transactions authenticity and integrity verification
Device Risk Scoring
RASP advanced anti-bypass
no
no
yes ✅
yes ✅
API protection and anti-API abuse
Transactions authenticity and integrity verification
Browser-based Apps protection using WebAssembly
Anti-bot and sesion hijacking
Anti-web scraping
no
no
no
yes ✅
Malware Detection
Detection of apps installed from untrusted stores or side-loaded
Detection of apps with suspicious permissions granted
Detection of risky apps
Detection of dangerous apps
basic ()
no
advanced ✅
advanced ✅ + online App Reputation API
App Security Monitoring and Logging
Threat events data collection
mandatory collection to Talsec services
mandatory collection to Talsec services
mandatory collection to Talsec services
optional and customizable logs destination ✅
App and threats data monitoring portal and Dashboard
limited functionality, no raw data access
full functionality with access to raw data search ✅
full functionality with access to raw data search ✅
full functionality with access to raw data search ✅
Self-care portal for the SDK configuration
no
yes ✅
yes ✅
yes ✅
Support and Maintenance
SLA and maintenance updates
not committed
yes ✅
yes ✅
yes (advanced variants) 🏆✅
Fair Usage Policy - up to 100K Devices
Total apps downloads limit
up to 100K Devices (premium upgrade required for more)
up to 10K
up to 10K
100K+ Devices 🚀
End-users' threats data collection and processing by Talsec
mandatory
mandatory
mandatory
optional and customizable logs destination ✅

When the background evaluation process completes and identifies one or more threats, the detection engine triggers a callback to your application. This section details how to intercept this callback, parse the threat data, and implement dynamic remediation strategies.
The results of the scan are delivered asynchronously via the standard Threat Callback mechanism. Because the engine automatically filters out safe system applications and caches benign results, this callback is only fired if a suspicious application is actively detected on the device.
Implement the onMalware method from the ThreatListener.ThreatDetected interface:
override fun onMalware(suspiciousApps: List<SuspiciousAppInfo>?) {
Provide the onMalware callback within your ThreatCallback object:
Add the malware callback to your actions object:
Add the malware callback to your actions object:
Add the malware callback to your actions object:
Collect FreeRaspEvent.Malware events from the threatEvents SharedFlow:
For each identified threat, the engine generates a SuspiciousAppInfo data object containing metadata about the offending application and the specific rules it violated.
The structure of this object depends on the version of the module integrated into your project.
By default, the appIcon property is omitted to reduce the computation time required to serialize the payload. If your application requires displaying a threat warning dialog with visual context, retrieve the icon asynchronously.
Retrieve the icon natively using the Android PackageManager:
Because behavioral heuristics are probabilistic, legitimate tools may occasionally be flagged. To handle false positives, you can manually whitelist specific package names on the local device.
Once an application is whitelisted, the engine ignores it during all future evaluations until the detection configuration changes.
If you determine an application is an absolute threat and the user is unable to proceed, you can programmatically prompt them to uninstall it.
Because Android security constraints prevent applications from silently uninstalling other packages, remediation requires direct user intervention. The standard approach is to dispatch a native Intent that routes the user to the system's Application Details screen.
Public display name.
packageInfo.version
String?
versionName string.
packageInfo.installerStore
String?
Installer package name (e.g., com.android.vending).
packageInfo.appIcon
String?
Base64 encoded icon (null by default).
reasons
Set<String>
Rules violated (blocklist, installSource, suspiciousPermission).
permissions
Set<String>?
Exact permissions that triggered detection (if flagged with suspiciousPermission).
packageInfo.packageName
String
Unique package identifier.
packageInfo.appName
packageInfo.packageName
string
Unique package identifier.
packageInfo.appName
packageInfo.packageName
string
Unique package identifier.
packageInfo.appName
packageInfo.packageName
string
Unique package identifier.
packageInfo.appName
packageInfo.packageName
String
Unique package identifier.
packageInfo.appName
The primary threat signal (blocklist, installSource, or suspiciousPermission). Returns only the highest-priority match (suspiciousPermission overrides installSource).
packageInfo.packageName
String
Unique package identifier.
packageInfo.appName
packageInfo.packageName
string
Unique package identifier.
packageInfo.appName
packageInfo.packageName
string
Unique package identifier.
packageInfo.appName
packageInfo.packageName
string
Unique package identifier.
packageInfo.appName
packageInfo.packageName
String
Unique package identifier.
packageInfo.appName
import { type SuspiciousAppInfo } from 'capacitor-freerasp';
const actions = {
// Other threat callbacks...
malware: (suspiciousApps: SuspiciousAppInfo[]) => {
console.log('Detected suspicious apps: ', suspiciousApps);
},
};const actions = {
// Other threat callbacks...
malware: (suspiciousApps) => {
console.log('Detected suspicious apps: ', suspiciousApps);
},
};FreeraspKMP.threatEvents
.filterIsInstance<FreeRaspEvent.Malware>()
.collect { event ->
event.suspiciousAppInfo.forEach { app ->
println("Detected malware: ${app.packageInfo.packageName}")
}
}packageInfo.packageName
String
Unique package identifier.
packageInfo.appName
packageInfo
PackageInfo
The native Android PackageInfo object. Provides comprehensive OS-level metadata about the flagged application (e.g., version, signatures, installed location).
reason
val drawable = context.packageManager.getApplicationIcon(app.packageInfo.packageName)import 'dart:convert';
final decodedImage = base64.decode(app.packageInfo.appIcon!);
Image.memory(decodedImage);import { getAppIcon, type SuspiciousAppInfo } from 'freerasp-react-native';
const retrieveIcon = async (app: SuspiciousAppInfo) => {
try {
const iconBase64 = await getAppIcon(app.packageInfo.packageName);
app.packageInfo.appIcon = iconBase64;
} catch (error) {
console.error('Failed to retrieve icon', error);
}
};import { getAppIcon } from 'capacitor-freerasp';
const retrieveIcon = async (app) => {
try {
const iconBase64 = await getAppIcon(app.packageInfo.packageName);
app.packageInfo.appIcon = iconBase64;
} catch (error) {
console.error('Failed to retrieve icon', error);
}
};const retrieveIcon = async (app) => {
try {
const iconBase64 = await getAppIcon(app.packageInfo.packageName);
app.packageInfo.appIcon = iconBase64;
} catch (error) {
console.error('Failed to retrieve icon', error);
}
};val iconBase64 = FreeraspKMP.getAppIcon(app.packageInfo.packageName)Talsec.addToWhitelist(context, "com.trusted.sideloaded.app")Talsec.instance.addToWhitelist("com.trusted.sideloaded.app");import { addToWhitelist } from 'freerasp-react-native';
try {
await addToWhitelist('com.trusted.sideloaded.app');
} catch (error) {
console.error('Whitelist error: ', error);
}import { addToWhitelist } from 'capacitor-freerasp';
try {
await addToWhitelist('com.trusted.sideloaded.app');
} catch (error) {
console.error('Whitelist error: ', error);
}try {
await addToWhitelist('com.trusted.sideloaded.app');
} catch (error) {
console.error('Whitelist error: ', error);
}FreeraspKMP.addToWhiteList("com.trusted.sideloaded.app")val intent = Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
data = Uri.fromParts("package", app.packageInfo.packageName, null)
flags = Intent.FLAG_ACTIVITY_NEW_TASK
}
context.startActivity(intent)import 'package:android_intent_plus/android_intent.dart';
final intent = AndroidIntent(
action: 'android.settings.APPLICATION_DETAILS_SETTINGS',
data: 'package:${app.packageInfo.packageName}',
);
await intent.launch();import IntentLauncher from 'react-native-intent-launcher';
IntentLauncher.startActivity({
action: 'android.settings.APPLICATION_DETAILS_SETTINGS',
data: `package:${app.packageInfo.packageName}`,
});import { IntentLauncher } from '@capgo/capacitor-intent-launcher';
await IntentLauncher.startActivity({
action: 'android.settings.APPLICATION_DETAILS_SETTINGS',
data: `package:${app.packageInfo.packageName}`,
});window.plugins.intentShim.startActivity(
{
action: "android.settings.APPLICATION_DETAILS_SETTINGS",
data: `package:${app.packageInfo.packageName}`
},
() => console.log('Settings launched successfully'),
(err) => console.error('Failed to launch settings:', err)
);val intent = Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
data = Uri.fromParts("package", app.packageInfo.packageName, null)
flags = Intent.FLAG_ACTIVITY_NEW_TASK
}
context.startActivity(intent)Exception Handling Required
The getApplicationIcon method throws a PackageManager.NameNotFoundException if the system cannot locate the package. Wrap this call in a try-catch block.
Exception Handling Required
Calls to getAppIcon() will throw a native exception if the user uninstalls the target application before the fetch completes. Wrap the execution in a try-catch block and implement a fallback UI.
Exception Handling Required
The getAppIcon() Promise will reject if the target application is uninstalled before the fetch completes. Wrap the await call in a try-catch block.
Exception Handling Required
The getAppIcon() Promise will reject if the target application is uninstalled before the fetch completes. Wrap the await call in a try-catch block.
Exception Handling Required
getAppIcon() throws a FreeraspKMPException if the target application cannot be found. Wrap the call in a try-catch block and implement a fallback UI.
Security Constraint
Never automatically whitelist sideloaded applications based purely on their package name. Attackers frequently spoof popular package names to bypass filters. Always implement a UI flow requiring the user to explicitly confirm trust before executing the whitelist method.
Pre-Initialization Whitelisting
If your logic requires whitelisting an application immediately upon the first launch, the addToWhitelist method must be executed before calling the core Talsec.start() initialization routine.

final callback = ThreatCallback(
onMalware: (List<SuspiciousAppInfo?> suspiciousApps) {
for (var app in suspiciousApps) {
print('Detected malware: ${app?.packageInfo.packageName}');
}
},
// Other callbacks...
);import { type SuspiciousAppInfo } from 'freerasp-react-native';
const actions = {
// Other threat callbacks...
malware: (suspiciousApps: SuspiciousAppInfo[]) => {
console.log('Detected suspicious apps: ', suspiciousApps);
},
};String?
String
String?
Public display name.
packageInfo.version
String?
versionName string.
packageInfo.installerStore
String?
Installer package name (e.g., com.android.vending).
packageInfo.appIcon
String?
Base64 encoded icon (null by default).
reasons
List<String>
Rules violated (blocklist, installSource, suspiciousPermission).
permissions
List<String>?
Exact permissions that triggered detection (if flagged with suspiciousPermission).
string?
Public display name.
packageInfo.version
string?
versionName string.
packageInfo.installerStore
string?
Installer package name (e.g., com.android.vending).
packageInfo.appIcon
string?
Base64 encoded icon (null by default).
reasons
string[]
Rules violated (blocklist, installSource, suspiciousPermission).
permissions
string[]?
Exact permissions that triggered detection (if flagged with suspiciousPermission).
string?
Public display name.
packageInfo.version
string?
versionName string.
packageInfo.installerStore
string?
Installer package name (e.g., com.android.vending).
packageInfo.appIcon
string?
Base64 encoded icon (null by default).
reasons
string[]
Rules violated (blocklist, installSource, suspiciousPermission).
permissions
string[]?
Exact permissions that triggered detection (if flagged with suspiciousPermission).
string?
Public display name.
packageInfo.version
string?
versionName string.
packageInfo.installerStore
string?
Installer package name (e.g., com.android.vending).
packageInfo.appIcon
string?
Base64 encoded icon (null by default).
reasons
string[]
Rules violated (blocklist, installSource, suspiciousPermission).
permissions
string[]?
Exact permissions that triggered detection (if flagged with suspiciousPermission).
String?
Public display name.
packageInfo.version
String?
versionName string.
packageInfo.installerStore
String?
Installer package name (e.g., com.android.vending).
packageInfo.appIcon
String?
Base64 encoded icon (null by default).
reasons
Set<String>
Rules violated (blocklist, installSource, suspiciousPermission).
permissions
Set<String>?
Exact permissions that triggered detection (if flagged with suspiciousPermission).
String?
Public display name.
packageInfo.version
String?
versionName string.
packageInfo.installationSource
String?
Installer package name (e.g., com.android.vending).
packageInfo.appIcon
String?
Base64 encoded icon (null by default).
reason
String
The primary threat signal (blocklist, installSource, or suspiciousPermission). Returns only the highest-priority match (suspiciousPermission overrides installSource).
string?
Public display name.
packageInfo.version
string?
versionName string.
packageInfo.installerStore
string?
Installer package name (e.g., com.android.vending).
packageInfo.appIcon
string?
Base64 encoded icon (null by default).
reason
string
The primary threat signal (blocklist, installSource, or suspiciousPermission). Returns only the highest-priority match (suspiciousPermission overrides installSource).
string?
Public display name.
packageInfo.version
string?
versionName string.
packageInfo.installerStore
string?
Installer package name (e.g., com.android.vending).
packageInfo.appIcon
string?
Base64 encoded icon (null by default).
reason
string
The primary threat signal (blocklist, installSource, or suspiciousPermission). Returns only the highest-priority match (suspiciousPermission overrides installSource).
string?
Public display name.
packageInfo.version
string?
versionName string.
packageInfo.installerStore
string?
Installer package name (e.g., com.android.vending).
packageInfo.appIcon
string?
Base64 encoded icon (null by default).
reason
string
The primary threat signal (blocklist, installSource, or suspiciousPermission). Returns only the highest-priority match (suspiciousPermission overrides installSource).
String?
Public display name.
packageInfo.version
String?
versionName string.
packageInfo.installerStore
String?
Installer package name (e.g., com.android.vending).
packageInfo.appIcon
String?
Base64 encoded icon (null by default).
reason
String
The primary threat signal (blocklist, installSource, or suspiciousPermission). Returns only the highest-priority match (suspiciousPermission overrides installSource).
Introducing Multi-Instancing Detection for freeRASP

Obfuscation of Mobile Apps

Browse the latest freeRASP release notes, breaking changes, and new security features across Android, iOS, and cross‑platform SDKs to keep your mobile app protection up to date.
Stay up-to-date with the latest features, improvements and bug fixes for freeRASP. Here you'll find detailed information about each update we've rolled out, organized by platform. Whether you're using the Android, iOS, Flutter, React Native, Capacitor, or Cordova version, all platforms are supported.
Explore the tabs below to see what's new and how the experience has been improved for you. If you're looking for specific changes or features, each update is documented for your convenience.
Learn more:
Github Changelog:
Fixed the reporting issue in root detection
Fixed the reporting issue in hook detection
Fixed ANR during SDK initialization caused by blocking I/O operations
❗️Breaking: Renamed ThreatListener.ThreatDetected and ThreatListener.DeviceState callback methods
❗️Breaking: Changed package namespace from com.aheaditec.talsec_security to app.talsec.rasp
Added bootloader detection (unlocked/compromised) with onBootloader() callback
Added option to fetch JitPack dependencies from our own Talsec repository (`https://europe-west3-maven.pkg.dev/talsec-artifact-repository/common`)
Fixed native crash caused by std::terminate() race condition
Fixed periodic hook and root check overwriting
Fixed root detection crash in obfuscated release builds
Fixed hardware-backed keystore detection failing with NoSuchMethodError on some Android 12+ devices
Improved KernelSU detection
Improved hook detection
Improved Frida detection
Improved root detection capabilities
❗️Breaking: Modified property reason (of type String) in SuspiciousAppInfo to reasons (to type Set<String>)
❗️Breaking: One of the reasons in SuspiciousAppInfo renamed from blacklist to blocklist
Added new detection check for KernelSU
Fixed memory management issues in the native code
Patched possibility of getInstalledPackages throwing DeadSystemException
Patched possibility of getNetworkCapabilities throwing SecurityException
Fixed well-known issue of Cipher.init throwing KeyStoreConnectException
Removed deprecated monitoring feature
Fixed method storeExternalId to return ExternalIdResult for error handling
Fixed ScreenProtector crash during activity start and permissions request
Fixed screen recording detection callback
❗️Breaking: Changed ThreatListener API interfaces (ThreatDetected, DeviceState) to abstract classes
❗️Breaking: Added onAutomationDetected() callback to ThreatDetected interface
We are introducing a new capability, detecting whether the device is being automated using tools like Appium
❗️Breaking: Added value restrictions to externalId
Method storeExternalId() now returns ExternalIdResult, which indicates Success or Error when externalId violates restrictions
Improved HMA detection to the existing root detection capability
Updated compile and target API to 36
Improved root detection capabilities
Detection of wireless ADB added to ADB detections
Fixed bug related to key storing in keystore type detection (hw-backed keystore check)
Fixed manifest queries merge
❗️Breaking: Added killOnBypass method to the TalsecConfig.Builder that configures if the app should be terminated when the threat callbacks are suppressed/hooked by an attacker Issue 65
❗️Breaking: Added onTimeSpoofingDetected() callback to ThreatDetected interface
We are introducing a new capability, detecting whether the device time has been tampered with
❗️Breaking: Added onLocationSpoofing() callback
We are introducing a new capability, detecting whether the location is being spoofed on the device.
❗️Breaking: Added onUnsecureWifi() callback to ThreatDetected interface
❗️Breaking: Changed onMalwareDetected() method parameter packageInfo to non-nullable
❗️Breaking: Updated dispatchKeyEvent() parameter nullability from @Nullable to @NonNull
❗️Breaking: Changed parameter type of Activity instead of Context in the blockScreenCapture() method
❗️Breaking: Removed deprecated functionality Pbkdf2Native and both related native libraries (libpbkdf2_native.so and libpolarssl.so)
Added ScreenProtector feature wrapper object that helps with registration/unregistration of screen protection features
A new constructor parameter of type RaspExecutionState in class ThreatListenerrepresenting changes in state in our library. RaspExecutionState contains onAllChecksFinished() method, which is triggered after all checks are completed.
Added matched permissions to SuspiciousAppInfo object when malware detection reason is suspiciousPermission
New option to start Talsec, Talsec.start() takes new parameter TalsecMode that determines the dispatcher thread of initialization and sync checks
Capability to check if another app has an option REQUEST_INSTALL_PACKAGES enabled in the system settings to malware detection
ANR issue caused by registerScreenCaptureCallback() method on the main thread
NullPointerException when checking key alias in Keystore on Android 7
JaCoCo issue causing MethodTooLargeException during instrumentation
DeadApplicationException when calling Settings.Global.getInt or Settings.Secure.getInt on invalid context
AndroidKeyStore crashes causing java.util.concurrent.TimeoutException when calling finalize() method on Cipher (GC issues)
Shortened the value of threat detection interval
Refactoring of internal architecture of SDK that newly uses Coroutines to manage threading
Update of internal dependencies and security libraries
❗️Added onMultiInstanceDetected() callback - detection whether the application is installed/running in various multi-instancing environments (e.g. Parallel Space).
Added support for 16 KB memory page sizes.
The ADB service running as "root" is a signal for root detection.
Improved emulator detection.
Internal security improvements.
Removed malware report duplicates.
Added new root detection checks.
Added eventId to the logs, which is unique per each log. It allows traceability of the same log across various systems.
Added externalId to put an integrator-specified custom identifier into the logs. This feature will be presented later.
Resolved SecurityException caused by getNetworkCapabilities() - Android 11 specific bug (GH Android issue #56).
Compile API increased to 35, dependencies updated
Internal library obfuscation reworked
Root detection divided into 2 parts (quick initial checks, and time-demanding asynchronous post checks)
ANR issues bug-fixing
❗️Added onScreenshotDetected() - detection of screenshots, refer to the Android freeRASP integration documentation.
❗️Added onScreenRecordingDetected() - detection of screen recording, refer to the Android freeRASP integration documentation.
Added blockScreenCapture(Activity activity, boolean enable) for FLAG_SECURE control, an active protection against screen capturing.
isScreenCaptureBlocked() - to receive whether the screen capture is blocked
Rate limiting for both screenshot and screenRecording incidents
Improved root detection capabilities
Updated proguard rules to fix warnings from okhttp dependency.
Added request integrity information to data collection headers.
Enhanced and accelerated the data collection logic.
BREAKING CHANGE: Added onADBEnabledDetected detection feature, which allows you to detect USB debugging option enabled in the developer settings on the device. App needs to implement this new callback.
Refactored Magisk checks in the root detection
Internal refactoring of Malware detection feature
Bug Fix
Resolved IllegalArgumentException caused by unregistering not registered receiver in TalsecMonitoringReceiver
Reported ANR issues present on some devices were resolved (GH issue #138).
Reported crashes caused by ConcurrentModificationException and NullPointerException were resolved (GH Flutter #140).
Reported crashes caused by the UnsupportedOperationException were resolved.
False positives in Hook detection (runtimeManipulation).
Added onMalwareDetected to ThreatListener.ThreatDetected interface, this is a breaking change and the onMalwareDetected has to be implemented by the integrating application.
Important Information
Further details for this feature will be provided shortly with the new repositories.
For now, do not react to the callback, you can implement it simply by just using println().
Added the auditing of the internal execution for the future check optimization and overall security improvements.
Changed the way TalsecConfig is created, we introduced a Builder pattern to make the process more streamlined and readable.
Updated CURL to 8.8.0 and OpenSSL to 3.0.14 (Github issue #114).
Refactored fetching the list of installed applications for root and hook detection.
Fixed native crashes (SEGFAULT errors) in ifpip method.
Fixed collision for command line tools (like ping) invoked without absolute path (Github issue #41).
Two new threat callbacks, onDeveloperModeDetected and onSystemVPNDetected, have been added for detecting Developer mode and System VPN.
Updated GMS dependency to a newer version for improved performance and compatibility.
Updated CA bundle to enhance security for secure connections.
Resolved a problem with displaying the Arabic alphabet in logs caused by the device’s default system locale.
Updated freeRASP SDK artifact hosting ensuring better stability and availability.
Shortened duration of threat evaluation.
Improved appIntegrity check and its logging.
Updated CURL to 8.5.0 and OpenSSL to 1.1.1w.
Fixed a native crash bug during one of the native root checks (detected after NDK upgrade).
Increased the compileSdk and targetSdk in the demo application.
Updated dependencies in the demo application.
Fixed issue with ProviderException (#26).
Curious about more in-depth changes for Android? Head over to our GitHub Changelog for the complete history of updates!
Github Changelog: https://github.com/talsec/Free-RASP-iOS/releases
Improved jailbreak detection
Added support for postponed checks, therefore, due to slower execution, some subchecks are run after initial startup checks.
Improved hook detection.
Fixed issue with app's color scheme initialization.
Fixed bad memory access in jaibreak check.
Fixed retrigger jailbreak issue on iOS 15 and 16.
Fixed false positives with jailbreak on iOS 15 and 16.
Fixed issue with app crashing on screenshot/screen recording.
Fixed new jailbreak checks false positives on iOS 14 and 13.
Improved timeSpoofing detection methods.
Added time spoofing detection, detecting an inaccurate device clock. It is a new threat timeSpoofing.
Improved jailbreak detection methods.
A new extension of SecurityThreatCenter: RaspExecutionState contains onAllChecksFinished() method, which is triggered after all checks are completed.
Updated internal dependencies.
Added palera1n jailbreak detection.
Improved Dopamine jailbreak detection.
Resolved memory-related stability issues.
Screen capture protection obscuring app content in screenshots and screen recordings preventing unauthorized content capture. Refer to the .
Added externalId to put an integrator-specified custom identifier into the logs. This feature will be presented later.
Added eventId to the logs, which is unique per each log. It allows traceability of the same log across various systems.
Resolved an issue that prevented Xcode tests from running correctly.
Resolved an issue with the screen recording detection.
Improvement of the obfuscation of the SDK
Deep signing of the OpenSSL binaries
Enhanced security with our new Screen Capture Threat Detection, now capable of identifying screen recording, AirPlay mirroring, and screenshots to guard against unauthorized viewing. Check out the new screenshot and screenRecording callbacks.
Updated SDK code signing; it will now be signed with:
Team ID: PBDDS45LQS
Team Name: Lynx SFT s.r.o.
Added jailbreak detection.
Renewed the signing certificate.
jailbreak detection.
Updated OpenSSL to version 3.0.14 and CURL to version 8.8.0. ()
Added request integrity information to data collection.
Significantly improved the response time from data collection service.
Added new threat callback systemVPN for System VPN detection.
Passcode check is now performed periodically.
Updated the CA bundle to enhance security for secure connections.
Resolved a problem with displaying the Arabic alphabet in logs caused by the device’s default system locale.
Added Privacy Manifest.
Added codesigning for the SDK, it is signed by:
Team ID: ASQC376HCN,
Team Name: AHEAD iTec, s.r.o.
Updated CURL to 8.5.0 and OpenSSL to 1.1.1w.
Improved obfuscation of Swift and C strings.
Fixed memory leak ().
Curious about more in-depth changes for iOS? Head over to our for the complete history of updates!
Github Changelog: https://github.com/talsec/Free-RASP-Flutter/releases
[Android] Fixed the reporting issue in root detection
[Android] Fixed the reporting issue in hook detection
[Android] Fixed ANR during SDK initialization caused by blocking I/O operations
[Android] Fixed background SDK initialization stalling when the shared thread pool is saturated
Fixed published package contents so required iOS framework artifacts are included
Included the example entrypoint for pub.dev; the full demo app remains in the repository only
Excluded non-essential development files (tests, codegen inputs, build outputs) from the published package
[Android] Moved -flattenpackagehierarchy
Added onBootloader callback for detecting an unlocked or compromised bootloader (Android only).
[Android] Added bootloader detection (unlocked/compromised) with onBootloader() callback
[Android] Added option to fetch JitPack dependencies from our own Talsec repository
[Android] Improved KernelSU detection
[Android] Improved hook detection
[Android] Improved Frida detection
[Android] Improved root detection capabilities
[Android] Fixed native crash caused by std::terminate() race condition
[Android] Fixed periodic hook and root check overwriting
[Android] Fixed crash inside AppZygotePreload during root detection
[Android] Fixed root detection crash in obfuscated release builds
Swift Package Manager (SPM) support for iOS. Requires Flutter 3.41.0 or newer; CocoaPods remains supported on older versions.
[iOS] Added support for postponed checks, therefore, due to slower execution, some subchecks are run after initial startup checks.
[iOS] Improved hook detection.
[iOS] Fixed issue with app's color scheme initialization.
[iOS] Fixed bad memory access in jailbreak check.
[iOS] Raised the minimum iOS deployment target to 13.0, as required by the iOS SDK.
RaspExecutionStateCallback.onAllChecksDone renamed to onAllChecksFinished
PackageInfo.installationSource renamed to installerStore
SuspiciousAppInfo.reason
SuspiciousAppInfo.permissions field (List<String>?) — list of suspicious permissions detected on the app
[Android] New API class SuspiciousAppDetectionConfig that can be used to configure malware detection
[Android] New API for malware detection configuration in TalsecConfig
[Android] Fixed VerifyError caused by JaCoCo bytecode instrumentation
[Android] Fixed a potential cause of crash in the multi-instance detector
[Android] Fixed Java interoperability of ScreenProtector methods
[Android] Fine-tuned location spoofing detection
[Android] Modified malware incident log structure for better aggregation
[Android] Made dispatchers singletons
[iOS] Fixed new jailbreak checks false positives on iOS 14 and 13.
[iOS] Fixed false positives with jailbreak on iOS 15 and 16.
[iOS] Fixed issue with app crashing on screenshot/screen recording.
[iOS] Fixed retrigger jailbreak issue on iOS 15 and 16.
[Android] Added support for KernelSU to the existing root detection capabilities
[Android] Added support for HMA to the existing root detection capabilities
[Android] Added new malware detection capabilities
Updated the internal handling of ExternalIdResult on Android (for storeExternalId() method)
[Android] Removed unused library tmlib
[Android] Refactoring of signature verification code
[Android] Fixed exception handling for the KeyStore getEntry operation
[Android] Fixed issue in ScreenProtector concerning the onScreenRecordingDetected invocations
[Android] Merged internal shared libraries into a single one, reducing the final APK size
Added onAutomation callback to ThreatCallback for handling Threat.automation threat
Added killOnBypass to TalsecConfig that configures if the app should be terminated when the threat callbacks are suppressed/hooked by an attacker (Android only) ()
Added onTimeSpoofing callback to ThreatCallback for handling Threat.timeSpoofing threat (Android only)
Removed deprecated functionality Pbkdf2Native and both related native libraries (libpbkdf2_native.so and libpolarssl.so)
Updated internal dependencies
[Android] Fixed an issue with crashing screen protector
[iOS] Fixed an issue with native framework
Added interface for multi-instance detection
[iOS] Added palera1n jailbreak detection
[iOS] Improved Dopamine jailbreak detection
[Android] Improved emulator detection
[Android] Added support for 16 KB pages
[iOS] Resolved memory-related stability issues
[Android] Removed malware report duplicates
Added interface for screenshot / screen recording blocking on iOS.
Improvements
Added interface for external ID storage.
Added eventId to the logs, which is unique per each log. It allows traceability of the same log across various systems.
[Android] New root detection checks added.
Fixed
Issue that caused compilation errors due to unknown references.
[iOS] Resolved an issue with the screen recording detection.
[iOS] Resolved an issue that prevented Xcode tests from running correctly.
fvm support for Flutter version management
Updated versions for example app
[Android] Breaking: Raised Kotlin version to 2.1.0
[Android] Compile API increased to 35, dependencies updated
[Android] ANR issues bug-fixing
Added screenshot - detection of screenshots, refer to the .
Added screenRecording - detection of screen recording, refer to the .
Added blockScreenCapture for FLAG_SECURE control, an
[Android] Raised Android CompileSDK level to 35
[Android] Monitoring is now disabled by default
[Android] Improved root detection
[Android] Proguard rules to address warnings from okhttp dependency
[Android] Added request integrity information to data collection headers.
[Android] Enhanced and accelerated the data collection logic.
App icons for detected malware are not fetched automatically anymore, which reduces computation required to retrieve malware data. From now on, app icons have to be retrieved using the getAppIcon method
[Android] Malware data is now parsed on background thread to improve responsiveness.
[Android] onADBEnabled callback, allowing you to detect USB debugging option enabled in the developer settings on the device.
[Android] Malware detection as a new callback for enhanced app security.
[Android] Internal refactoring of Malware detection feature.
[Android] Refactoring Magisk checks in the root detection.
[iOS] Enhanced security with Detection
Maintenance
[iOS] Updated SDK code signing; it will now be signed with:
Team ID: PBDDS45LQS
Team Name: Lynx SFT s.r.o.
[Android] Resolved IllegalArgumentException caused by unregistering not registered receiver in TalsecMonitoringReceiver
[iOS] Renewed the signing certificate.
[Android] Reported ANR issues present on some devices were resolved ().
[Android] Reported crashes caused by ConcurrentModificationException and NullPointerException were resolved ().
[Android] Reported crashes caused by the UnsupportedOperationException were resolved.
[Android] False positives for hook detection.
[Android] Added the auditing of the internal execution for the future check optimization and overall security improvements.
[iOS] jailbreak detection.
Migration to .
Updated CURL to 8.8.0 and OpenSSL to 3.0.14 ().
[Android] TalsecConfig creation was migrated to a Builder pattern.
[Android] Native crashes (SEGFAULT) in ifpip method.
[Android] Fixed collision for command line tools (like ping) invoked without absolute path ().
Added new threat Threat.systemVPN for VPN detection.
Added new callback onSystemVPN in ThreatCallback for handling Threat.systemVPN threat.
[Android] Added a new threat detection feature,
Increased minimal Dart SDK version to 2.18.0 and minimal Flutter version to 3.3.0
Updated the CA bundle to enhance security for secure connections.
[Android] Increased the version of the GMS dependency
[iOS] Passcode check is now performed periodically.
Resolved a problem in logging caused by the device’s default system locale
[Android] New Talsec SDK artifact hosting - better stability and availibility.
[iOS] Added Privacy Manifest.
[iOS] Added codesigning for the SDK, it is signed by:
Team ID: ASQC376HCN,
Updated CURL to 8.5.0 and OpenSSL to 1.1.1w.
[Android] Improved appIntegrity check and its logging.
[iOS]
[Android] Fixed issue with disappearing threats when the app is quickly put into the background and then back to the foreground (resolves ).
[Android] Fixed a native crash bug during one of the native root checks (detected after NDK upgrade).
Improved reaction obfuscation.
[iOS] Improved obfuscation of the iOS SDK.
[iOS] Raised supported Xcode version to 14.3.1 .
[Android] Fixed ProviderException.
Fixed typo in namespace which caused incompatibility with AGP 8.0 .
Curious about more in-depth changes for Flutter? Head over to our for the complete history of updates!
Github Changelog: https://github.com/talsec/Free-RASP-ReactNative/releases
[Android] Fixed the reporting issue in root detection
[Android] Fixed the reporting issue in hook detection
[Android] Fixed ANR during SDK initialization caused by blocking I/O operations
[Android] Fixed background SDK initialization stalling when the shared thread pool is saturated
Added bootloader callback for detecting an unlocked or compromised bootloader (Android only)
[Android] Added bootloader detection (unlocked/compromised) with onBootloader() callback
[Android] Added option to fetch JitPack dependencies from our own Talsec repository
[Android] Improved KernelSU detection
[Android] Improved hook detection
[Android] Improved Frida detection
[Android] Improved root detection capabilities
[Android] Fixed native crash caused by std::terminate() race condition
[Android] Fixed periodic hook and root check overwriting
[Android] Fixed crash inside AppZygotePreload during root detection
[Android] Fixed root detection crash in obfuscated release builds
Fixed missing files in the published npm package
Added Swift Package Manager delivery of TalsecRuntime, enabled by default for Expo projects and available as an opt-in for bare React Native 0.75 or newer projects
Added the Expo config plugin option ios.useSpm; set it to false to use the vendored XCFramework fallback
[iOS] Added support for postponed checks, therefore, due to slower execution, some subchecks are run after initial startup checks
Fixed identifier retrieval after React Native context reinitialization ()
[iOS] Fixed issue with app's color scheme initialization
[iOS] Fixed bad memory access in jailbreak check
❗️Breaking: SuspiciousAppInfo.reason (string) renamed to reasons (string[])
❗️Breaking: Value "blacklist" in reasons renamed to "blocklist"
[Android] New API class SuspiciousAppDetectionConfig that can be used to configure malware detection
[Android] New API for malware detection configuration in TalsecConfig, see TalsecConfig.Builder#suspiciousAppDetection
Removed TalsecMalwareConfig type and TalsecAndroidConfig.malwareConfig field
[Android] Fine-tuned location spoofing detection
[Android] Modified malware incident log structure for better aggregation
[Android] Fixed VerifyError caused by JaCoCo bytecode instrumentation
[Android] Fixed a potential cause of crash in the multi-instance detector
[Android] Fixed Java interoperability of ScreenProtector methods
Enhanced event dispatchers logic
[iOS] Fixed new jailbreak checks false positives on iOS 14 and 13
[iOS] Fixed false positives with jailbreak on iOS 15 and 16
[iOS] Fixed issue with app crashing on screenshot/screen recording
[iOS] Fixed retrigger jailbreak issue on iOS 15 and 16
Fixed case where event dispatchers on Android were not initialized before calling onResume at the app launch
[Android] Added support for KernelSU to the existing root detection capabilities
[Android] Added support for HMA to the existing root detection capabilities
[Android] Added new malware detection capabilities
Updated the internal handling of ExternalIdResult on Android (for storeExternalId() method)
[Android] Removed unused library tmlib
[Android] Refactoring of signature verification code
[Android] Fixed exception handling for the KeyStore getEntry operation
[Android] Fixed issue in ScreenProtector concerning the onScreenRecordingDetected invocations
[Android] Merged internal shared libraries into a single one, reducing the final APK size
Added cache for freeRASP callbacks when listener is not registered with the app
Added API for automation callback into ThreatEventActions (Android only)
Updated compile and target SDK versions to 36 on Android
Higher compileSdk from [rootProject, plugin] is now used in build.gradle on Android
Prevent multiple registration of the freeRASP listeners on the native side
Fixed
Resolved potential NullPointerException when execution state events are being sent
Fixed
Resolved duplicate classes error on iOS
Added
Added killOnBypass to TalsecConfig that configures if the app should be terminated when the threat callbacks are suppressed/hooked by an attacker (Android only) ()
Added API for timeSpoofing callback into ThreatEventActions (Android only)
Fixed
Resolved potential collision in threat identifiers
Added
Added killOnBypass method to the TalsecConfig.Builder that configures if the app should be terminated when the threat callbacks are suppressed/hooked by an attacker
We are introducing a new capability, detecting whether the device time has been tampered with (timeSpoofing)
We are introducing a new capability, detecting whether the location is being spoofed on the device (locationSpoofing
Fixed
ANR issue caused by registerScreenCaptureCallback() method on the main thread
NullPointerException when checking key alias in Keystore on Android 7
JaCoCo issue causing MethodTooLargeException during instrumentation
Changed
Shortened the value of threat detection interval
Refactoring of internal architecture of SDK that newly uses Coroutines to manage threading
Update of internal dependencies and security libraries
Changed
Updated internal dependencies
Fixed
iOS dependencies are now installed via install_modules_dependencies by default
Fixed
Root detection related bugs causing false positives
Changed
Deprecated Nexus repository removed (GCP artifact registry is the main supported distribution repository)
Changed
Replaced deprecated getCurrentActivity() call on Android (compatibility with RN 0.81+)
Fixed
Possible conflict with other packages during proguard code minification
Fixed
Issue with empty SharedPreferences files
Changed
Decreased version of Kotlin to 2.0.0
Added interface for multi-instance detection
[iOS] Added palera1n jailbreak detection
[iOS] Improved Dopamine jailbreak detection
[Android] Improved emulator detection
[Android] Added support for 16 KB pages
[iOS] Resolved memory-related stability issues
[Android] Removed malware report duplicates
Added interface for screenshot / screen recording blocking on iOS.
Improvements
Added interface for external ID storage.
Added eventId to the logs, which is unique per each log. It allows traceability of the same log across various systems.
[Android] New root detection checks added.
Fixed
[iOS] Resolved an issue with the screen recording detection.
[iOS] Resolved an issue that prevented Xcode tests from running correctly.
Android SDK requires kotlin_version >= 2.0.0
Set Java version to 17
[Android] Compile API increased to 35, dependencies updated
[Android] ANR issues bug-fixing
Added screenshot - detection of screenshots, refer to the .
Added screenRecording - detection of screen recording, refer to the .
Added blockScreenCapture for FLAG_SECURE control, an
[Android] Raised Android compileSDK level to 35
[Android] Improved root detection
Compatibility issues with RN New Architecture
[Android] Added proguard rules for malware data serialization in release mode on Android
[Android] Proguard rules to address warnings from okhttp dependency
[Android] Added request integrity information to data collection headers.
[Android] Enhanced and accelerated the data collection logic.
App icons for detected malware are not fetched automatically anymore, which reduces computation required to retrieve malware data. From now on, app icons have to be retrieved using the getAppIcon method.
Parsing of malware data is now async.
[Android] Malware data is now parsed on background thread to improve responsiveness.
[Android] adbEnabled callback, allowing you to detect USB debugging option enabled in the developer settings on the device.
Added configuration fields for malware detection.
[Android] Malware detection as a new callback for enhanced app security.
[Android] Refactoring Magisk checks in the root detection.
[iOS] Enhanced security with Detection to identify compromised devices.
Maintenance
[iOS] Updated SDK code signing; it will now be signed with:
Team ID: PBDDS45LQS
Team Name: Lynx SFT s.r.o.
[iOS] Renewed the signing certificate.
[Android] Reported ANR issues present on some devices were resolved ().
[Android] Reported crashes caused by ConcurrentModificationException and NullPointerException were resolved ().
[Android] Reported crashes caused by the UnsupportedOperationException were resolved.
[Android] False positives for hook detection.
[Android] Added the auditing of the internal execution for the future check optimization and overall security improvements.
[iOS] jailbreak detection.
Improved error messages when validation of the freeRASP configuration fails.
Updated CURL to 8.8.0 and OpenSSL to 3.0.14 ().
[Android] Changed the way TalsecConfig is created, we introduced a Builder pattern to make the process more streamlined and readable.
Fixed incorrect path to types in package.json.
[Android] Fixed native crashes (SEGFAULT errors) in ifpip method.
[Android] Fixed collision for command line tools (like ping) invoked without absolute path ().
Updated proguard rules to resolve build issues in RN 0.75.x.
Added a new threat systemVPN for VPN detection.
[Android] Added a new threat devMode for Developer mode detection.
Updated the CA bundle to enhance security for secure connections.
[Android] Updated the GMS dependency to a newer version for improved performance and compatibility.
[iOS] Enhanced and accelerated the data collection logic.
[iOS] Passcode check is now performed periodically.
Resolved a problem with displaying the Arabic alphabet in logs caused by the device’s default system locale.
[Android] Fixed proguard warning in specific versions of RN.
Updated expo config plugin to fix release build issue in RN 0.73.
[Android] Updated freeRASP SDK artifact hosting ensuring better stability and availibility.
[Android] Fixed compatibility issues with RN < 0.63.
Added support for apps built with Expo SDK.
[iOS] Added Privacy Manifest.
[iOS] Added codesigning for the SDK, it is signed by:
Team ID: ASQC376HCN
Updated CURL to 8.5.0 and OpenSSL to 1.1.1w.
[Android] Shortened duration of threat evaluation.
[Android] Improved appIntegrity
[Android] Fixed a native crash bug during one of the native root checks (detected after NDK upgrade).
[iOS] Fixed memory leak ().
Curious about more in-depth changes for React Native? Head over to our for the complete history of updates!
Github Changelog: https://github.com/talsec/Free-RASP-Cordova/releases
[Android] Fixed the reporting issue in root detection
[Android] Fixed the reporting issue in hook detection
[Android] Fixed ANR during SDK initialization caused by blocking I/O operations
[Android] Fixed background SDK initialization stalling when the shared thread pool is saturated
bootloader threat callback, reporting an unlocked or compromised bootloader — Android only
[Android] Added bootloader detection (unlocked/compromised) with onBootloader() callback
[Android] Added option to fetch JitPack dependencies from our own Talsec repository (https://europe-west3-maven.pkg.dev/talsec-artifact-repository/common)
[Android] Improved KernelSU detection
[Android] Improved hook detection
[Android] Improved Frida detection
[Android] Improved root detection capabilities
[Android] Fixed native crash caused by std::terminate() race condition
[Android] Fixed periodic hook and root check overwriting
[Android] Fixed root detection crash in obfuscated release builds
[Android] Fixed hardware-backed keystore detection failing with NoSuchMethodError
❗️Breaking: SuspiciousAppInfo.reason (string) renamed to reasons (string[])
❗️Breaking: Value "blacklist" in reasons renamed to "blocklist"
Removed TalsecMalwareConfig type and TalsecAndroidConfig.malwareConfig field
[Android] New API class SuspiciousAppDetectionConfig that can be used to configure malware detection
[Android] New API for malware detection configuration in TalsecConfig, see TalsecConfig.Builder#suspiciousAppDetection
[Android] Fine-tuned location spoofing detection
[Android] Modified malware incident log structure for better aggregation
[Android] Fixed VerifyError caused by JaCoCo bytecode instrumentation
[Android] Fixed a potential cause of crash in the multi-instance detector
[Android] Fixed Java interoperability of ScreenProtector methods
Fixed case where event dispatchers on Android were not initialized before calling onResume at the app launch
[iOS] Fixed new jailbreak checks false positives on iOS 14 and 13
[iOS] Fixed false positives with jailbreak on iOS 15 and 16
Added cache for freeRASP callbacks when listener is not registered with the app
Added API for automation callback into ThreatEventActions (Android only)
[Android] Added new detection check for KernelSU
Updated compile and target SDK versions to 36 on Android
Higher compileSdk from [rootProject, plugin] is now used in build.gradle on Android
[Android] Removed unused library tmlib
[Android] Removed deprecated monitoring feature
Prevent multiple registration of the freeRASP listeners on the native side
[Android] Fixed memory management issues in the native code
[Android] Patched possibility of getInstalledPackages throwing DeadSystemException
Added killOnBypass to TalsecConfig that configures if the app should be terminated when the threat callbacks are suppressed/hooked by an attacker (Android only) ()
Added API for timeSpoofing callback into ThreatEventActions (Android only)
Changed deprecated initialize for pluginInitialize on Android
Improved the RASP listener registration
[Android] Shortened the value of threat detection interval
[Android] Removed deprecated functionality Pbkdf2Native and both related native libraries (libpbkdf2_native.so and libpolarssl.so)
Resolved potential collision in threat identifiers
[Android] ANR issue caused by registerScreenCaptureCallback() method on the main thread
[Android] NullPointerException when checking key alias in Keystore on Android 7
Fixed
Issue with empty SharedPreferences files
Changed
Decreased version of Kotlin to 2.0.0
Added interface for multi-instance detection
[iOS] Added palera1n jailbreak detection
[iOS] Improved Dopamine jailbreak detection
[Android] Improved emulator detection
[Android] Added support for 16 KB pages
[iOS] Resolved memory-related stability issues
[Android] Removed malware report duplicates
Added interface for screenshot / screen recording blocking on iOS.
Changed
Plugin now requires kotlin version >= 2.0.0.
Improvements
Added interface for external ID storage.
Added eventId to the logs, which is unique per each log. It allows traceability of the same log across various systems.
[Android] New root detection checks added.
Fixed
[iOS] Resolved an issue with the screen recording detection.
[iOS] Resolved an issue that prevented Xcode tests from running correctly.
[Android] Compile API increased to 35, dependencies updated
[Android] Internal library obfuscation reworked
[Android] Root detection divided into 2 parts (quick initial checks, and time-demanding asynchronous post checks)
[iOS] Improvement of the obfuscation of the SDK
[Android] ANR issues bug-fixing
Added screenshot - detection of screenshots, refer to the .
Added screenRecording - detection of screen recording, refer to the .
Added blockScreenCapture for FLAG_SECURE control, an
[Android] Set following required SDK versions for Android plugin:
minSdkVersion 23
targetSdkVersion to 35
compileSdkVersion to 35
[Android] Improved root detection
[Android] Proguard rules to address warnings from okhttp dependency
[Android] Added request integrity information to data collection headers.
[Android] Enhanced and accelerated the data collection logic.
App icons for detected malware are not fetched automatically anymore, which reduces computation required to retrieve malware data. From now on, app icons have to be retrieved using the getAppIcon method.
Parsing of malware data is now async.
[Android] Malware data is now parsed on background thread to improve responsiveness.
[Android] adbEnabled callback, allowing you to detect USB debugging option enabled in the developer settings on the device.
Added configuration fields for malware detection.
[Android] Malware detection as a new callback for enhanced app security.
[Android] Refactoring Magisk checks in the root detection.
[iOS] Enhanced security with Detection to identify compromised devices.
Maintenance
BREAKING CHANGE: New dependency is required to run freeRASP; add following plugin to android/build.gradle:
[iOS] Updated SDK code signing; it will now be signed with:
Team ID: PBDDS45LQS
Team Name: Lynx SFT s.r.o.
[Android] Resolved IllegalArgumentException caused by unregistering not registered receiver in TalsecMonitoringReceiver
[iOS] Renewed the signing certificate.
[Android] Reported ANR issues present on some devices were resolved ().
[Android] Reported crashes caused by ConcurrentModificationException and NullPointerException were resolved ().
[Android] Reported crashes caused by the UnsupportedOperationException were resolved.
[Android] False positives for hook detection.
[Android] Added the auditing of the internal execution for the future check optimization and overall security improvements.
[iOS] jailbreak detection.
Improved error messages when validation of the freeRASP configuration fails.
Updated CURL to 8.8.0 and OpenSSL to 3.0.14 ().
[Android] Changed the way TalsecConfig is created, we introduced a Builder pattern to make the process more streamlined and readable.
[Android] Fixed native crashes (SEGFAULT errors) in ifpip method.
[Android] Fixed collision for command line tools (like ping) invoked without absolute path ().
Added a new threat systemVPN for VPN detection.
[Android] Added a new threat devMode for Developer mode detection.
Updated the CA bundle to enhance security for secure connections.
[Android] Updated the GMS dependency to a newer version for improved performance and compatibility.
[iOS] Passcode check is now performed periodically.
Resolved a problem with displaying the Arabic alphabet in logs caused by the device’s default system locale.
Fixed BAD_ACCESS error occurring in specific versions of cordova-ios plugin ().
[Android] Removed the talsec namespace that caused change of namespaces for whole app.
[iOS] Fixed issue causing app crash with lower versions of cordova-ios plugin.
[Android] Updated freeRASP SDK artifact hosting ensuring better stability and availibility.
Curious about more in-depth changes for Cordova? Head over to our for the complete history of updates!
Github Changelog: https://github.com/talsec/Free-RASP-Capacitor/releases
[Android] Fixed the reporting issue in root detection
[Android] Fixed the reporting issue in hook detection
[Android] Fixed ANR during SDK initialization caused by blocking I/O operations
[Android] Fixed background SDK initialization stalling when the shared thread pool is saturated
bootloader threat callback, reporting an unlocked or compromised bootloader — Android only
[Android] Added bootloader detection (unlocked/compromised) with onBootloader() callback
[Android] Added option to fetch JitPack dependencies from our own Talsec repository (https://europe-west3-maven.pkg.dev/talsec-artifact-repository/common)
[Android] Improved KernelSU detection
[Android] Improved hook detection
[Android] Improved Frida detection
[Android] Improved root detection capabilities
[Android] Fixed native crash caused by std::terminate() race condition
[Android] Fixed periodic hook and root check overwriting
[Android] Fixed root detection crash in obfuscated release builds
[Android] Fixed hardware-backed keystore detection failing with NoSuchMethodError
Swift Package Manager support for iOS. CocoaPods remains supported as a fallback
[iOS] Added support for postponed checks, therefore, due to slower execution, some subchecks are run after initial startup checks
[iOS] Improved hook detection
[iOS] Fixed issue with app's color scheme initialization
[iOS] Fixed bad memory access in jailbreak check
❗️Breaking: SuspiciousAppInfo.reason (string) renamed to reasons (string[])
❗️Breaking: Value "blacklist" in reasons renamed to "blocklist"
Added SuspiciousAppDetectionConfig for malware detection configuration
[Android] New API class SuspiciousAppDetectionConfig that can be used to configure malware detection
[Android] New API for malware detection configuration in TalsecConfig, see TalsecConfig.Builder#suspiciousAppDetection
Removed TalsecMalwareConfig type and TalsecAndroidConfig.malwareConfig field
[Android] Fine-tuned location spoofing detection
[Android] Modified malware incident log structure for better aggregation
[Android] Fixed VerifyError caused by JaCoCo bytecode instrumentation
[Android] Fixed a potential cause of crash in the multi-instance detector
[Android] Fixed Java interoperability of ScreenProtector methods
Fixed case where event dispatchers on Android were not initialized before calling onResume at the app launch
[iOS] Fixed new jailbreak checks false positives on iOS 14 and 13
[iOS] Fixed false positives with jailbreak on iOS 15 and 16
[Android] Added support for KernelSU to the existing root detection capabilities
[Android] Added support for HMA to the existing root detection capabilities
[Android] Added new malware detection capabilities
Refactor the Android plugin to separate the logic for managing listener states
[Android] Removed unused library tmlib
[Android] Refactoring of signature verification code
[Android]
[Android] Fixed exception handling for the KeyStore getEntry operation
[Android] Fixed issue in ScreenProtector concerning the onScreenRecordingDetected invocations
[Android] Merged internal shared libraries into a single one, reducing the final APK size
Resolved potential NullPointerException when execution state events are being sent
Added cache for freeRASP callbacks when listener is not registered with the app
Added API for automation callback into ThreatEventActions (Android only)
Updated compile and target SDK versions to 36 on Android
Prevent multiple registration of the freeRASP listeners on the native side
[Android] Added killOnBypass to TalsecConfig that configures if the app should be terminated when the threat callbacks are suppressed/hooked by an attacker (Android only) ()
Added API for timeSpoofing callback into ThreatEventActions (Android only)
[Android] Added killOnBypass method to the TalsecConfig.Builder that configures if the app should be terminated when the threat callbacks are suppressed/hooked by an attacker
We are introducing a new capability, detecting whether the device time has been tampered with (timeSpoofing)
We are introducing a new capability, detecting whether the location is being spoofed on the device (
[Android] Deprecated Nexus repository removed (GCP artifact registry is the main supported distribution repository)
[Android] Shortened the value of threat detection interval
[Android] Refactoring of internal architecture of SDK that newly uses Coroutines to manage threading
[Android] Update of internal dependencies and security libraries
[Android] Resolved potential collision in threat identifiers
[Android] Root detection related bugs causing false positives
[Android] ANR issue caused by registerScreenCaptureCallback() method on the main thread
[Android] Added killOnBypass to TalsecConfig that configures if the app should be terminated when the threat callbacks are suppressed/hooked by an attacker (Android only) ()
Added API for timeSpoofing callback into ThreatEventActions (Android only)
[Android] Added killOnBypass method to the TalsecConfig.Builder that configures if the app should be terminated when the threat callbacks are suppressed/hooked by an attacker
We are introducing a new capability, detecting whether the device time has been tampered with (timeSpoofing)
We are introducing a new capability, detecting whether the location is being spoofed on the device (
[Android] Deprecated Nexus repository removed (GCP artifact registry is the main supported distribution repository)
[Android] Shortened the value of threat detection interval
[Android] Refactoring of internal architecture of SDK that newly uses Coroutines to manage threading
[Android] Update of internal dependencies and security libraries
[Android] Resolved potential collision in threat identifiers
[Android] Root detection related bugs causing false positives
[Android] ANR issue caused by registerScreenCaptureCallback() method on the main thread
[Android] Issue with empty SharedPreferences files
[Android] Decreased version of Kotlin to 2.0.0
Added interface for multi-instance detection
[iOS] Added palera1n jailbreak detection
[iOS] Improved Dopamine jailbreak detection
[Android] Improved emulator detection
[Android] Added support for 16 KB pages
[iOS] Resolved memory-related stability issues
[Android] Removed malware report duplicates
Added interface for screenshot / screen recording blocking on iOS.
Added interface for external ID storage.
Added eventId to the logs, which is unique per each log. It allows traceability of the same log across various systems.
[Android] New root detection checks added.
[iOS] Resolved an issue with the screen recording detection.
[iOS] Resolved an issue that prevented Xcode tests from running correctly.
Android SDK requires kotlin_version >= 2.0.0
[Android] Compile API increased to 35, dependencies updated
[Android] Internal library obfuscation reworked
[Android] ANR issues bug-fixing
Added screenshot - detection of screenshots, refer to the .
Added screenRecording - detection of screen recording, refer to the .
Added blockScreenCapture for FLAG_SECURE control, an
[Android] Raised Android compileSDK level to 35
[Android] Set minifyEnabled in plugin to true implicitly
[Android] Improved root detection
[Android] Proguard rules to address warnings from okhttp dependency
[Android] Added request integrity information to data collection headers.
[Android] Enhanced and accelerated the data collection logic.
App icons for detected malware are not fetched automatically anymore, which reduces computation required to retrieve malware data. From now on, app icons have to be retrieved using the getAppIcon method.
Parsing of malware data is now async.
[Android] Malware data is now parsed on background thread to improve responsiveness.
[Android] adbEnabled callback, allowing you to detect USB debugging option enabled in the developer settings on the device.
Added configuration fields for malware detection.
[Android] Malware detection as a new callback for enhanced app security.
[Android] Refactoring Magisk checks in the root detection.
[iOS] Enhanced security with Detection to identify compromised devices.
Maintenance
[iOS] Updated SDK code signing; it will now be signed with:
Team ID: PBDDS45LQS
Team Name: Lynx SFT s.r.o.
Bug Fix
Resolved compatibilty issues with JDK 21
[iOS] Renewed the signing certificate.
[Android] Reported ANR issues present on some devices were resolved ().
[Android] Reported crashes caused by ConcurrentModificationException and NullPointerException were resolved ().
[Android] Reported crashes caused by the UnsupportedOperationException were resolved.
[Android] False positives for hook detection.
[Android] Added the auditing of the internal execution for the future check optimization and overall security improvements.
[iOS] jailbreak detection.
Improved error messages when validation of the freeRASP configuration fails.
Updated CURL to 8.8.0 and OpenSSL to 3.0.14 ().
[Android] Changed the way TalsecConfig is created, we introduced a Builder pattern to make the process more streamlined and readable.
[Android] Fixed native crashes (SEGFAULT errors) in ifpip method.
[Android] Fixed collision for command line tools (like ping) invoked without absolute path ().
Added a new threat systemVPN for VPN detection.
[Android] Added a new threat devMode for Developer mode detection.
Updated the CA bundle to enhance security for secure connections.
[Android] Updated the GMS dependency to a newer version for improved performance and compatibility.
[iOS] Passcode check is now performed periodically.
Resolved a problem with displaying the Arabic alphabet in logs caused by the device’s default system locale.
[Android] Updated freeRASP SDK artifact hosting ensuring better stability and availibility.
[iOS] Added Privacy Manifest.
[iOS] Added codesigning for the SDK, it is signed by:
Team ID: ASQC376HCN,
Updated CURL to 8.5.0 and OpenSSL to 1.1.1w.
[Android] Shortened duration of threat evaluation.
[Android] Improved appIntegrity
[Android] Fixed a native crash bug during one of the native root checks (detected after NDK upgrade).
[iOS] Fixed memory leak ()
[Android] Fixed bug that prevented firing callbacks in specific situations.
[iOS] Fixed bug that caused app being killed in specific situations ().
Curious about more in-depth changes for Capacitor? Head over to our for the complete history of updates!
[iOS] Improved jailbreak detection
[Android] Fixed hardware-backed keystore detection failing with NoSuchMethodError on some Android 12+ devices
reasonsValue "blacklist" in reasons renamed to "blocklist"
Removed MalwareConfig and AndroidConfig.malwareConfig — use SuspiciousAppDetectionConfig instead
TalsecConfig.Builder#suspiciousAppDetection[Android] Fixed Kotlin classpath conflicts in SDK dependency resolution (Kotlin 2.0.0)
[Android] Added onAutomationDetected() callback to ThreatDetected interface
We are introducing a new capability, detecting whether the device is being automated using tools like Appium
[Android] Added value restrictions to externalId
Method storeExternalId() now returns ExternalIdResult, which indicates Success or Error when externalId violates restrictions
[iOS] Added time spoofing detection, detecting an inaccurate device clock. It is a new threat timeSpoofing.
[Android] Improved root detection capabilities
[Android] Detection of wireless ADB added to ADB detections
[iOS] Improved jailbreak detection methods.
[Android] Fixed bug related to key storing in keystore type detection (hw-backed keystore check)
[Android] Fixed manifest queries merge
We are introducing a new capability, detecting whether the device time has been tampered with
Added onLocationSpoofing callback to ThreatCallback for handling Threat.locationSpoofing threat (Android only)
We are introducing a new capability, detecting whether the location is being spoofed on the device.
Added onUnsecureWifi callback to ThreatCallback for handling Threat.unsecureWifi threat (Android only)
We are introducing a new capability, detecting whether the device is connected to an unsecured Wi-Fi network.
Added onAllChecksDone callback to new RaspExecutionStateCallback
We are introducing a new callback that notifies when all security checks have been completed.
[Android] Root detection divided into 2 parts (quick initial checks, and time-demanding asynchronous post checks)
[iOS] Improvement of the obfuscation of the SDK
[iOS] Deep signing of the OpenSSL binaries
Added isScreenCaptureBlocked - to receive whether the screen capture is blocked
[Android] Refactored fetching the list of installed applications for root and hook detection.
[iOS] Enhanced and accelerated the data collection logic.
Threat.devMode[Android] Added a new callback onDevMode in ThreatCallback for handling Threat.devMode threat.
AHEAD iTec, s.r.o..[iOS] Improved jailbreak detection
[Android] Fixed hardware-backed keystore detection failing with NoSuchMethodError on some Android 12+ devices
[iOS] Improved hook detection
❗️Breaking: Removed MalwareConfig and AndroidConfig.malwareConfig
[Android] Fixed Kotlin classpath conflicts in SDK dependency resolution (Kotlin 2.0.0)
[Android] Added onAutomationDetected() callback to ThreatDetected interface — introducing a new capability, detecting whether the device is being automated using tools like Appium
[Android] Added value restrictions to externalId — storeExternalId() now returns ExternalIdResult, indicating Success or Error when externalId violates restrictions
[iOS] Added time spoofing detection, detecting an inaccurate device clock. It is a new threat timeSpoofing
[Android] Updated compile and target API to 36
[Android] Improved root detection capabilities
[Android] Detection of wireless ADB added to ADB detections
[iOS] Improved jailbreak detection methods
[Android] Fixed bug related to key storing in keystore type detection (hw-backed keystore check)
[Android] Fixed manifest queries merge
unsecureWifi callback into ThreatEventActions (Android only)Added API for allChecksFinished callback into new RaspExecutionStateEventActions object
Added matched permissions to SuspiciousAppInfo object when malware detection reason is suspiciousPermission
We are introducing a new capability, detection of unsecure WiFi (unecureWifi)
Removed deprecated functionality Pbkdf2Native and both related native libraries (libpbkdf2_native.so and libpolarssl.so)
Added new RaspExecutionState which contains onAllChecksFinished() method, which is triggered after all checks are completed.
Added matched permissions to SuspiciousAppInfo object when malware detection reason is suspiciousPermission
New option to start Talsec, Talsec.start() takes new parameter TalsecMode that determines the dispatcher thread of initialization and sync checks (uses background thread by default)
Capability to check if another app has an option REQUEST_INSTALL_PACKAGES enabled in the system settings to malware detection
DeadApplicationException when calling Settings.Global.getInt or Settings.Secure.getInt on invalid context
AndroidKeyStore crashes causing java.util.concurrent.TimeoutException when calling finalize() method on Cipher (GC issues)
Fixed issue with late initializers and TalsecMode coroutines scopes
[Android] Root detection divided into 2 parts (quick initial checks, and time-demanding asynchronous post checks)
[iOS] Improvement of the obfuscation of the SDK
[iOS] Deep signing of the OpenSSL binaries
Added isScreenCaptureBlocked - to receive whether the screen capture is blocked
[Android] Refactored fetching the list of installed applications for root and hook detection.
Team Name: AHEAD iTec, s.r.o..
[iOS] Improved obfuscation of Swift and C strings.
[iOS] Added support for postponed checks, therefore, due to slower execution, some subchecks are run after initial startup checks
[iOS] Improved jailbreak detection
[iOS] Improved hook detection
[iOS] Fixed issue with app's color scheme initialization
[iOS] Fixed bad memory access in jailbreak check
❗️Breaking: Removed TalsecMalwareConfig type and TalsecAndroidConfig.malwareConfig field
❗️Breaking: SuspiciousAppDetectionConfig.malwareScanScope and reasonMode are now required
[Android] Fixed Kotlin classpath conflicts in SDK dependency resolution (Kotlin 2.0.0)
[iOS] Fixed retrigger jailbreak issue on iOS 15 and 16
KernelSU to the existing root detection capabilities[Android] Added support for HMA to the existing root detection capabilities
[Android] Added new malware detection capabilities
[Android] Added onAutomationDetected() callback to ThreatDetected interface — introducing a new capability, detecting whether the device is being automated using tools like Appium
[Android] Added value restrictions to externalId — storeExternalId() now returns ExternalIdResult, indicating Success or Error when externalId violates restrictions
[iOS] Added time spoofing detection, detecting an inaccurate device clock. It is a new threat timeSpoofing
[Android] Refactoring of signature verification code
[Android] Updated compile and target API to 36
[Android] Improved root detection capabilities
[Android] Detection of wireless ADB added to ADB detections
[iOS] Improved jailbreak detection methods
[Android] Patched possibility of getNetworkCapabilities throwing SecurityException
[Android] Fixed well-known issue of Cipher.init throwing KeyStoreConnectException
[Android] Fixed exception handling for the KeyStore getEntry operation
[Android] Fixed issue in ScreenProtector concerning the onScreenRecordingDetected invocations
[Android] Merged internal shared libraries into a single one, reducing the final APK size
[Android] Fixed bug related to key storing in keystore type detection (hw-backed keystore check)
[Android] Fixed manifest queries merge
unsecureWifi callback into ThreatEventActions (Android only)Added API for allChecksFinished callback into new RaspExecutionStateEventActions object
Added matched permissions to SuspiciousAppInfo object when malware detection reason is suspiciousPermission
[Android] Added killOnBypass method to the TalsecConfig.Builder that configures if the app should be terminated when the threat callbacks are suppressed/hooked by an attacker ()
[Android] We are introducing a new capability, detecting whether the device time has been tampered with (timeSpoofing)
[Android] We are introducing a new capability, detecting whether the location is being spoofed on the device (locationSpoofing)
[Android] We are introducing a new capability, detection of unsecure WiFi (unecureWifi)
[Android] Added new RaspExecutionState which contains onAllChecksFinished() method, which is triggered after all checks are completed
[Android] Added matched permissions to SuspiciousAppInfo object when malware detection reason is suspiciousPermission
[Android] New option to start Talsec, Talsec.start() takes new parameter TalsecMode that determines the dispatcher thread of initialization and sync checks (uses background thread by default)
[Android] Capability to check if another app has an option REQUEST_INSTALL_PACKAGES enabled in the system settings to malware detection
[Android] Update of internal dependencies and security libraries
[iOS] Updated internal dependencies
[Android] JaCoCo issue causing MethodTooLargeException during instrumentation
[Android] DeadApplicationException when calling Settings.Global.getInt or Settings.Secure.getInt on invalid context
[Android] AndroidKeyStore crashes causing java.util.concurrent.TimeoutException when calling finalize() method on Cipher (GC issues)
[Android] Fixed issue with late initializers and TalsecMode coroutines scopes
[iOS] Deep signing of the OpenSSL binaries
Added isScreenCaptureBlocked - to receive whether the screen capture is blocked
[Android] Refactored fetching the list of installed applications for root and hook detection.
[iOS] Enhanced and accelerated the data collection logic.
[iOS] Improved jailbreak detection
❗️Breaking: Removed TalsecMalwareConfig and TalsecAndroidConfig.malwareConfig
❗️Breaking: SuspiciousAppDetectionConfig.malwareScanScope and reasonMode are now required
[Android] Fixed Kotlin classpath conflicts in SDK dependency resolution (Kotlin 2.0.0)
[iOS] Fixed retrigger jailbreak issue on iOS 15 and 16
[Android] Added onAutomationDetected() callback to ThreatDetected interface — introducing a new capability, detecting whether the device is being automated using tools like Appium
[Android] Added value restrictions to externalId — storeExternalId() now returns ExternalIdResult, indicating Success or Error when externalId violates restrictions
[iOS] Added time spoofing detection, detecting an inaccurate device clock. It is a new threat timeSpoofing
[Android] Improved root detection capabilities
[Android] Detection of wireless ADB added to ADB detections
[iOS] Improved jailbreak detection methods
[Android] Fixed bug related to key storing in keystore type detection (hw-backed keystore check)
[Android] Fixed manifest queries merge
unsecureWifi callback into ThreatEventActions (Android only)Added API for allChecksFinished callback into new RaspExecutionStateEventActions object
[Android] Added matched permissions to SuspiciousAppInfo object when malware detection reason is suspiciousPermission
locationSpoofingWe are introducing a new capability, detection of unsecure WiFi (unecureWifi)
Removed deprecated functionality Pbkdf2Native and both related native libraries (libpbkdf2_native.so and libpolarssl.so)
Added new RaspExecutionState which contains onAllChecksFinished() method, which is triggered after all checks are completed.
[Android] Added matched permissions to SuspiciousAppInfo object when malware detection reason is suspiciousPermission
[Android] New option to start Talsec, Talsec.start() takes new parameter TalsecMode that determines the dispatcher thread of initialization and sync checks (uses background thread by default)
[Android] Capability to check if another app has an option REQUEST_INSTALL_PACKAGES enabled in the system settings to malware detection
[iOS] Updated internal dependencies
NullPointerException when checking key alias in Keystore on Android 7[Android] JaCoCo issue causing MethodTooLargeException during instrumentation
[Android] DeadApplicationException when calling Settings.Global.getInt or Settings.Secure.getInt on invalid context
[Android] AndroidKeyStore crashes causing java.util.concurrent.TimeoutException when calling finalize() method on Cipher (GC issues)
[Android] Fixed issue with late initializers and TalsecMode coroutines scopes
unsecureWifi callback into ThreatEventActions (Android only)Added API for allChecksFinished callback into new RaspExecutionStateEventActions object
[Android] Added matched permissions to SuspiciousAppInfo object when malware detection reason is suspiciousPermission
locationSpoofingWe are introducing a new capability, detection of unsecure WiFi (unecureWifi)
Removed deprecated functionality Pbkdf2Native and both related native libraries (libpbkdf2_native.so and libpolarssl.so)
Added new RaspExecutionState which contains onAllChecksFinished() method, which is triggered after all checks are completed.
[Android] Added matched permissions to SuspiciousAppInfo object when malware detection reason is suspiciousPermission
[Android] New option to start Talsec, Talsec.start() takes new parameter TalsecMode that determines the dispatcher thread of initialization and sync checks (uses background thread by default)
[Android] Capability to check if another app has an option REQUEST_INSTALL_PACKAGES enabled in the system settings to malware detection
[iOS] Updated internal dependencies
NullPointerException when checking key alias in Keystore on Android 7[Android] JaCoCo issue causing MethodTooLargeException during instrumentation
[Android] DeadApplicationException when calling Settings.Global.getInt or Settings.Secure.getInt on invalid context
[Android] AndroidKeyStore crashes causing java.util.concurrent.TimeoutException when calling finalize() method on Cipher (GC issues)
[Android] Fixed issue with late initializers and TalsecMode coroutines scopes
[iOS] Improvement of the obfuscation of the SDK
[iOS] Deep signing of the OpenSSL binaries
Added isScreenCaptureBlocked - to receive whether the screen capture is blocked
[Android] Refactored fetching the list of installed applications for root and hook detection.
[iOS] Enhanced and accelerated the data collection logic.
AHEAD iTec, s.r.o..[iOS] Improved obfuscation of Swift and C strings.
plugins {
id 'org.jetbrains.kotlin.plugin.serialization' version '1.7.10'
}