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).

## [5.2.0] - 2026-08-05

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

### React Native

#### Added

- Added `bootloader` 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

## [5.1.1] - 2026-07-21

- 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 @@ -105,7 +105,7 @@ dependencies {
implementation "com.facebook.react:react-native:$react_native_version"
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1"
implementation "com.aheaditec.talsec.security:TalsecSecurity-Community-ReactNative:18.3.0"
implementation "com.aheaditec.talsec.security:TalsecSecurity-Community-ReactNative:19.2.1"
}

if (isNewArchitectureEnabled()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import android.os.Build
import android.os.Handler
import android.os.HandlerThread
import android.os.Looper
import com.aheaditec.talsec_security.security.api.ExternalIdResult
import com.aheaditec.talsec_security.security.api.SuspiciousAppInfo
import com.aheaditec.talsec_security.security.api.Talsec
import com.aheaditec.talsec_security.security.api.TalsecConfig
import com.aheaditec.talsec_security.security.api.TalsecMode
import app.talsec.rasp.security.api.ExternalIdResult
import app.talsec.rasp.security.api.SuspiciousAppInfo
import app.talsec.rasp.security.api.Talsec
import app.talsec.rasp.security.api.TalsecConfig
import app.talsec.rasp.security.api.TalsecMode
import com.facebook.react.bridge.Arguments
import com.facebook.react.bridge.LifecycleEventListener
import com.facebook.react.bridge.Promise
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.freeraspreactnative

import android.content.Context
import com.aheaditec.talsec_security.security.api.SuspiciousAppInfo
import com.aheaditec.talsec_security.security.api.ThreatListener
import app.talsec.rasp.security.api.SuspiciousAppInfo
import app.talsec.rasp.security.api.ThreatListener
import com.freeraspreactnative.dispatchers.ExecutionStateDispatcher
import com.freeraspreactnative.dispatchers.ThreatDispatcher
import com.freeraspreactnative.events.RaspExecutionStateEvent
Expand All @@ -12,90 +12,94 @@ internal object PluginThreatHandler {

private val threatDetected = object : ThreatListener.ThreatDetected() {

override fun onRootDetected() {
override fun onPrivilegedAccess() {
ThreatDispatcher.dispatchThreat(ThreatEvent.PrivilegedAccess)
}

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

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

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

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

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

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

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

override fun onMalwareDetected(suspiciousAppInfos: MutableList<SuspiciousAppInfo>) {
ThreatDispatcher.dispatchMalware(suspiciousAppInfos ?: mutableListOf())
override fun onMalware(packageInfo: List<SuspiciousAppInfo>) {
ThreatDispatcher.dispatchMalware(packageInfo.toMutableList())
}

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

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

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

override fun onUnsecureWifiDetected() {
override fun onUnsecureWifi() {
ThreatDispatcher.dispatchThreat(ThreatEvent.UnsecureWifi)
}

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

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

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

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

private val deviceState = object : ThreatListener.DeviceState() {

override fun onUnlockedDeviceDetected() {
override fun onPasscode() {
ThreatDispatcher.dispatchThreat(ThreatEvent.Passcode)
}

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

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

override fun onADBEnabledDetected() {
override fun onAdbEnabled() {
ThreatDispatcher.dispatchThreat(ThreatEvent.ADBEnabled)
}

override fun onSystemVPNDetected() {
override fun onSystemVpn() {
ThreatDispatcher.dispatchThreat(ThreatEvent.SystemVPN)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import android.view.WindowManager.SCREEN_RECORDING_STATE_VISIBLE
import androidx.annotation.RequiresApi
import androidx.core.content.ContextCompat

import com.aheaditec.talsec_security.security.api.Talsec
import app.talsec.rasp.security.api.Talsec
import java.util.function.Consumer

@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.freeraspreactnative.dispatchers

import com.aheaditec.talsec_security.security.api.SuspiciousAppInfo
import app.talsec.rasp.security.api.SuspiciousAppInfo
import com.freeraspreactnative.events.ThreatEvent
import com.freeraspreactnative.interfaces.PluginThreatListener

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ internal sealed class ThreatEvent(override val value: Int) : BaseRaspEvent {
data object LocationSpoofing : ThreatEvent(RandomGenerator.next())
data object UnsecureWifi : ThreatEvent(RandomGenerator.next())
data object Automation : ThreatEvent(RandomGenerator.next())
data object Bootloader : ThreatEvent(RandomGenerator.next())

companion object {
internal val CHANNEL_NAME = RandomGenerator.next().toString()
Expand Down Expand Up @@ -61,7 +62,8 @@ internal sealed class ThreatEvent(override val value: Int) : BaseRaspEvent {
TimeSpoofing,
LocationSpoofing,
UnsecureWifi,
Automation
Automation,
Bootloader
).map { it.value }
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.freeraspreactnative.interfaces

import com.aheaditec.talsec_security.security.api.SuspiciousAppInfo
import app.talsec.rasp.security.api.SuspiciousAppInfo
import com.freeraspreactnative.events.ThreatEvent

internal interface PluginThreatListener {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ package com.freeraspreactnative.utils
import android.content.pm.PackageInfo
import android.util.Base64
import android.util.Log
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.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 com.facebook.react.bridge.Arguments
import com.facebook.react.bridge.ReactContext
import com.facebook.react.bridge.ReadableArray
Expand Down
10 changes: 10 additions & 0 deletions example/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,16 @@ const App = () => {
)
);
},
// Android only
bootloader: () => {
setAppChecks((currentState) =>
currentState.map((threat) =>
threat.name === 'Bootloader'
? { ...threat, status: 'nok' }
: threat
)
);
},
};

const raspExecutionStateActions = {
Expand Down
1 change: 1 addition & 0 deletions example/src/checks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@ export const androidChecks = [
{ name: 'Location Spoofing', status: 'ok' },
{ name: 'Unsecure Wifi', status: 'ok' },
{ name: 'Automation', status: 'ok' },
{ name: 'Bootloader', status: 'ok' },
];
10 changes: 5 additions & 5 deletions ios/TalsecRuntime.xcframework/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,32 @@
<key>BinaryPath</key>
<string>TalsecRuntime.framework/TalsecRuntime</string>
<key>LibraryIdentifier</key>
<string>ios-arm64</string>
<string>ios-arm64_x86_64-simulator</string>
<key>LibraryPath</key>
<string>TalsecRuntime.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
<string>x86_64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict>
<dict>
<key>BinaryPath</key>
<string>TalsecRuntime.framework/TalsecRuntime</string>
<key>LibraryIdentifier</key>
<string>ios-arm64_x86_64-simulator</string>
<string>ios-arm64</string>
<key>LibraryPath</key>
<string>TalsecRuntime.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
<string>x86_64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict>
</array>
<key>CFBundlePackageType</key>
Expand Down
Binary file modified ios/TalsecRuntime.xcframework/_CodeSignature/CodeDirectory
Binary file not shown.
Loading