Skip to content
Merged
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
38 changes: 38 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,44 @@ 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).

## [3.2.0] - 2026-08-07

- Android SDK version: 19.2.1
- iOS SDK version: 7.1.2

### Capacitor

#### Added

- `bootloader` threat callback, reporting 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 (`https://europe-west3-maven.pkg.dev/talsec-artifact-repository/common`)

#### Fixed

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

#### Changed

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

### iOS

#### Added

- Improved jailbreak detection

## [3.1.0] - 2026-07-27

- Android SDK version: 18.3.0
Expand Down
4 changes: 2 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ let package = Package(
targets: [
.binaryTarget(
name: "TalsecRuntime",
url: "https://storage.googleapis.com/talsec-artifact-repository/freerasp/ios/capacitor/7.1.1/TalsecRuntime.xcframework.zip",
checksum: "fced1ed1c8ce3eec19ca66f290e65a3a1dab0ed2d2893ca82ced76e6e890b08b"
url: "https://storage.googleapis.com/talsec-artifact-repository/freerasp/ios/capacitor/7.1.2/TalsecRuntime.xcframework.zip",
checksum: "db6c4236bb9619b9c19ccada6b6787c137da2d72cc2e52c73537404c080024b3"
),
.target(
name: "CapacitorFreerasp",
Expand Down
4 changes: 2 additions & 2 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ repositories {
rootProject.allprojects {
repositories {
maven{url "https://europe-west3-maven.pkg.dev/talsec-artifact-repository/freerasp"}
maven{url "https://jitpack.io"}
maven{url "https://europe-west3-maven.pkg.dev/talsec-artifact-repository/common"}
}
}

Expand All @@ -76,5 +76,5 @@ dependencies {
androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"

implementation 'com.aheaditec.talsec.security:TalsecSecurity-Community-Capacitor:18.3.0'
implementation 'com.aheaditec.talsec.security:TalsecSecurity-Community-Capacitor:19.2.1'
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ import android.os.Build
import android.os.Handler
import android.os.HandlerThread
import android.os.Looper
import app.talsec.rasp.security.api.SuspiciousAppInfo
import app.talsec.rasp.security.api.Talsec
import app.talsec.rasp.security.api.TalsecConfig
import com.aheaditec.freerasp.dispatchers.ExecutionStateDispatcher
import com.aheaditec.freerasp.dispatchers.ThreatDispatcher
import com.aheaditec.freerasp.utils.Utils
import com.aheaditec.freerasp.utils.getArraySafe
import com.aheaditec.freerasp.utils.toEncodedJSArray
import com.aheaditec.freerasp.utils.toSuspiciousAppDetectionConfig
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.freerasp.events.BaseRaspEvent
import com.aheaditec.freerasp.events.RaspExecutionStateEvent
import com.aheaditec.freerasp.events.ThreatEvent
Expand Down
52 changes: 28 additions & 24 deletions android/src/main/java/com/aheaditec/freerasp/PluginThreatHandler.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.aheaditec.freerasp

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.aheaditec.freerasp.dispatchers.ExecutionStateDispatcher
import com.aheaditec.freerasp.dispatchers.ThreatDispatcher
import com.aheaditec.freerasp.events.RaspExecutionStateEvent
Expand All @@ -13,90 +13,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(suspiciousAppInfos: MutableList<SuspiciousAppInfo>) {
ThreatDispatcher.dispatchMalware(suspiciousAppInfos)
}

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 @@ -10,7 +10,7 @@ import android.util.Log
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 com.aheaditec.freerasp.events.ThreatEvent
import java.util.function.Consumer

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.aheaditec.freerasp.dispatchers

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

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

companion object {

Expand Down Expand Up @@ -64,7 +65,8 @@ internal sealed class ThreatEvent(override val value: Int) : BaseRaspEvent {
TimeSpoofing,
LocationSpoofing,
UnsecureWifi,
Automation
Automation,
Bootloader
).map { it.value }
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.aheaditec.freerasp.interfaces

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

internal interface PluginThreatListener {
Expand Down
10 changes: 5 additions & 5 deletions android/src/main/java/com/aheaditec/freerasp/utils/Extensions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import android.content.Context
import android.content.pm.PackageInfo
import android.util.Base64
import android.util.Log
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.aheaditec.freerasp.models.CapPackageInfo
import com.aheaditec.freerasp.models.CapSuspiciousAppInfo
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 com.getcapacitor.JSArray
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
Expand Down
5 changes: 4 additions & 1 deletion dist/esm/api/listeners/threat.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading