Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,39 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [8.2.0] - 2026-08-05

- Android SDK version: 19.2.1
- iOS SDK version: 7.1.1

### Flutter

#### Added

- Added `onBootloader` callback for detecting an unlocked or compromised bootloader (Android only).

### Android

#### Added

- Added bootloader detection (unlocked/compromised) with `onBootloader()` callback
- Added option to fetch JitPack dependencies from our own Talsec repository

#### Changed

- Improved KernelSU detection
- Improved hook detection
- Improved Frida detection
- Improved root detection capabilities

#### Fixed

- Fixed native crash caused by std::terminate() race condition
- Fixed periodic hook and root check overwriting
- Fixed crash inside AppZygotePreload during root detection
- Fixed root detection crash in obfuscated release builds
- Fixed hardware-backed keystore detection failing with `NoSuchMethodError` on some Android 12+ devices

## [8.1.0] - 2026-07-23

- Android SDK version: 18.3.0
Expand Down
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ version '1.0-SNAPSHOT'

buildscript {
ext.kotlin_version = '2.1.0'
ext.talsec_version = '18.3.0'
ext.talsec_version = '19.2.1'
repositories {
google()
mavenCentral()
Expand Down
12 changes: 6 additions & 6 deletions android/src/main/kotlin/com/aheaditec/freerasp/Extensions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ package com.aheaditec.freerasp
import android.content.Context
import android.content.pm.PackageInfo
import android.os.Build
import com.aheaditec.talsec_security.security.api.ExternalIdResult
import com.aheaditec.talsec_security.security.api.MalwareScanScope
import com.aheaditec.talsec_security.security.api.ReasonMode
import com.aheaditec.talsec_security.security.api.ScopeType
import com.aheaditec.talsec_security.security.api.SuspiciousAppDetectionConfig
import com.aheaditec.talsec_security.security.api.SuspiciousAppInfo
import app.talsec.rasp.security.api.ExternalIdResult
import app.talsec.rasp.security.api.MalwareScanScope
import app.talsec.rasp.security.api.ReasonMode
import app.talsec.rasp.security.api.ScopeType
import app.talsec.rasp.security.api.SuspiciousAppDetectionConfig
import app.talsec.rasp.security.api.SuspiciousAppInfo
import io.flutter.plugin.common.MethodChannel
import org.json.JSONArray
import org.json.JSONObject
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import androidx.annotation.RequiresApi
import androidx.core.content.ContextCompat
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import com.aheaditec.talsec_security.security.api.Talsec
import app.talsec.rasp.security.api.Talsec
import io.flutter.Log
import java.util.function.Consumer

Expand Down
2 changes: 2 additions & 0 deletions android/src/main/kotlin/com/aheaditec/freerasp/Threat.kt
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,6 @@ internal sealed class Threat(val value: Int) {
object LocationSpoofing : Threat(653273273)

object Automation : Threat(298453120)

object Bootloader : Threat(1651076936)
}
2 changes: 1 addition & 1 deletion android/src/main/kotlin/com/aheaditec/freerasp/Utils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.os.Build
import android.util.Base64
import com.aheaditec.talsec_security.security.api.TalsecConfig
import app.talsec.rasp.security.api.TalsecConfig
import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package com.aheaditec.freerasp.dispatchers

import com.aheaditec.freerasp.Threat
import com.aheaditec.freerasp.handlers.MethodCallHandler
import com.aheaditec.talsec_security.security.api.SuspiciousAppInfo
import app.talsec.rasp.security.api.SuspiciousAppInfo
import io.flutter.plugin.common.EventChannel.EventSink

internal object ThreatDispatcher {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import com.aheaditec.freerasp.generated.TalsecPigeonApi
import com.aheaditec.freerasp.resolve
import com.aheaditec.freerasp.runResultCatching
import com.aheaditec.freerasp.toPigeon
import com.aheaditec.talsec_security.security.api.SuspiciousAppInfo
import com.aheaditec.talsec_security.security.api.Talsec
import app.talsec.rasp.security.api.SuspiciousAppInfo
import app.talsec.rasp.security.api.Talsec
import io.flutter.Log
import io.flutter.plugin.common.BinaryMessenger
import io.flutter.plugin.common.MethodCall
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import com.aheaditec.freerasp.RaspExecutionStateEvent
import com.aheaditec.freerasp.Threat
import com.aheaditec.freerasp.dispatchers.ExecutionStateDispatcher
import com.aheaditec.freerasp.dispatchers.ThreatDispatcher
import com.aheaditec.talsec_security.security.api.SuspiciousAppInfo
import com.aheaditec.talsec_security.security.api.ThreatListener
import com.aheaditec.talsec_security.security.api.ThreatListener.DeviceState
import com.aheaditec.talsec_security.security.api.ThreatListener.RaspExecutionState
import com.aheaditec.talsec_security.security.api.ThreatListener.ThreatDetected
import app.talsec.rasp.security.api.SuspiciousAppInfo
import app.talsec.rasp.security.api.ThreatListener
import app.talsec.rasp.security.api.ThreatListener.DeviceState
import app.talsec.rasp.security.api.ThreatListener.RaspExecutionState
import app.talsec.rasp.security.api.ThreatListener.ThreatDetected

/**
* A Singleton object that manages the [ThreatListener] to handle detected security threats in the application.
Expand All @@ -19,89 +19,93 @@ import com.aheaditec.talsec_security.security.api.ThreatListener.ThreatDetected
internal object PluginThreatHandler {

private val threatDetected = object : ThreatDetected() {
override fun onRootDetected() {
override fun onPrivilegedAccess() {
ThreatDispatcher.dispatchThreat(Threat.PrivilegedAccess)
}

override fun onDebuggerDetected() {
override fun onDebug() {
ThreatDispatcher.dispatchThreat(Threat.Debug)
}

override fun onEmulatorDetected() {
override fun onSimulator() {
ThreatDispatcher.dispatchThreat(Threat.Simulator)
}

override fun onTamperDetected() {
override fun onAppIntegrity() {
ThreatDispatcher.dispatchThreat(Threat.AppIntegrity)
}

override fun onUntrustedInstallationSourceDetected() {
override fun onUnofficialStore() {
ThreatDispatcher.dispatchThreat(Threat.UnofficialStore)
}

override fun onHookDetected() {
override fun onHooks() {
ThreatDispatcher.dispatchThreat(Threat.Hooks)
}

override fun onDeviceBindingDetected() {
override fun onDeviceBinding() {
ThreatDispatcher.dispatchThreat(Threat.DeviceBinding)
}

override fun onObfuscationIssuesDetected() {
override fun onObfuscationIssues() {
ThreatDispatcher.dispatchThreat(Threat.ObfuscationIssues)
}

override fun onMalwareDetected(suspiciousApps: List<SuspiciousAppInfo>) {
override fun onMalware(suspiciousApps: List<SuspiciousAppInfo>) {
ThreatDispatcher.dispatchMalware(suspiciousApps)
}

override fun onScreenshotDetected() {
override fun onScreenshot() {
ThreatDispatcher.dispatchThreat(Threat.Screenshot)
}

override fun onScreenRecordingDetected() {
override fun onScreenRecording() {
ThreatDispatcher.dispatchThreat(Threat.ScreenRecording)
}

override fun onMultiInstanceDetected() {
override fun onMultiInstance() {
ThreatDispatcher.dispatchThreat(Threat.MultiInstance)
}

override fun onUnsecureWifiDetected() {
override fun onUnsecureWifi() {
ThreatDispatcher.dispatchThreat(Threat.UnsecureWiFi)
}

override fun onTimeSpoofingDetected() {
override fun onTimeSpoofing() {
ThreatDispatcher.dispatchThreat(Threat.TimeSpoofing)
}

override fun onLocationSpoofingDetected() {
override fun onLocationSpoofing() {
ThreatDispatcher.dispatchThreat(Threat.LocationSpoofing)
}

override fun onAutomationDetected() {
override fun onAutomation() {
ThreatDispatcher.dispatchThreat(Threat.Automation)
}

override fun onBootloader() {
ThreatDispatcher.dispatchThreat(Threat.Bootloader)
}
}

private val deviceState = object : DeviceState() {
override fun onUnlockedDeviceDetected() {
override fun onPasscode() {
ThreatDispatcher.dispatchThreat(Threat.Passcode)
}

override fun onHardwareBackedKeystoreNotAvailableDetected() {
override fun onSecureHardwareNotAvailable() {
ThreatDispatcher.dispatchThreat(Threat.SecureHardwareNotAvailable)
}

override fun onSystemVPNDetected() {
override fun onSystemVpn() {
ThreatDispatcher.dispatchThreat(Threat.SystemVPN)
}

override fun onDeveloperModeDetected() {
override fun onDevMode() {
ThreatDispatcher.dispatchThreat(Threat.DevMode)
}

override fun onADBEnabledDetected() {
override fun onAdbEnabled() {
ThreatDispatcher.dispatchThreat(Threat.ADBEnabled)
}
}
Expand All @@ -121,4 +125,4 @@ internal object PluginThreatHandler {
internal fun unregisterListener(context: Context) {
internalListener.unregisterListener(context)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import com.aheaditec.freerasp.RaspExecutionStateEvent
import com.aheaditec.freerasp.ScreenProtector
import com.aheaditec.freerasp.dispatchers.ExecutionStateDispatcher
import com.aheaditec.freerasp.dispatchers.ThreatDispatcher
import com.aheaditec.talsec_security.security.api.Talsec
import com.aheaditec.talsec_security.security.api.TalsecConfig
import app.talsec.rasp.security.api.Talsec
import app.talsec.rasp.security.api.TalsecConfig
import io.flutter.plugin.common.EventChannel.EventSink

/**
Expand Down
1 change: 1 addition & 0 deletions example/lib/threat_notifier.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class ThreatNotifier extends AutoDisposeNotifier<ThreatState> {
onTimeSpoofing: () => _updateThreat(Threat.timeSpoofing),
onLocationSpoofing: () => _updateThreat(Threat.locationSpoofing),
onAutomation: () => _updateThreat(Threat.automation),
onBootloader: () => _updateThreat(Threat.bootloader),
);

final raspExecutionStateCallback =
Expand Down
7 changes: 7 additions & 0 deletions lib/src/callbacks/threat_callback.dart
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class ThreatCallback extends TalsecPigeonApi {
this.onTimeSpoofing,
this.onLocationSpoofing,
this.onAutomation,
this.onBootloader,
});

/// This method is called when a threat related dynamic hooking (e.g. Frida)
Expand Down Expand Up @@ -115,6 +116,12 @@ class ThreatCallback extends TalsecPigeonApi {
/// This method is called when automation is detected
final VoidCallback? onAutomation;

/// This method is called when an unlocked or compromised bootloader is
/// detected.
///
/// Android only
final VoidCallback? onBootloader;

@override
void onMalwareDetected(List<SuspiciousAppInfo> packageInfo) {
onMalware?.call(packageInfo);
Expand Down
8 changes: 8 additions & 0 deletions lib/src/enums/threat.dart
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,11 @@ enum Threat {
///
/// Android only
automation,

/// The device bootloader is unlocked or otherwise compromised.
///
/// Android only
bootloader,
}

/// An extension on the [Threat] enum to provide additional functionality.
Expand Down Expand Up @@ -126,6 +131,7 @@ extension ThreatX on Threat {
/// * 64690214 - screenRecording
/// * 859307284 - multiInstance
/// * 298453120 - automation
/// * 1651076936 - bootloader
static Threat fromInt(int code) {
switch (code) {
case 1268968002:
Expand Down Expand Up @@ -170,6 +176,8 @@ extension ThreatX on Threat {
return Threat.locationSpoofing;
case 298453120:
return Threat.automation;
case 1651076936:
return Threat.bootloader;
default:
// Unknown data came from native code. This shouldn't normally happen.
exit(127);
Expand Down
2 changes: 2 additions & 0 deletions lib/src/talsec.dart
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,8 @@ class Talsec {
callback.onLocationSpoofing?.call();
case Threat.automation:
callback.onAutomation?.call();
case Threat.bootloader:
callback.onBootloader?.call();
}
});
}
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: freerasp
description: Flutter library for improving app security and threat monitoring on Android and iOS mobile devices. Learn more about provided features on the freeRASP's homepage first.
version: 8.1.0
version: 8.2.0
homepage: https://www.talsec.app/freerasp-in-app-protection-security-talsec
repository: https://github.com/talsec/Free-RASP-Flutter

Expand Down
Loading