Skip to content

Threat detection

Talsec edited this page Oct 13, 2022 · 32 revisions

FreeRASP performs several security checks to detect potential threats to the application during its runtime. Each covers a particular attack vector, and the developers (business owners) can choose how to respond to the incidents on their own. Developers can implement an application to kill itself, send a warning to the user, fetch the incident's details, or ignore it entirely.

To help choose an appropriate response, we briefly explain the available checks. Please note that proper response depends heavily on application security requirements and use cases.

Detecting rooted or jailbroken devices

// Root detection on Android
override fun onRootDetected() {
    TODO("Not yet implemented")
}

// iOS jailbreaking detection
case jailbreak

// Flutter root and jailbreak detection
onRootDetected: () => print('root') // Android
onJailbreakDetected: () => print('jailbreak') // iOS

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 or Shadow can hide the privileged access and are often used by attackers.

Talsec 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, Shad0w).

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.

Recommended action: Notify users that their device is insecure and log the event on your BE. Some of the applications (mostly banking) are even killed upon this incident.

Emulator detection

// Android emulator check
override fun onEmulatorDetected() {
    TODO("Not yet implemented")
}

// iOS simulator detection
case simulator

// Flutter checks
onEmulatorDetected: () => print('emulator') // Android
onSimulatorDetected: () => print('simulator') // iOS

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.

Talsec provides real-time emulator/simulator detection, which increases the difficulty of running the application in a compromised environment.

Recommended action: Notify users that their device is insecure and log the event on your BE. Some of the applications (mostly banking) are even killed upon this incident.

Hook detection

// Android hook check
override fun onHookDetected() {
    TODO("Not yet implemented")
}

// iOS hook detection
case runtimeManipulation

// Flutter detections
onHookDetected: () => print('hook') // Android
onRuntimeManipulationDetected: () => print('runtime manipulation') // iOS

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.

Recommended action: Notify users that their device or app is insecure. In some cases, it is recommended to even kill the application.

App tampering detection

// Android tampering
override fun onTamperDetected() {
    TODO("Not yet implemented")
}

// iOS tampering
case signature

// Flutter tamper
onTamperDetected: () => print('tamper') // Android
onSignatureDetected: () => print('signature') // iOS

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.

Recommended action: Kill the application.

Debugger detection

// Android debugger detection
override fun onDebuggerDetected() {
    TODO("Not yet implemented")
}

// iOS debugger detection
case debugger

// FLutter
onDebuggerDetected: () => print('debugger') // both platforms

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.

Recommended action: Kill the application.

Detecting unofficial installation

// Android installation check
override fun onUntrustedInstallationSourceDetected() {
    TODO("Not yet implemented")
}

// iOS installation check
case unofficialStore

// Flutter detection
onUntrustedInstallationDetected: () => print('untrusted install') // Android
onUnofficialStoreDetected: () => print('unofficial store') // iOS

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 other than Google Play Store or Huawei App Gallery. If you want to define which applications can install the application, define its package name in the supportedAlternativeStores parameter, e.g. dev.firebase.appdistribution in case of Firebase distribution.

Recommended action: Notify users that the application is installed from unofficial store. In some cases, it is recommended to even kill the application.

Device binding detection

// Android device binding check
override fun onDeviceBindingDetected() {
    TODO("Not yet implemented")
}

// iOS device binding methods
case deviceChange
case deviceID

// Flutter detection
onDeviceBindingDetected: () => print('device binding') // Android
onDeviceChangeDetected: () => print('device binding') // iOS
onDeviceIdDetected: () => print('device id changed') // iOS

Device binding is attaching an application instance to a particular mobile device. It's used for user authentication by confirming that a user owns a trusted device. This method detects a transfer of an application instance to another device.

The deviceID detects, whether the device identifier has been changed. It can be triggered after reinstallation of the application if there are none other applications from the same vendor installed.

Recommended action: Log the event on your BE and react to it if you need to have an instance attached to a particular mobile device (e.g., activation scenarios), otherwise ignore it.

Keystore/Keychain secure storage check

// Android Keystore
override fun onHardwareBackedKeystoreNotAvailableDetected() {
    TODO("Not yet implemented")
}

// iOS Secure Enclave
case missingSecureEnclave

// Flutter check
onMissingSecureEnclaveDetected: () => print('secure enclave') // iOS

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.

Recommended action: Ignore the callback or log the event to your BE.

Device lock

// Android lock check
override fun onUnlockedDeviceDetected() {
    TODO("Not yet implemented")
}

// iOS lock check
case passcode

// Flutter lock detection
onPasscodeDetected: () => print('passcode') // iOS

Saving any sensitive data on a device without a lock 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.

Recommended action: Log the event on your BE or react to it if you need users to have a screen lock set up, otherwise ignore it.

Clone this wiki locally