Skip to content

Commit efee676

Browse files
authored
release: freeRASP 7.4.0 (#192)
* feat: init update * fix: xcframework * revert xcframework update * fix: xcframework * fix handler * fix: android * fix: android * update ios * fix: ios * fix: format * fix: format * update PluginThreatHandler * update TalsecThreatHandler * fix: issues * fix: dart listener * chore: update changelog * chore: update files * chore: update example app * chore: update example app * chore: update example app * update lock handling * handle execution state sink on events * update example app * update example app
1 parent bb151df commit efee676

37 files changed

Lines changed: 728 additions & 604 deletions

CHANGELOG.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,43 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [7.4.0] - 2026-02-10
9+
- Android SDK version: 18.0.2
10+
- iOS SDK version: 6.13.0
11+
12+
### Flutter
13+
14+
#### Added
15+
- Added `onAutomation` callback to `ThreatCallback` for handling `Threat.automation` threat
16+
17+
### Android
18+
19+
#### Added
20+
21+
- Added support for `KernelSU` to the existing root detection capabilities
22+
- Added support for `HMA` to the existing root detection capabilities
23+
- Added new malware detection capabilities
24+
- Added `onAutomationDetected()` callback to `ThreatDetected` interface
25+
- We are introducing a new capability, detecting whether the device is being automated using tools like Appium
26+
- Added value restrictions to `externalId`
27+
- Method `storeExternalId()` now returns `ExternalIdResult`, which indicates `Success` or `Error` when `externalId` violates restrictions
28+
29+
#### Fixed
30+
31+
- Fixed exception handling for the KeyStore `getEntry` operation
32+
- Fixed issue in `ScreenProtector` concerning the `onScreenRecordingDetected` invocations
33+
- Merged internal shared libraries into a single one, reducing the final APK size
34+
- Fixed bug related to key storing in keystore type detection (hw-backed keystore check)
35+
- Fixed manifest queries merge
36+
37+
#### Changed
38+
39+
- Removed unused library `tmlib`
40+
- Refactoring of signature verification code
41+
- Updated compile and target API to 36
42+
- Improved root detection capabilities
43+
- Detection of wireless ADB added to ADB detections
44+
845
## [7.3.0] - 2025-10-20
946
- Android SDK version: 17.0.0
1047
- iOS SDK version: 6.13.0

android/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ version '1.0-SNAPSHOT'
33

44
buildscript {
55
ext.kotlin_version = '2.1.0'
6-
ext.talsec_version = '17.0.0'
6+
ext.talsec_version = '18.0.2'
77
repositories {
88
google()
99
mavenCentral()
@@ -32,7 +32,7 @@ android {
3232
namespace("com.aheaditec.freerasp")
3333
}
3434

35-
compileSdk 35
35+
compileSdk 36
3636

3737
compileOptions {
3838
sourceCompatibility JavaVersion.VERSION_17

android/src/main/kotlin/com/aheaditec/freerasp/FreeraspPlugin.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import android.os.Build
66
import androidx.lifecycle.Lifecycle
77
import androidx.lifecycle.LifecycleEventObserver
88
import androidx.lifecycle.LifecycleOwner
9+
import com.aheaditec.freerasp.handlers.ExecutionStateStreamHandler
910
import com.aheaditec.freerasp.handlers.MethodCallHandler
1011
import com.aheaditec.freerasp.handlers.StreamHandler
1112
import com.aheaditec.freerasp.handlers.TalsecThreatHandler
@@ -17,6 +18,7 @@ import io.flutter.embedding.engine.plugins.lifecycle.FlutterLifecycleAdapter
1718
/** FreeraspPlugin */
1819
class FreeraspPlugin : FlutterPlugin, ActivityAware, LifecycleEventObserver {
1920
private var streamHandler: StreamHandler = StreamHandler()
21+
private var executionStateStreamHandler: ExecutionStateStreamHandler = ExecutionStateStreamHandler()
2022
private var methodCallHandler: MethodCallHandler = MethodCallHandler()
2123
private var screenProtector: ScreenProtector? =
2224
if (Build.VERSION.SDK_INT >= 34) ScreenProtector else null
@@ -30,11 +32,13 @@ class FreeraspPlugin : FlutterPlugin, ActivityAware, LifecycleEventObserver {
3032
context = flutterPluginBinding.applicationContext
3133
methodCallHandler.createMethodChannel(messenger, flutterPluginBinding.applicationContext)
3234
streamHandler.createEventChannel(messenger)
35+
executionStateStreamHandler.createEventChannel(messenger)
3336
}
3437

3538
override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
3639
methodCallHandler.destroyMethodChannel()
3740
streamHandler.destroyEventChannel()
41+
executionStateStreamHandler.destroyEventChannel()
3842
TalsecThreatHandler.detachListener(binding.applicationContext)
3943
}
4044

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package com.aheaditec.freerasp
2+
3+
internal sealed class RaspExecutionStateEvent(val value: Int) {
4+
object AllChecksFinished : RaspExecutionStateEvent(187429)
5+
}

android/src/main/kotlin/com/aheaditec/freerasp/Threat.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,6 @@ internal sealed class Threat(val value: Int) {
4545
object TimeSpoofing : Threat(189105221)
4646

4747
object LocationSpoofing : Threat(653273273)
48+
49+
object Automation : Threat(298453120)
4850
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package com.aheaditec.freerasp.dispatchers
2+
3+
import com.aheaditec.freerasp.RaspExecutionStateEvent
4+
import io.flutter.plugin.common.EventChannel.EventSink
5+
6+
internal class ExecutionStateDispatcher {
7+
private val eventCache = mutableSetOf<RaspExecutionStateEvent>()
8+
9+
var eventSink: EventSink? = null
10+
set(value) {
11+
field = value
12+
if (value != null) {
13+
flushCache(value)
14+
}
15+
}
16+
17+
fun dispatch(event: RaspExecutionStateEvent) {
18+
val sink = synchronized(eventCache) {
19+
val currentSink = eventSink
20+
if (currentSink != null) {
21+
currentSink
22+
} else {
23+
eventCache.add(event)
24+
null
25+
}
26+
}
27+
sink?.success(event.value)
28+
}
29+
30+
private fun flushCache(sink: EventSink) {
31+
val events = synchronized(eventCache) {
32+
val snapshot = eventCache.toSet()
33+
eventCache.clear()
34+
snapshot
35+
}
36+
events.forEach { sink.success(it.value) }
37+
}
38+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package com.aheaditec.freerasp.dispatchers
2+
3+
import com.aheaditec.freerasp.Threat
4+
import com.aheaditec.freerasp.handlers.MethodCallHandler
5+
import com.aheaditec.talsec_security.security.api.SuspiciousAppInfo
6+
import io.flutter.plugin.common.EventChannel.EventSink
7+
8+
internal class ThreatDispatcher {
9+
private val threatCache = mutableSetOf<Threat>()
10+
private val malwareCache = mutableListOf<SuspiciousAppInfo>()
11+
12+
var eventSink: EventSink? = null
13+
set(value) {
14+
field = value
15+
if (value != null) {
16+
flushThreatCache(value)
17+
}
18+
}
19+
20+
var methodSink: MethodCallHandler.MethodSink? = null
21+
set(value) {
22+
field = value
23+
if (value != null) {
24+
flushMalwareCache(value)
25+
}
26+
}
27+
28+
fun dispatchThreat(threat: Threat) {
29+
val sink = synchronized(threatCache) {
30+
val currentSink = eventSink
31+
if (currentSink != null) {
32+
currentSink
33+
} else {
34+
threatCache.add(threat)
35+
null
36+
}
37+
}
38+
sink?.success(threat.value)
39+
}
40+
41+
fun dispatchMalware(apps: List<SuspiciousAppInfo>) {
42+
val sink = synchronized(malwareCache) {
43+
val currentSink = methodSink
44+
if (currentSink != null) {
45+
currentSink
46+
} else {
47+
malwareCache.addAll(apps)
48+
null
49+
}
50+
}
51+
sink?.onMalwareDetected(apps)
52+
}
53+
54+
private fun flushThreatCache(sink: EventSink) {
55+
val threats = synchronized(threatCache) {
56+
val snapshot = threatCache.toSet()
57+
threatCache.clear()
58+
snapshot
59+
}
60+
threats.forEach { sink.success(it.value) }
61+
}
62+
63+
private fun flushMalwareCache(sink: MethodCallHandler.MethodSink) {
64+
val malware = synchronized(malwareCache) {
65+
val snapshot = malwareCache.toMutableList()
66+
malwareCache.clear()
67+
snapshot
68+
}
69+
if (malware.isNotEmpty()) {
70+
sink.onMalwareDetected(malware)
71+
}
72+
}
73+
}

android/src/main/kotlin/com/aheaditec/freerasp/generated/RaspExecutionState.kt

Lines changed: 0 additions & 53 deletions
This file was deleted.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package com.aheaditec.freerasp.handlers
2+
3+
import io.flutter.Log
4+
import io.flutter.plugin.common.BinaryMessenger
5+
import io.flutter.plugin.common.EventChannel
6+
7+
/**
8+
* A stream handler that creates and manages an [EventChannel] for freeRASP execution state events.
9+
*/
10+
internal class ExecutionStateStreamHandler : EventChannel.StreamHandler {
11+
12+
private var eventChannel: EventChannel? = null
13+
14+
companion object {
15+
private const val CHANNEL_NAME: String = "talsec.app/freerasp/execution_state"
16+
}
17+
18+
internal fun createEventChannel(messenger: BinaryMessenger) {
19+
if (eventChannel != null) {
20+
Log.i("ExecStateStreamHandler", "Tried to create channel without disposing old one.")
21+
destroyEventChannel()
22+
}
23+
eventChannel = EventChannel(messenger, CHANNEL_NAME).also {
24+
it.setStreamHandler(this)
25+
}
26+
}
27+
28+
internal fun destroyEventChannel() {
29+
eventChannel?.setStreamHandler(null)
30+
eventChannel = null
31+
TalsecThreatHandler.detachExecutionStateSink()
32+
}
33+
34+
override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
35+
events?.let {
36+
TalsecThreatHandler.attachExecutionStateSink(it)
37+
}
38+
}
39+
40+
override fun onCancel(arguments: Any?) {
41+
TalsecThreatHandler.detachExecutionStateSink()
42+
}
43+
}

0 commit comments

Comments
 (0)