RASP Feature Overview
RASP (runtime application self-protection) features protect the app against several attack vectors at runtime. Here is a list of available features:
- Detection of rooted devices
- Detection of emulators
- Detection of attached debuggers
- Detection of app repackaging
- Detection of screen sharing (screen mirroring)
- Blocking screen readers from reading app screens
- Screenshot blocking and detection
- Tapjacking protection
- Detection of HTTP proxy
- Detection of VPN
- Detection of usage of system screen lock
- Obtaining Play Protect status
- Changing app process name
- Detection of ADB status
- Detection of developer options status
- Detection of biometry enrollment status
- Detection of active call
- Detection of application presence
- Detection of spoofed location
- Activity protection
Configuration
RASP features can be initially configured by building a RaspConfig
instance and passing it to the raspConfig
method in the general AppProtectionConfig
:
val config = AppProtectionConfig.Builder(appContext)
.raspConfig(
RaspConfig.Builder()
// RASP feature configuration
.build()
)
// other Malwarelytics configuration
.build()
When no RaspConfig
instance is provided, all RASP features are turned off. When a RaspConfig
instance is provided, all RASP configurations are enabled by default. However, the repackaging detection feature requires a signatureHash
to be set.
A minimum RASP configuration with all features enabled requires only signatureHash
to be set in RepackageDetectionConfig
:
val config = AppProtectionConfig.Builder(appContext)
.raspConfig(
RaspConfig.Builder()
.repackage(
RepackageDetectionConfig.Builder()
.signatureHash(listOf(SIGNATURE_HASH))
.build()
)
.build()
)
// …
.build()
Available Configuration Items
val raspConfig = RaspConfig.Builder()
.emulator(DetectionConfig)
.root(RootDetectionConfig)
.debugger(
DebuggerDetectionConfig.Builder()
.action(DetectionConfig)
.debuggerTypes(Collection<DebuggerType>)
.build()
)
.repackage(
RepackageDetectionConfig.Builder()
.action(DetectionConfig)
.signatureHash(Collection<String>)
.build()
)
.screenSharing(DetectionConfig)
.screenReader(
ScreenReaderBlockConfig.Builder()
.action(BlockConfig)
.allowedScreenReaders(Collection<RaspConfig.ApkAllowlistItem>)
.build()
)
.screenshot(
ScreenshotConfig.Builder()
.blockAction(BlockConfig)
.detectionAction(SimpleDetectionConfig)
.build()
)
.tapjacking(
TapjackingBlockConfig.Builder()
.action(BlockConfig)
.ignoreTapjackingSystemApps(Boolean)
.blockTapjackingSensitivity(ThreatIndex)
.allowedTapjackingApps(Collection<RaspConfig.ApkAllowlistItem>)
.build()
)
.httpProxy(DetectionConfig)
.vpn(DetectionConfig)
.adb(DetectionConfig)
.activeCall(SimpleDetectionConfig)
.appPresence(
AppPresenceDetectionConfig.Builder()
.action(DetectionConfig)
.remoteDesktopApps(Collection<AppPresenceDetectionConfig.NamedApkItem>)
.build()
)
.processName(ProcessNameConfig)
.sendInfoOutputs(Boolean)
.build()
Method | Description |
---|---|
emulator(DetectionConfig) |
defines the behavior of automatic emulator detection. Defaults to DetectionConfig.Notify . |
root(RootDetectionConfig) |
defines the behavior of automatic root detection. Defaults to RootDetectionConfig.Notify . |
debugger(DebuggerDetectionConfig) |
defines the behavior of automatic debugger detection. Details and defaults are described in Debugger Detection Configuration Items. |
repackage(RepackageDetectionConfig) |
defines the behavior of automatic repackaging detection. Details and defaults are described in Repackage Detection Configuration Items. |
screenSharing(DetectionConfig) |
defines the behavior of automatic screen sharing detection. Defaults to DetectionConfig.Notify . |
screenReader(ScreenReaderBlockConfig) |
defines the behavior of the screen reader blocking feature. Details and defaults are described in Screen Reader Blocking Configuration Items. |
screenshot(ScreenshotConfig) |
defines the behavior of the screenshot blocking and detection features, and screen recording blocking feature. Details and defaults are described in Screenshot Blocking and Detection Configuration Items. |
tapjacking(TapjackingBlockConfig) |
defines the behavior of the tapjacking protection feature. Details and defaults are described in Tapjacking Protection Configuration Items. |
httpProxy(DetectionConfig) |
defines the behavior of HTTP proxy detection. Defaults to DetectionConfig.Notify . |
vpn(DetectionConfig) |
defines the behavior of VPN detection. Defaults to DetectionConfig.Notify . |
adb(DetectionConfig) |
defines the behavior of ADB (Android Debug Bridge) detection. Defaults to DetectionConfig.Notify . |
activeCall(SimpleDetectionConfig) |
defines the behavior of automatic active call detection. Defaults to SimpleDetectionConfig.Notify . |
appPresence(AppPresenceDetectionConfig) |
defines the behavior of automatic app presence detection. Details and defaults are described in App Presence Detection Configuration Items. |
processName(ProcessNameConfig) |
defines the behavior of the changing process name feature. Default to ProcessNameConfig.UseStealthy(null) . |
sendInfoOutputs(Boolean) |
defines whether the outputs of info methods should be sent to the remote server. Defaults to true. Details about these info methods can be found in the section RASP Info Methods. |
The behavior of all the configuration items can be summarized with these rules:
- The
NoAction
values turn the corresponding feature off. In some cases, detection data can be manually obtained throughRaspManager
. - The
Notify
values cause observers (and remote server when configured) to be notified about the corresponding detection. - The
Exit(exitUrl)
values cause the app to be terminated when the corresponding “positive” detection of the feature is detected. TheexitUrl
parameters define URLs to be opened in the system web browser when the app is terminated as a result of the corresponding detection. - The
Block
values turn blocking certain system features on to shield the app against the related vulnerability. - Some of the RASP features require/offer additional parameters for detailed configuration of the corresponding feature.
Detailed information about these configuration items can be found on the documentation pages of individual features.
Debugger Detection Configuration Items
Method | Description |
---|---|
action(DetectionConfig) |
specifies the automatic behavior of the debugger detection feature. Defaults to DetectionConfig.Notify . |
debuggerTypes(Collection<DebuggerType>) |
indicates types of debuggers that will be detected. Defaults to DebuggerType.values().toList() . |
Repackaging Detection Configuration Items
Method | Description |
---|---|
action(DetectionConfig) |
specifies the automatic behavior of the repackaging detection feature. Defaults to DetectionConfig.Exit() . |
signatureHash(Collection<String>) |
SHA-1 of signing certificate(s). One or more values can be set. A lowercase hex value without any byte separators is expected. No default value is set. |
Screen Reader Blocking Configuration Items
Method | Description |
---|---|
action(BlockConfig) |
specifies the automatic behavior of the screen reader blocking feature. Defaults to BlockConfig.Block . |
allowedScreenReaders( Collection<RaspConfig.ApkAllowlistItem>) |
defines a collection of allowed screen readers. The default value is ScreenReaderBlockConfig.DEFAULT_ALLOWED_SCREEN_READERS . |
Screenshot Blocking and Detection Configuration Items
Method | Description |
---|---|
blockAction(BlockConfig) |
specifies the automatic behavior of the screenshot blocking feature. Defaults to BlockConfig.Block . |
detectionAction(SimpleDetectionConfig) |
specifies the automatic behavior of the screenshot detection feature. Defaults to SimpleDetectionConfig.Notify . Screenshot detection works only on Android 14+. |
Tapjacking Protection Configuration Items
Method | Description |
---|---|
action(BlockConfig) |
specifies the automatic behavior of the tapjacking protection feature. Defaults to BlockConfig.Block . However, tapjacking is not blocked unless a “problematic” app is installed on the device. An app is deemed “problematic” when it meets sensitivity criteria defined by blockTapjackingSensitivity . |
ignoreTapjackingSystemApps(Boolean) |
indicates whether tapjacking protection should ignore system apps in the checks. Defaults to false . If set to true all system apps will be ignored and tapjacking will get blocked only if a non-system “problematic” app is present. |
blockTapjackingSensitivity(ThreatIndex) |
defines tapjacking protection sensitivity. Defaults to ThreatIndex.HIGHLY_DANGEROUS . |
allowedTapjackingApps( Collection<RaspConfig.ApkAllowlistItem>) |
defines a collection of allowed app capable of tapjacking. It is empty by default. |
App Presence Detection Configuration Items
Method | Description |
---|---|
action(DetectionConfig) |
specifies the automatic behavior of the app presence detection feature. Defaults to DetectionConfig.Notify . |
remoteDesktopApps( Collection<NamedApkItem>) |
defines a collection of unwanted apps capable of providing remote desktop functionality. The default value is AppPresenceDetectionConfig.DEFAULT_REMOTE_DESKTOP_APPS . |
Obtaining Detection Results
After Malwarelytics for Android has been initialized with certain configurations, RASP features can be accessed with RaspManager
. You can obtain an instance from AppProtection
by calling:
val raspManager = appProtection.getRaspManager()
When RaspConfig
is not provided, all RASP features are turned off and the RaspManager
instance cannot be used to access RASP features.
You can use the RaspManager
instance to register and unregister a RASP observer or to trigger RASP checks manually.
Checking If RASP Is Enabled
An app can check if the RASP feature is enabled in runtime by calling:
val enabled = raspManager.isEnabled()
Observing RASP Detections
An observer can be registered in RaspManager
to notify the app about any RASP detections. This is an example of registering an observer in which all available detections are handled:
val raspObserver = object : RaspObserver {
override fun onEmulatorDetected(emulatorDetection: EmulatorDetection) {
// handle emulator detection
}
override fun onRootDetected(rootDetection: RootDetection) {
// handle root detection
}
override fun onDebuggerDetected(debuggerDetected: Boolean) {
// handle debugger detection
}
override fun onRepackagingDetected(repackagingResult: RepackagingResult) {
// handle repackaging detection
}
override fun onScreenSharingDetected(screenSharingDetection: ScreenSharingDetection) {
// handle screen sharing detection
}
override fun onScreenReaderDetected(screenReaderDetection: ScreenReaderDetection) {
// handle screen reader detection
}
override fun onScreenshotDetected(screenshotDetection: ScreenshotDetection) {
// handle screenshot detection
// delivered only on Android 14+
}
override fun onTapjackingDetected(tapjackingDetection: TapjackingDetection) {
// handle tapjacking detection
}
override fun onHttpProxyDetected(httpProxyDetected: Boolean) {
// handle HTTP proxy detection
}
override fun onVpnDetected(vpnEnabled: Boolean) {
// handle VPN detection
}
override fun onAdbStatusDetected(adbStatus: Boolean) {
// handle ADB status detection
}
override fun onActiveCallDetected(activeCallDetection: ActiveCallDetection) {
// handle active call detection
}
override fun onAppPresenceChanged(appPresenceDetection: AppPresenceDetection) {
// handle app presence detection
}
}
raspManager.registerRaspObserver(raspObserver)
The observer can be unregistered when it is no longer necessary:
raspManager.unregisterRaspObserver(raspObserver)
The observer callbacks are always called on a background thread before the app exits. It’s recommended to perform only quick lightweight processing in the callback as any heavy processing or threading is not guaranteed to be completed.
Any detections that are manually triggered via RaspManager
(see section below) are not propagated into the observer.
More details about RaspObserver
behavior can be found in RASP Observer.
Triggering RASP Checks Manually
All RASP checks can be triggered manually with RaspManager
. There are two types of manual checks: the is-
methods give a simple boolean answer whereas the get-
methods provide more detailed information.
// root detection
val rootDetection = raspManager.getRootDetection()
val isRooted = raspManager.isDeviceRooted()
// emulator detection
val emulatorDetection = raspManager.getEmulatorDetection()
val isDeviceEmulator = raspManager.isDeviceEmulator()
// debugger
val debuggerDetection = raspManager.getDebuggerDetection()
val isDebuggerAttached = raspManager.isDebuggerAttached()
// repackaging
val repackagingResult = raspManager.isAppRepackaged()
// screen sharing
val screenSharingDetection = raspManager.getScreenSharingDetection()
val isScreenShared = raspManager.isScreenShared()
// screen reader
val screenReaderDetection = raspManager.getScreenReaderDetection()
val isNotAllowedScreenReaderEnabled = raspManager.isNotAllowedScreenReaderEnabled()
// screen lock usage
val isDeviceUsingScreenLock = raspManager.isDeviceUsingScreenLock()
// Play Protect status
val isPlayProtectEnabled = raspManager.isPlayProtectEnabled()
// tapjacking
val isBadTapjackingCapableAppPresent = raspManager.isBadTapjackingCapableAppPresent()
val tapjackingDetection = raspManager.getTapjackingDetection()
// http proxy detection
val isHttpProxyEnabled = raspManager.isHttpProxyEnabled()
val httpProxyDetection = raspManager.getHttpProxyDetection()
// VPN
val isVpnEnabled = raspManager.isVpnEnabled()
// ADB status
val isAdbEnabled = raspManager.isAdbEnabled()
// developer options status
val isDeveloperOptionsEnabled = raspManager.isDeveloperOptionsEnabled()
// biometry enrollment status
val biometryDetection = raspManager.getBiometryDetection()
// active call
val isCallActive = raspManager.isCallActive()
val activeCallDetection = raspManager.getActiveCallDetection()
RASP Info Methods
Few RASP features do not have any callbacks or passive behavior. These features only provide methods for obtaining certain information. These methods are:
// screen lock usage
val isDeviceUsingScreenLock = raspManager.isDeviceUsingScreenLock()
// biometry enrollment status
val biometryDetection = raspManager.getBiometryDetection()
// Play Protect status
val isPlayProtectEnabled = raspManager.isPlayProtectEnabled()
// developer options status
val isDeveloperOptionsEnabled = raspManager.isDeveloperOptionsEnabled()
// spoofed location
val isLocationMocked = raspManager.isLocationMocked(location)
val spoofedLocationDetection: SpoofedLocationDetection = raspManager.getSpoofedLocationDetection()