Skip to content

Commit 51d119f

Browse files
martinzigraitompsotacursoragent
authored
release: freeRASP 5.0.0 (#149)
* feat: bump Android SDK to 18.3.0 * feat!: rename reason to reasons in SuspiciousAppInfo * feat!: deprecate old malware config fields * feat: add SuspiciousAppDetectionConfig to API * refactor: extract SuspiciousAppDetectionConfig parsing to utils * chore: update changelog for 4.6.0 * refactor: align toMalwareScanScope to operate on scope object directly * fix: add TalsecConfig type annotation to example config * fix: use positional arguments for non-Kotlin SDK constructors * refactor: simplify enum parsing and map reading in Extensions * fix: use emptyList() as default trustedInstallSources in MalwareScanScope * refactor: tighten SuspiciousAppDetectionConfig parsing * feat!: remove deprecated MalwareConfig API * chore: bump to 5.0.0 * docs: drop stale MalwareConfig deprecation notes from 4.6.0 * docs: merge unreleased 4.6.0 changelog into 5.0.0 * refactor: rename MalwareScanScope to ScanScope and extract config helpers * fix ci * docs: update changelog * refactor: rename normalizeConfig to withDefaults * refactor: rename ScanScope.scanScope field to scopeType Rename the `scanScope: ScopeType` field inside the `ScanScope` type to `scopeType` so the field name matches its type name. Update the JSON key, default config, example app, and Kotlin native bridge accordingly. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Tomas Psota <72520867+tompsota@users.noreply.github.com> Co-authored-by: Tomas Psota <to.psota@gmail.com> Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent afaf39e commit 51d119f

12 files changed

Lines changed: 149 additions & 30 deletions

File tree

CHANGELOG.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,42 @@ 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+
## [5.0.0] - 2026-05-15
9+
10+
- Android SDK version: 18.3.0
11+
- iOS SDK version: 6.14.4
12+
13+
### Breaking
14+
15+
- `SuspiciousAppInfo.reason` (String) renamed to `reasons` (string[])
16+
- Value `"blacklist"` in `reasons` renamed to `"blocklist"`
17+
- Removed `MalwareConfig` and `AndroidConfig.malwareConfig`
18+
19+
### React Native
20+
21+
#### Removed
22+
23+
- `TalsecMalwareConfig` type and `TalsecAndroidConfig.malwareConfig` field
24+
25+
### Android
26+
27+
#### Added
28+
29+
- New API class `SuspiciousAppDetectionConfig` that can be used to configure malware detection
30+
- New API for malware detection configuration in `TalsecConfig`, see `TalsecConfig.Builder#suspiciousAppDetection`
31+
32+
#### Fixed
33+
34+
- Fixed `VerifyError` caused by `JaCoCo` bytecode instrumentation
35+
- Fixed a potential cause of crash in the multi-instance detector
36+
- Fixed Java interoperability of `ScreenProtector` methods
37+
- Fixed Kotlin classpath conflicts in SDK dependency resolution (Kotlin 2.0.0)
38+
39+
#### Changed
40+
41+
- Fine-tuned location spoofing detection
42+
- Modified malware incident log structure for better aggregation
43+
844
## [4.5.2] - 2026-03-24
945

1046
- Android SDK version: 18.0.4

android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ dependencies {
105105
implementation "com.facebook.react:react-native:$react_native_version"
106106
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
107107
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1"
108-
implementation "com.aheaditec.talsec.security:TalsecSecurity-Community-ReactNative:18.0.4"
108+
implementation "com.aheaditec.talsec.security:TalsecSecurity-Community-ReactNative:18.3.0"
109109
}
110110

111111
if (isNewArchitectureEnabled()) {

android/src/main/java/com/freeraspreactnative/FreeraspReactNativeModule.kt

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import com.freeraspreactnative.utils.getMapThrowing
3333
import com.freeraspreactnative.utils.getNestedArraySafe
3434
import com.freeraspreactnative.utils.getStringThrowing
3535
import com.freeraspreactnative.utils.toEncodedWritableArray
36+
import com.freeraspreactnative.utils.toSuspiciousAppDetectionConfig
3637

3738
class FreeraspReactNativeModule(private val reactContext: ReactApplicationContext) :
3839
ReactContextBaseJavaModule(reactContext) {
@@ -298,12 +299,9 @@ class FreeraspReactNativeModule(private val reactContext: ReactApplicationContex
298299
.killOnBypass(config.getBooleanSafe("killOnBypass", false))
299300
.supportedAlternativeStores(androidConfig.getArraySafe("supportedAlternativeStores"))
300301

301-
if (androidConfig.hasKey("malwareConfig")) {
302-
val malwareConfig = androidConfig.getMapThrowing("malwareConfig")
303-
talsecBuilder.whitelistedInstallationSources(malwareConfig.getArraySafe("whitelistedInstallationSources"))
304-
talsecBuilder.blacklistedHashes(malwareConfig.getArraySafe("blacklistedHashes"))
305-
talsecBuilder.blacklistedPackageNames(malwareConfig.getArraySafe("blacklistedPackageNames"))
306-
talsecBuilder.suspiciousPermissions(malwareConfig.getNestedArraySafe("suspiciousPermissions"))
302+
if (androidConfig.hasKey("suspiciousAppDetectionConfig")) {
303+
val suspiciousAppConfig = androidConfig.getMapThrowing("suspiciousAppDetectionConfig")
304+
talsecBuilder.suspiciousAppDetection(suspiciousAppConfig.toSuspiciousAppDetectionConfig())
307305
}
308306

309307
return talsecBuilder.build()

android/src/main/java/com/freeraspreactnative/models/RNSuspiciousAppInfo.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import kotlinx.serialization.Serializable
99
@Serializable
1010
data class RNSuspiciousAppInfo(
1111
val packageInfo: RNPackageInfo,
12-
val reason: String,
12+
val reasons: Set<String>,
1313
val permissions: Set<String>?
1414
)
1515

android/src/main/java/com/freeraspreactnative/utils/Extensions.kt

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ package com.freeraspreactnative.utils
33
import android.content.pm.PackageInfo
44
import android.util.Base64
55
import android.util.Log
6+
import com.aheaditec.talsec_security.security.api.MalwareScanScope
7+
import com.aheaditec.talsec_security.security.api.ReasonMode
8+
import com.aheaditec.talsec_security.security.api.ScopeType
9+
import com.aheaditec.talsec_security.security.api.SuspiciousAppDetectionConfig
610
import com.aheaditec.talsec_security.security.api.SuspiciousAppInfo
711
import com.facebook.react.bridge.Arguments
812
import com.facebook.react.bridge.ReactContext
@@ -32,7 +36,7 @@ internal fun ReadableMap.getBooleanSafe(key: String, defaultValue: Boolean = tru
3236
return defaultValue
3337
}
3438

35-
private inline fun <reified T> ReadableArray.toPrimitiveArray(): Array<T> {
39+
internal inline fun <reified T> ReadableArray.toPrimitiveArray(): Array<T> {
3640
val output = mutableListOf<T>()
3741

3842
for (i in 0 until this.size()) {
@@ -74,7 +78,7 @@ internal fun ReadableMap.getNestedArraySafe(key: String): Array<Array<String>> {
7478
internal fun SuspiciousAppInfo.toRNSuspiciousAppInfo(context: ReactContext): RNSuspiciousAppInfo {
7579
return RNSuspiciousAppInfo(
7680
packageInfo = this.packageInfo.toRNPackageInfo(context),
77-
reason = this.reason,
81+
reasons = this.reasons,
7882
permissions = this.permissions
7983
)
8084
}
@@ -92,6 +96,22 @@ internal fun PackageInfo.toRNPackageInfo(context: ReactContext): RNPackageInfo {
9296
)
9397
}
9498

99+
internal fun ReadableMap.toScanScope(): MalwareScanScope {
100+
val scopeType = ScopeType.valueOf(getStringThrowing("scopeType"))
101+
val trustedInstallSources = getArraySafe("trustedInstallSources").toList().ifEmpty { null }
102+
return MalwareScanScope(scopeType, trustedInstallSources)
103+
}
104+
105+
internal fun ReadableMap.toSuspiciousAppDetectionConfig(): SuspiciousAppDetectionConfig {
106+
val packageNames = getArraySafe("packageNames").toSet().ifEmpty { null }
107+
val hashes = getArraySafe("hashes").toSet().ifEmpty { null }
108+
val requestedPermissions = getNestedArraySafe("requestedPermissions").map { it.toSet() }.toSet().ifEmpty { null }
109+
val grantedPermissions = getNestedArraySafe("grantedPermissions").map { it.toSet() }.toSet().ifEmpty { null }
110+
val scanScope = getMapThrowing("scanScope").toScanScope()
111+
val reasonMode = ReasonMode.valueOf(getStringThrowing("reasonMode"))
112+
return SuspiciousAppDetectionConfig(packageNames, hashes, requestedPermissions, grantedPermissions, scanScope, reasonMode)
113+
}
114+
95115
/**
96116
* Convert the Talsec's SuspiciousAppInfo to base64-encoded json array,
97117
* which can be then sent to React Native

example/src/App.tsx

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
addToWhitelist,
66
useFreeRasp,
77
type SuspiciousAppInfo,
8+
type TalsecConfig,
89
} from 'freerasp-react-native';
910
import { DemoApp } from './DemoApp';
1011
import { commonChecks, iosChecks, androidChecks } from './checks';
@@ -29,23 +30,28 @@ const App = () => {
2930
})();
3031
}, []);
3132

32-
const config = {
33+
const config: TalsecConfig = {
3334
androidConfig: {
3435
packageName: 'com.freeraspreactnativeexample',
3536
certificateHashes: ['AKoRuyLMM91E7lX/Zqp3u4jMmd0A7hH/Iqozu0TMVd0='],
3637
// supportedAlternativeStores: ['storeOne', 'storeTwo'],
37-
malwareConfig: {
38-
blacklistedHashes: ['FgvSehLMM91E7lX/Zqp3u4jMmd0A7hH/Iqozu0TMVd0u'],
39-
blacklistedPackageNames: ['com.freeraspreactnativeexample'],
40-
suspiciousPermissions: [
38+
suspiciousAppDetectionConfig: {
39+
packageNames: ['com.freeraspreactnativeexample'],
40+
hashes: ['FgvSehLMM91E7lX/Zqp3u4jMmd0A7hH/Iqozu0TMVd0u'],
41+
requestedPermissions: [
4142
[
4243
'android.permission.INTERNET',
4344
'android.permission.ACCESS_COARSE_LOCATION',
4445
],
4546
['android.permission.BLUETOOTH'],
4647
['android.permission.BATTERY_STATS'],
4748
],
48-
whitelistedInstallationSources: ['com.apkpure.aegon'],
49+
grantedPermissions: [['android.permission.ACCESS_FINE_LOCATION']],
50+
scanScope: {
51+
scopeType: 'SIDELOADED_AND_SYSTEM_EXCLUDE_OEM',
52+
trustedInstallSources: ['com.apkpure.aegon'],
53+
},
54+
reasonMode: 'HIGHEST_CONFIDENCE',
4955
},
5056
},
5157
iosConfig: {

example/src/MalwareItem.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,8 @@ export const MalwareItem: React.FC<{ app: SuspiciousAppInfo }> = ({ app }) => {
9090
<Text style={styles.listItem}>
9191
{app.packageInfo.installerStore ?? 'Not specified'}
9292
</Text>
93-
<Text style={styles.listItemTitle}>Detection reason:</Text>
94-
<Text style={styles.listItem}>{app.reason}</Text>
93+
<Text style={styles.listItemTitle}>Detection reasons:</Text>
94+
<Text style={styles.listItem}>{app.reasons.join(', ')}</Text>
9595
<Text style={styles.listItemTitle}>Granted permissions:</Text>
9696
<Text style={styles.listItem}>
9797
{app.permissions?.join(', ') ?? 'Not specified'}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "freerasp-react-native",
3-
"version": "4.5.2",
3+
"version": "5.0.0",
44
"description": "React Native plugin for improving app security and threat monitoring on Android and iOS mobile devices.",
55
"main": "lib/commonjs/index",
66
"module": "lib/module/index",

src/api/methods/native.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { Platform } from 'react-native';
22
import { FreeraspReactNative } from '../nativeModules';
33
import type { TalsecConfig } from '../../types/types';
4+
import { withDefaults } from '../../utils/config';
45

56
export const talsecStart = async (options: TalsecConfig): Promise<string> => {
6-
return FreeraspReactNative.talsecStart(options);
7+
return FreeraspReactNative.talsecStart(withDefaults(options));
78
};
89

910
export const addToWhitelist = async (packageName: string): Promise<boolean> => {

src/types/types.ts

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,28 +6,44 @@ export type TalsecConfig = {
66
killOnBypass?: boolean;
77
};
88

9+
export type ScopeType =
10+
| 'SIDELOADED_ONLY'
11+
| 'SIDELOADED_AND_SYSTEM_EXCLUDE_OEM'
12+
| 'SIDELOADED_AND_OEM'
13+
| 'SIDELOADED_AND_SYSTEM_AND_OEM'
14+
| 'ALL';
15+
16+
export type ReasonMode = 'ALL' | 'HIGHEST_CONFIDENCE';
17+
18+
export type ScanScope = {
19+
scopeType: ScopeType;
20+
trustedInstallSources?: string[];
21+
};
22+
23+
export type SuspiciousAppDetectionConfig = {
24+
packageNames?: string[];
25+
hashes?: string[];
26+
requestedPermissions?: string[][];
27+
grantedPermissions?: string[][];
28+
scanScope: ScanScope;
29+
reasonMode: ReasonMode;
30+
};
31+
932
export type TalsecAndroidConfig = {
1033
packageName: string;
1134
certificateHashes: string[];
1235
supportedAlternativeStores?: string[];
13-
malwareConfig?: TalsecMalwareConfig;
36+
suspiciousAppDetectionConfig?: SuspiciousAppDetectionConfig;
1437
};
1538

1639
export type TalsecIosConfig = {
1740
appBundleId: string;
1841
appTeamId: string;
1942
};
2043

21-
export type TalsecMalwareConfig = {
22-
blacklistedHashes?: string[];
23-
blacklistedPackageNames?: string[];
24-
suspiciousPermissions?: string[][];
25-
whitelistedInstallationSources?: string[];
26-
};
27-
2844
export type SuspiciousAppInfo = {
2945
packageInfo: PackageInfo;
30-
reason: string;
46+
reasons: string[];
3147
permissions?: string[];
3248
};
3349

0 commit comments

Comments
 (0)