Skip to content

Commit 572b864

Browse files
authored
release: freeRASP 7.5.0 (#196)
* add implementation * feat: update ios sdk * chore: update changelog
1 parent 73e4347 commit 572b864

46 files changed

Lines changed: 1762 additions & 2076 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,55 @@ 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-
## Unreleased
8+
## [7.5.0] - 2026-03-02
9+
10+
- Android SDK version: 18.0.4
11+
- iOS SDK version: 6.14.1
912

1013
### Flutter
1114

1215
#### Changed
1316

1417
- Updated the internal handling of ExternalIdResult on Android (for `storeExternalId()` method)
1518

19+
### Android
20+
21+
#### Added
22+
23+
- Added support for `KernelSU` to the existing root detection capabilities
24+
- Added support for `HMA` to the existing root detection capabilities
25+
- Added new malware detection capabilities
26+
- Added `onAutomationDetected()` callback to `ThreatDetected` interface
27+
- We are introducing a new capability, detecting whether the device is being automated using tools like Appium
28+
- Added value restrictions to `externalId`
29+
- Method `storeExternalId()` now returns `ExternalIdResult`, which indicates `Success` or `Error` when `externalId` violates restrictions
30+
31+
#### Fixed
32+
33+
- Fixed exception handling for the KeyStore `getEntry` operation
34+
- Fixed issue in `ScreenProtector` concerning the `onScreenRecordingDetected` invocations
35+
- Merged internal shared libraries into a single one, reducing the final APK size
36+
- Fixed bug related to key storing in keystore type detection (hw-backed keystore check)
37+
- Fixed manifest queries merge
38+
39+
#### Changed
40+
41+
- Removed unused library `tmlib`
42+
- Refactoring of signature verification code
43+
- Updated compile and target API to 36
44+
- Improved root detection capabilities
45+
- Detection of wireless ADB added to ADB detections
46+
47+
### iOS
48+
49+
#### Added
50+
51+
- Added time spoofing detection, detecting an inaccurate device clock. It is a new threat `timeSpoofing`.
52+
53+
#### Changed
54+
55+
- Improved jailbreak detection methods.
56+
1657
## [7.4.0] - 2026-02-10
1758
- Android SDK version: 18.0.2
1859
- iOS SDK version: 6.13.0

android/build.gradle

Lines changed: 1 addition & 1 deletion
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 = '18.0.2'
6+
ext.talsec_version = '18.0.4'
77
repositories {
88
google()
99
mavenCentral()

android/src/main/kotlin/com/aheaditec/freerasp/dispatchers/ExecutionStateDispatcher.kt

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,34 +5,46 @@ import io.flutter.plugin.common.EventChannel.EventSink
55

66
internal class ExecutionStateDispatcher {
77
private val eventCache = mutableSetOf<RaspExecutionStateEvent>()
8+
private var isAppInForeground = false
89

910
var eventSink: EventSink? = null
1011
set(value) {
1112
field = value
1213
if (value != null) {
13-
flushCache(value)
14+
isAppInForeground = true
15+
flushCache()
1416
}
1517
}
1618

19+
fun onResume() {
20+
isAppInForeground = true
21+
if (eventSink != null) {
22+
flushCache()
23+
}
24+
}
25+
26+
fun onPause() {
27+
isAppInForeground = false
28+
}
29+
1730
fun dispatch(event: RaspExecutionStateEvent) {
18-
val sink = synchronized(eventCache) {
19-
val currentSink = eventSink
20-
if (currentSink != null) {
21-
currentSink
22-
} else {
31+
// We can only use the sink if the app is in foreground and the sink is not null
32+
// We don't need to check for isListenerRegistered because it is equivalent to eventSink != null
33+
if (isAppInForeground && eventSink != null) {
34+
eventSink?.success(event.value)
35+
} else {
36+
synchronized(eventCache) {
2337
eventCache.add(event)
24-
null
2538
}
2639
}
27-
sink?.success(event.value)
2840
}
2941

30-
private fun flushCache(sink: EventSink) {
42+
private fun flushCache() {
3143
val events = synchronized(eventCache) {
3244
val snapshot = eventCache.toSet()
3345
eventCache.clear()
3446
snapshot
3547
}
36-
events.forEach { sink.success(it.value) }
48+
events.forEach { eventSink?.success(it.value) }
3749
}
3850
}

android/src/main/kotlin/com/aheaditec/freerasp/dispatchers/ThreatDispatcher.kt

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,66 +8,77 @@ import io.flutter.plugin.common.EventChannel.EventSink
88
internal class ThreatDispatcher {
99
private val threatCache = mutableSetOf<Threat>()
1010
private val malwareCache = mutableListOf<SuspiciousAppInfo>()
11+
private var isAppInForeground = false
1112

1213
var eventSink: EventSink? = null
1314
set(value) {
1415
field = value
1516
if (value != null) {
16-
flushThreatCache(value)
17+
isAppInForeground = true
18+
flushThreatCache()
1719
}
1820
}
1921

2022
var methodSink: MethodCallHandler.MethodSink? = null
2123
set(value) {
2224
field = value
2325
if (value != null) {
24-
flushMalwareCache(value)
26+
isAppInForeground = true
27+
flushMalwareCache()
2528
}
2629
}
2730

31+
fun onResume() {
32+
isAppInForeground = true
33+
if (eventSink != null) {
34+
flushThreatCache()
35+
}
36+
if (methodSink != null) {
37+
flushMalwareCache()
38+
}
39+
}
40+
41+
fun onPause() {
42+
isAppInForeground = false
43+
}
44+
2845
fun dispatchThreat(threat: Threat) {
29-
val sink = synchronized(threatCache) {
30-
val currentSink = eventSink
31-
if (currentSink != null) {
32-
currentSink
33-
} else {
46+
if (isAppInForeground && eventSink != null) {
47+
eventSink?.success(threat.value)
48+
} else {
49+
synchronized(threatCache) {
3450
threatCache.add(threat)
35-
null
3651
}
3752
}
38-
sink?.success(threat.value)
3953
}
4054

4155
fun dispatchMalware(apps: List<SuspiciousAppInfo>) {
42-
val sink = synchronized(malwareCache) {
43-
val currentSink = methodSink
44-
if (currentSink != null) {
45-
currentSink
46-
} else {
56+
if (isAppInForeground && methodSink != null) {
57+
methodSink?.onMalwareDetected(apps)
58+
} else {
59+
synchronized(malwareCache) {
4760
malwareCache.addAll(apps)
48-
null
4961
}
5062
}
51-
sink?.onMalwareDetected(apps)
5263
}
5364

54-
private fun flushThreatCache(sink: EventSink) {
65+
private fun flushThreatCache() {
5566
val threats = synchronized(threatCache) {
5667
val snapshot = threatCache.toSet()
5768
threatCache.clear()
5869
snapshot
5970
}
60-
threats.forEach { sink.success(it.value) }
71+
threats.forEach { eventSink?.success(it.value) }
6172
}
6273

63-
private fun flushMalwareCache(sink: MethodCallHandler.MethodSink) {
74+
private fun flushMalwareCache() {
6475
val malware = synchronized(malwareCache) {
6576
val snapshot = malwareCache.toMutableList()
6677
malwareCache.clear()
6778
snapshot
6879
}
6980
if (malware.isNotEmpty()) {
70-
sink.onMalwareDetected(malware)
81+
methodSink?.onMalwareDetected(malware)
7182
}
7283
}
7384
}

android/src/main/kotlin/com/aheaditec/freerasp/handlers/TalsecThreatHandler.kt

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,8 @@ internal object TalsecThreatHandler {
8888
* [EventSink] is not destroyed but also is not able to send events.
8989
*/
9090
internal fun suspendListener() {
91-
savedThreatEventSink = PluginThreatHandler.threatDispatcher.eventSink
92-
PluginThreatHandler.threatDispatcher.eventSink = null
93-
94-
savedExecutionStateSink = PluginThreatHandler.executionStateDispatcher.eventSink
95-
PluginThreatHandler.executionStateDispatcher.eventSink = null
91+
PluginThreatHandler.threatDispatcher.onPause()
92+
PluginThreatHandler.executionStateDispatcher.onPause()
9693
}
9794

9895
/**
@@ -107,20 +104,10 @@ internal object TalsecThreatHandler {
107104
* also is not able to send events.
108105
*/
109106
internal fun resumeListener() {
110-
if (savedThreatEventSink != null) {
111-
PluginThreatHandler.threatDispatcher.eventSink = savedThreatEventSink
112-
savedThreatEventSink = null
113-
}
114-
if (savedExecutionStateSink != null) {
115-
PluginThreatHandler.executionStateDispatcher.eventSink = savedExecutionStateSink
116-
savedExecutionStateSink = null
117-
}
107+
PluginThreatHandler.threatDispatcher.onResume()
108+
PluginThreatHandler.executionStateDispatcher.onResume()
118109
}
119110

120-
private var savedThreatEventSink: EventSink? = null
121-
private var savedExecutionStateSink: EventSink? = null
122-
123-
124111
/**
125112
* Called when a new listener subscribes to the event channel. Sends any previously detected
126113
* threats to the new listener.
@@ -136,7 +123,6 @@ internal object TalsecThreatHandler {
136123
*/
137124
internal fun detachEventSink() {
138125
PluginThreatHandler.threatDispatcher.eventSink = null
139-
savedThreatEventSink = null
140126
}
141127

142128
internal fun attachExecutionStateSink(eventSink: EventSink) {
@@ -145,7 +131,6 @@ internal object TalsecThreatHandler {
145131

146132
internal fun detachExecutionStateSink() {
147133
PluginThreatHandler.executionStateDispatcher.eventSink = null
148-
savedExecutionStateSink = null
149134
}
150135

151136
internal fun attachMethodSink(sink: MethodCallHandler.MethodSink) {

example/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
.buildlog/
99
.history
1010
.svn/
11+
**/.cxx/
1112

1213
# IntelliJ related
1314
*.iml

ios/Classes/TalsecHandlers.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ private let unofficialStoreValue = 629780916
1414
private let systemVPNValue = 659382561
1515
private let screenshotValue = 705651459
1616
private let screenRecordingValue = 64690214
17+
private let timeSpoofingValue = 189105221
1718

1819
/// Extension with submits events to plugin
1920
extension SecurityThreatCenter: SecurityThreatHandler, TalsecRuntime.RaspExecutionState {
@@ -62,6 +63,8 @@ extension SecurityThreat {
6263
return screenshotValue
6364
case .screenRecording:
6465
return screenRecordingValue
66+
case .timeSpoofing:
67+
return timeSpoofingValue
6568
@unknown default:
6669
return unknownValue
6770
}
48 Bytes
Binary file not shown.
-205 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)