capacitor-freerasp 2.2.2 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/CHANGELOG.md +105 -0
  2. package/CapacitorFreerasp.podspec +5 -1
  3. package/README.md +8 -8
  4. package/android/build.gradle +3 -3
  5. package/android/src/main/java/com/aheaditec/freerasp/FreeraspPlugin.kt +106 -33
  6. package/android/src/main/java/com/aheaditec/freerasp/PluginThreatHandler.kt +121 -0
  7. package/android/src/main/java/com/aheaditec/freerasp/ScreenProtector.kt +24 -2
  8. package/android/src/main/java/com/aheaditec/freerasp/dispatchers/ExecutionStateDispatcher.kt +38 -0
  9. package/android/src/main/java/com/aheaditec/freerasp/dispatchers/ThreatDispatcher.kt +62 -0
  10. package/android/src/main/java/com/aheaditec/freerasp/events/BaseRaspEvent.kt +7 -0
  11. package/android/src/main/java/com/aheaditec/freerasp/events/RaspExecutionStateEvent.kt +22 -0
  12. package/android/src/main/java/com/aheaditec/freerasp/events/ThreatEvent.kt +71 -0
  13. package/android/src/main/java/com/aheaditec/freerasp/interfaces/PluginExecutionStateListener.kt +7 -0
  14. package/android/src/main/java/com/aheaditec/freerasp/interfaces/PluginThreatListener.kt +9 -0
  15. package/android/src/main/java/com/aheaditec/freerasp/models/CapSuspiciousAppInfo.kt +1 -0
  16. package/android/src/main/java/com/aheaditec/freerasp/utils/Extensions.kt +1 -0
  17. package/android/src/main/java/com/aheaditec/freerasp/utils/RandomGenerator.kt +24 -0
  18. package/android/src/main/java/com/aheaditec/freerasp/utils/Utils.kt +3 -5
  19. package/dist/esm/api/listeners/raspExecutionState.d.ts +3 -0
  20. package/dist/esm/api/listeners/raspExecutionState.js +40 -0
  21. package/dist/esm/api/listeners/raspExecutionState.js.map +1 -0
  22. package/dist/esm/api/listeners/threat.d.ts +3 -0
  23. package/dist/esm/api/listeners/threat.js +104 -0
  24. package/dist/esm/api/listeners/threat.js.map +1 -0
  25. package/dist/esm/api/methods/capacitor.d.ts +4 -0
  26. package/dist/esm/api/methods/capacitor.js +11 -0
  27. package/dist/esm/api/methods/capacitor.js.map +1 -0
  28. package/dist/esm/api/methods/native.d.ts +7 -0
  29. package/dist/esm/api/methods/native.js +36 -0
  30. package/dist/esm/api/methods/native.js.map +1 -0
  31. package/dist/esm/api/nativeModules.d.ts +2 -0
  32. package/dist/esm/api/nativeModules.js +3 -0
  33. package/dist/esm/api/nativeModules.js.map +1 -0
  34. package/dist/esm/channels/raspExecutionState.d.ts +3 -0
  35. package/dist/esm/channels/raspExecutionState.js +27 -0
  36. package/dist/esm/channels/raspExecutionState.js.map +1 -0
  37. package/dist/esm/channels/threat.d.ts +3 -0
  38. package/dist/esm/channels/threat.js +34 -0
  39. package/dist/esm/channels/threat.js.map +1 -0
  40. package/dist/esm/index.d.ts +7 -12
  41. package/dist/esm/index.js +7 -158
  42. package/dist/esm/index.js.map +1 -1
  43. package/dist/esm/models/raspExecutionState.d.ts +6 -0
  44. package/dist/esm/models/raspExecutionState.js +10 -0
  45. package/dist/esm/models/raspExecutionState.js.map +1 -0
  46. package/dist/esm/models/threat.d.ts +27 -0
  47. package/dist/esm/{definitions.js → models/threat.js} +9 -3
  48. package/dist/esm/models/threat.js.map +1 -0
  49. package/dist/esm/{definitions.d.ts → types/types.d.ts} +41 -44
  50. package/dist/esm/types/types.js +2 -0
  51. package/dist/esm/types/types.js.map +1 -0
  52. package/dist/esm/utils/malware.d.ts +3 -0
  53. package/dist/esm/utils/malware.js +22 -0
  54. package/dist/esm/utils/malware.js.map +1 -0
  55. package/dist/esm/utils/utils.d.ts +3 -0
  56. package/dist/esm/utils/utils.js +12 -0
  57. package/dist/esm/utils/utils.js.map +1 -0
  58. package/dist/plugin.cjs.js +197 -76
  59. package/dist/plugin.cjs.js.map +1 -1
  60. package/dist/plugin.js +197 -76
  61. package/dist/plugin.js.map +1 -1
  62. package/ios/Plugin/FreeraspPlugin.m +3 -0
  63. package/ios/Plugin/FreeraspPlugin.swift +36 -77
  64. package/ios/Plugin/Info.plist +1 -1
  65. package/ios/Plugin/TalsecRuntime.xcframework/_CodeSignature/CodeDirectory +0 -0
  66. package/ios/Plugin/TalsecRuntime.xcframework/_CodeSignature/CodeResources +100 -298
  67. package/ios/Plugin/TalsecRuntime.xcframework/_CodeSignature/CodeSignature +0 -0
  68. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/CurlWrapper.h +1 -1
  69. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/TalsecRuntime-Swift.h +7 -2
  70. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/curl.h +380 -281
  71. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/curlver.h +5 -6
  72. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/easy.h +4 -4
  73. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/header.h +1 -1
  74. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/mprintf.h +11 -4
  75. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/multi.h +62 -22
  76. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/options.h +2 -2
  77. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/system.h +76 -164
  78. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/typecheck-gcc.h +947 -0
  79. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/urlapi.h +5 -4
  80. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/websockets.h +17 -3
  81. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Info.plist +0 -0
  82. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios.abi.json +233 -528
  83. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios.private.swiftinterface +7 -3
  84. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios.swiftdoc +0 -0
  85. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios.swiftinterface +7 -3
  86. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/TalsecRuntime +0 -0
  87. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/CurlWrapper.h +1 -1
  88. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/TalsecRuntime-Swift.h +14 -4
  89. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/curl.h +380 -281
  90. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/curlver.h +5 -6
  91. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/easy.h +4 -4
  92. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/header.h +1 -1
  93. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/mprintf.h +11 -4
  94. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/multi.h +62 -22
  95. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/options.h +2 -2
  96. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/system.h +76 -164
  97. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/typecheck-gcc.h +947 -0
  98. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/urlapi.h +5 -4
  99. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/websockets.h +17 -3
  100. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Info.plist +0 -0
  101. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.abi.json +233 -528
  102. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface +7 -3
  103. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.swiftdoc +0 -0
  104. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.swiftinterface +7 -3
  105. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.abi.json +233 -528
  106. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface +7 -3
  107. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.swiftdoc +0 -0
  108. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.swiftinterface +7 -3
  109. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/TalsecRuntime +0 -0
  110. package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/_CodeSignature/CodeResources +56 -45
  111. package/ios/Plugin/dispatchers/ExecutionStateDispatcher.swift +35 -0
  112. package/ios/Plugin/dispatchers/ThreatDispatcher.swift +36 -0
  113. package/ios/Plugin/models/RaspExecutionStates.swift +15 -0
  114. package/ios/Plugin/models/SecurityThreat.swift +40 -0
  115. package/ios/Plugin/utils/EventIdentifiers.swift +17 -0
  116. package/ios/Plugin/utils/RandomGenerator.swift +23 -0
  117. package/ios/Plugin/utils/Utils.swift +32 -0
  118. package/package.json +15 -10
  119. package/android/src/main/java/com/aheaditec/freerasp/Threat.kt +0 -58
  120. package/android/src/main/java/com/aheaditec/freerasp/ThreatHandler.kt +0 -76
  121. package/dist/esm/definitions.js.map +0 -1
  122. package/dist/esm/utils.d.ts +0 -2
  123. package/dist/esm/utils.js +0 -8
  124. package/dist/esm/utils.js.map +0 -1
  125. package/ios/Plugin/TalsecRuntime.xcframework/_CodeSignature/CodeRequirements-1 +0 -0
package/CHANGELOG.md CHANGED
@@ -5,6 +5,111 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [2.4.0] - 2026-02-13
9
+
10
+ - Android SDK version: 18.0.2
11
+ - iOS SDK version: 6.13.0
12
+
13
+ ### Capacitor
14
+
15
+ #### Added
16
+
17
+ - Added cache for freeRASP callbacks when listener is not registered with the app
18
+ - Added API for `automation` callback into `ThreatEventActions` (Android only)
19
+
20
+ #### Fixed
21
+
22
+ - Prevent multiple registration of the freeRASP listeners on the native side
23
+
24
+ #### Changed
25
+
26
+ - Updated compile and target SDK versions to 36 on Android
27
+
28
+ ### Android
29
+
30
+ #### Added
31
+
32
+ - Added support for `KernelSU` to the existing root detection capabilities
33
+ - Added support for `HMA` to the existing root detection capabilities
34
+ - Added new malware detection capabilities
35
+ - Added `onAutomationDetected()` callback to `ThreatDetected` interface
36
+ - We are introducing a new capability, detecting whether the device is being automated using tools like Appium
37
+ - Added value restrictions to `externalId`
38
+ - Method `storeExternalId()` now returns `ExternalIdResult`, which indicates `Success` or `Error` when `externalId` violates restrictions
39
+
40
+ #### Fixed
41
+
42
+ - Fixed exception handling for the KeyStore `getEntry` operation
43
+ - Fixed issue in `ScreenProtector` concerning the `onScreenRecordingDetected` invocations
44
+ - Merged internal shared libraries into a single one, reducing the final APK size
45
+ - Fixed bug related to key storing in keystore type detection (hw-backed keystore check)
46
+ - Fixed manifest queries merge
47
+
48
+ #### Changed
49
+
50
+ - Removed unused library `tmlib`
51
+ - Refactoring of signature verification code
52
+ - Updated compile and target API to 36
53
+ - Improved root detection capabilities
54
+ - Detection of wireless ADB added to ADB detections
55
+
56
+ ## [2.3.0] - 2025-12-15
57
+
58
+ - Android SDK version: 17.0.1
59
+ - iOS SDK version: 6.13.0
60
+
61
+ ### Capacitor
62
+
63
+ #### Added
64
+
65
+ - Added `killOnBypass` to `TalsecConfig` that configures if the app should be terminated when the threat callbacks are suppressed/hooked by an attacker (Android only) ([Issue 65](https://github.com/talsec/Free-RASP-Android/issues/65))
66
+ - Added API for `timeSpoofing` callback into `ThreatEventActions` (Android only)
67
+ - Added API for `unsecureWifi` callback into `ThreatEventActions` (Android only)
68
+ - Added API for `allChecksFinished` callback into new `RaspExecutionStateEventActions` object
69
+ - Added matched permissions to `SuspiciousAppInfo` object when malware detection reason is `suspiciousPermission`
70
+
71
+ #### Fixed
72
+
73
+ - Resolved potential collision in threat identifiers
74
+
75
+ ### Android
76
+
77
+ #### Added
78
+
79
+ - Added `killOnBypass` method to the `TalsecConfig.Builder` that configures if the app should be terminated when the threat callbacks are suppressed/hooked by an attacker [Issue 65](https://github.com/talsec/Free-RASP-Android/issues/65)
80
+ - We are introducing a new capability, detecting whether the device time has been tampered with (`timeSpoofing`)
81
+ - We are introducing a new capability, detecting whether the location is being spoofed on the device (`locationSpoofing`)
82
+ - We are introducing a new capability, detection of unsecure WiFi (`unecureWifi`)
83
+ - Removed deprecated functionality `Pbkdf2Native` and both related native libraries (`libpbkdf2_native.so` and `libpolarssl.so`)
84
+ - Added new `RaspExecutionState` which contains `onAllChecksFinished()` method, which is triggered after all checks are completed.
85
+ - Added matched permissions to `SuspiciousAppInfo` object when malware detection reason is `suspiciousPermission`
86
+ - New option to start Talsec, `Talsec.start()` takes new parameter `TalsecMode` that determines the dispatcher thread of initialization and sync checks (uses background thread by default)
87
+ - Capability to check if another app has an option `REQUEST_INSTALL_PACKAGES` enabled in the system settings to malware detection
88
+
89
+ #### Fixed
90
+
91
+ - Root detection related bugs causing false positives
92
+ - ANR issue caused by `registerScreenCaptureCallback()` method on the main thread
93
+ - `NullPointerException` when checking key alias in Keystore on Android 7
94
+ - `JaCoCo` issue causing `MethodTooLargeException` during instrumentation
95
+ - `DeadApplicationException` when calling `Settings.Global.getInt` or `Settings.Secure.getInt` on invalid context
96
+ - `AndroidKeyStore` crashes causing `java.util.concurrent.TimeoutException` when calling `finalize()` method on `Cipher` (GC issues)
97
+ - Fixed issue with late initializers and `TalsecMode` coroutines scopes
98
+
99
+
100
+ #### Changed
101
+
102
+ - Deprecated Nexus repository removed (GCP artifact registry is the main supported distribution repository)
103
+ - Shortened the value of threat detection interval
104
+ - Refactoring of internal architecture of SDK that newly uses Coroutines to manage threading
105
+ - Update of internal dependencies and security libraries
106
+
107
+ ### iOS
108
+
109
+ #### Changed
110
+
111
+ - Updated internal dependencies
112
+
8
113
  ## [2.2.2] - 2025-08-12
9
114
 
10
115
  - iOS SDK version: 6.12.1
@@ -10,7 +10,11 @@ Pod::Spec.new do |s|
10
10
  s.homepage = package['repository']['url']
11
11
  s.author = package['author']
12
12
  s.source = { :git => package['repository']['url'], :tag => s.version.to_s }
13
- s.source_files = 'ios/Plugin/*.{swift,h,m,c,cc,mm,cpp}', 'ios/Plugin/TalsecRuntime.xcframework'
13
+ s.source_files = 'ios/Plugin/models/*.{swift,h,m,c,cc,mm,cpp}',
14
+ 'ios/Plugin/utils/*.{swift,h,m,c,cc,mm,cpp}',
15
+ 'ios/Plugin/dispatchers/*.{swift,h,m,c,cc,mm,cpp}',
16
+ 'ios/Plugin/*.{swift,h,m,c,cc,mm,cpp}',
17
+ 'ios/Plugin/TalsecRuntime.xcframework'
14
18
  s.ios.deployment_target = '13.0'
15
19
  s.dependency 'Capacitor'
16
20
  s.swift_version = '5.1'
package/README.md CHANGED
@@ -6,9 +6,9 @@
6
6
 
7
7
  # freeRASP for Capacitor
8
8
 
9
- freeRASP for Capacitor is a mobile in-app protection and security monitoring plugin. It aims to cover the main aspects of RASP (Runtime App Self Protection) and application shielding.
9
+ freeRASP for Capacitor is a mobile in-app threat detection and security monitoring plugin. It aims to cover the main aspects of RASP (Runtime App Self Protection) and application shielding.
10
10
 
11
- :loudspeaker: [The official documentation has been moved to a new location. You can now find it here](https://docs.talsec.app/docs-and-articles-portal). :loudspeaker:
11
+ :loudspeaker: [The official documentation has been moved to a new location. You can now find it here](https://docs.talsec.app/docs-and-articles-portal?utm_source=github). :loudspeaker:
12
12
 
13
13
  # Overview
14
14
 
@@ -28,7 +28,7 @@ Key features are the detection and prevention of
28
28
  - Untrusted installation method
29
29
  - App/Device (un)binding
30
30
 
31
- Additional freeRASP features include low latency, easy integration and a weekly [Security Report](https://docs.talsec.app/freerasp/security-report) containing detailed information about detected incidents and potential threats, summarizing the state of your app security.
31
+ Additional freeRASP features include low latency, easy integration and a weekly [Security Report](https://docs.talsec.app/freerasp/security-report?utm_source=github) containing detailed information about detected incidents and potential threats, summarizing the state of your app security.
32
32
 
33
33
  The commercial version provides a top-notch protection level, extra features, support and maintenance. One of the most valued commercial features is AppiCrypt® - App Integrity Cryptogram.
34
34
 
@@ -41,7 +41,7 @@ It allows easy to implement API protection and App Integrity verification on the
41
41
 
42
42
  It is a unified solution that works across all mobile platforms without dependency on external web services (i.e., without extra latency, an additional point of failure, and maintenance costs).
43
43
 
44
- Learn more about commercial features at [https://talsec.app](https://talsec.app).
44
+ Learn more about commercial features at [https://talsec.app](https://talsec.app?utm_source=github).
45
45
 
46
46
  Learn more about freemium freeRASP features at [GitHub main repository](https://github.com/talsec/Free-RASP-Community).
47
47
 
@@ -54,17 +54,17 @@ After the integration of freeRASP, make sure you visit the [freeMalwareDetection
54
54
 
55
55
  Visit the [GitBook page](https://docs.talsec.app/freerasp) for comprehensive and up-to-date guides, tutorials, and technical documentation specifically for freeRASP. It serves as your go-to resource, offering everything from basic instructions to advanced tips and tricks to help you get the most out of the project.
56
56
 
57
- :loudspeaker: [The official documentation has been moved to a new location. You can now find it here](https://docs.talsec.app/docs-and-articles-portal). :loudspeaker:
57
+ :loudspeaker: [The official documentation has been moved to a new location. You can now find it here](https://docs.talsec.app/docs-and-articles-portal?utm_source=github). :loudspeaker:
58
58
 
59
59
  ## :link: Integration Guide
60
60
 
61
- For integrating freeRASP on the Capacitor platform, be sure to follow all the steps in the [Integration Guide](https://docs.talsec.app/freerasp/integration). This guide provides detailed instructions to help you achieve a smooth and efficient integration.
61
+ For integrating freeRASP on the Capacitor platform, be sure to follow all the steps in the [Integration Guide](https://docs.talsec.app/freerasp/integration?utm_source=github). This guide provides detailed instructions to help you achieve a smooth and efficient integration.
62
62
 
63
63
  Be sure to bookmark it and stay informed! :books: :sparkles:.
64
64
 
65
65
  # :rocket: What's New and Changelog
66
66
 
67
- Stay informed and make the most of freeRASP by checking out [What's New and Changelog](https://docs.talsec.app/freerasp/whats-new-and-changelog)! Here, you’ll discover the latest features, enhancements, and bug fixes we’ve implemented to improve your experience across all platforms, including Android, iOS, Flutter, React Native, Capacitor, and Cordova.
67
+ Stay informed and make the most of freeRASP by checking out [What's New and Changelog](https://docs.talsec.app/freerasp/whats-new-and-changelog?utm_source=github)! Here, you’ll discover the latest features, enhancements, and bug fixes we’ve implemented to improve your experience across all platforms, including Android, iOS, Flutter, React Native, Capacitor, and Cordova.
68
68
 
69
69
  Don’t miss out on any updates and explore the changelog to see how we’re continually making freeRASP better for you!
70
70
 
@@ -76,4 +76,4 @@ You can check out the project board [here](https://github.com/orgs/talsec/projec
76
76
 
77
77
  # :page_facing_up: License
78
78
 
79
- This project is provided as freemium software, i.e. there is a [fair usage policy](https://docs.talsec.app/freerasp/features-and-pricing-plans#plans-comparison) that imposes some limitations on the free usage. The SDK software consists of open-source and binary parts, which is the property of Talsec. The open-source part is licensed under the MIT License - see the LICENSE file for details.
79
+ This project is provided as freemium software, i.e. there is a [fair usage policy](https://docs.talsec.app/freerasp/features-and-pricing-plans#plans-comparison?utm_source=github) that imposes some limitations on the free usage. The SDK software consists of open-source and binary parts, which is the property of Talsec. The open-source part is licensed under the MIT License - see the LICENSE file for details.
@@ -27,10 +27,10 @@ apply plugin: 'kotlinx-serialization'
27
27
 
28
28
  android {
29
29
  namespace "com.aheaditec.freerasp"
30
- compileSdk 35
30
+ compileSdk Math.max(36, project.hasProperty('rootProject.ext.compileSdk') ? rootProject.ext.compileSdk as int : 36)
31
31
  defaultConfig {
32
32
  minSdkVersion 23
33
- targetSdkVersion 35
33
+ targetSdkVersion 36
34
34
  versionCode 1
35
35
  versionName "1.0"
36
36
  testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -76,5 +76,5 @@ dependencies {
76
76
  androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
77
77
  androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
78
78
 
79
- implementation 'com.aheaditec.talsec.security:TalsecSecurity-Community-Capacitor:16.0.2'
79
+ implementation 'com.aheaditec.talsec.security:TalsecSecurity-Community-Capacitor:18.0.2'
80
80
  }
@@ -1,5 +1,6 @@
1
1
  package com.aheaditec.freerasp
2
2
 
3
+ import android.content.Context
3
4
  import android.os.Build
4
5
  import android.os.Handler
5
6
  import android.os.HandlerThread
@@ -11,7 +12,11 @@ import com.aheaditec.freerasp.utils.toEncodedJSArray
11
12
  import com.aheaditec.talsec_security.security.api.SuspiciousAppInfo
12
13
  import com.aheaditec.talsec_security.security.api.Talsec
13
14
  import com.aheaditec.talsec_security.security.api.TalsecConfig
14
- import com.aheaditec.talsec_security.security.api.ThreatListener
15
+ import com.aheaditec.freerasp.events.BaseRaspEvent
16
+ import com.aheaditec.freerasp.events.RaspExecutionStateEvent
17
+ import com.aheaditec.freerasp.events.ThreatEvent
18
+ import com.aheaditec.freerasp.interfaces.PluginExecutionStateListener
19
+ import com.aheaditec.freerasp.interfaces.PluginThreatListener
15
20
  import com.getcapacitor.JSObject
16
21
  import com.getcapacitor.Plugin
17
22
  import com.getcapacitor.PluginCall
@@ -19,11 +24,11 @@ import com.getcapacitor.PluginMethod
19
24
  import com.getcapacitor.annotation.CapacitorPlugin
20
25
  import org.json.JSONArray
21
26
 
27
+ typealias CapacitorCallback = (String, JSObject) -> Unit
28
+
22
29
  @CapacitorPlugin(name = "Freerasp")
23
30
  class FreeraspPlugin : Plugin() {
24
31
 
25
- private val threatHandler = TalsecThreatHandler(this)
26
- private val listener = ThreatListener(threatHandler, threatHandler)
27
32
  private var registered = true
28
33
 
29
34
  @PluginMethod
@@ -35,7 +40,15 @@ class FreeraspPlugin : Plugin() {
35
40
  }
36
41
  try {
37
42
  val talsecConfig = buildTalsecConfigThrowing(config)
38
- listener.registerListener(context)
43
+
44
+ val pluginCallback: CapacitorCallback = { eventName, data ->
45
+ notifyListeners(eventName, data, true)
46
+ }
47
+
48
+ PluginThreatHandler.threatDispatcher.listener = PluginListener(context, pluginCallback)
49
+ PluginThreatHandler.executionStateDispatcher.listener = PluginListener(context, pluginCallback)
50
+ PluginThreatHandler.registerListener(context)
51
+
39
52
  bridge.activity.runOnUiThread {
40
53
  Talsec.start(context, talsecConfig)
41
54
  mainHandler.post {
@@ -67,8 +80,10 @@ class FreeraspPlugin : Plugin() {
67
80
  override fun handleOnPause() {
68
81
  super.handleOnPause()
69
82
  if (activity.isFinishing) {
70
- listener.unregisterListener(context)
83
+ PluginThreatHandler.unregisterListener(context)
71
84
  registered = false
85
+ PluginThreatHandler.threatDispatcher.listener = null
86
+ PluginThreatHandler.executionStateDispatcher.listener = null
72
87
  }
73
88
  }
74
89
 
@@ -76,7 +91,7 @@ class FreeraspPlugin : Plugin() {
76
91
  super.handleOnResume()
77
92
  if (!registered) {
78
93
  registered = true
79
- listener.registerListener(context)
94
+ PluginThreatHandler.registerListener(context)
80
95
  }
81
96
  }
82
97
 
@@ -97,18 +112,40 @@ class FreeraspPlugin : Plugin() {
97
112
  */
98
113
  @PluginMethod
99
114
  fun getThreatIdentifiers(call: PluginCall) {
100
- call.resolve(JSObject().put("ids", Threat.getThreatValues()))
115
+ call.resolve(JSObject().put("ids", ThreatEvent.ALL_EVENTS))
101
116
  }
102
117
 
103
118
  /**
104
- * Method to setup the message passing between native and React Native
105
- * @return list of [THREAT_CHANNEL_NAME, THREAT_CHANNEL_KEY]
119
+ * Method to get the random identifiers of callbacks
120
+ */
121
+ @PluginMethod
122
+ fun getRaspExecutionStateIdentifiers(call: PluginCall) {
123
+ call.resolve(JSObject().put("ids", RaspExecutionStateEvent.ALL_EVENTS))
124
+ }
125
+
126
+ /**
127
+ * Method to setup the message passing between native and Capacitor
128
+ * @return list of [CHANNEL_NAME, CHANNEL_KEY, MALWARE_CHANNEL_KEY]
106
129
  */
107
130
  @PluginMethod
108
131
  fun getThreatChannelData(call: PluginCall) {
109
132
  val channelData = JSONArray(
110
133
  (listOf(
111
- THREAT_CHANNEL_NAME, THREAT_CHANNEL_KEY, MALWARE_CHANNEL_KEY
134
+ ThreatEvent.CHANNEL_NAME, ThreatEvent.CHANNEL_KEY, ThreatEvent.MALWARE_CHANNEL_KEY
135
+ ))
136
+ )
137
+ call.resolve(JSObject().put("ids", channelData))
138
+ }
139
+
140
+ /**
141
+ * Method to setup the execution state message passing between native and Capacitor
142
+ * @return list of [CHANNEL_NAME, CHANNEL_KEY]
143
+ */
144
+ @PluginMethod
145
+ fun getRaspExecutionStateChannelData(call: PluginCall) {
146
+ val channelData = JSONArray(
147
+ (listOf(
148
+ RaspExecutionStateEvent.CHANNEL_NAME, RaspExecutionStateEvent.CHANNEL_KEY
112
149
  ))
113
150
  )
114
151
  call.resolve(JSObject().put("ids", channelData))
@@ -119,7 +156,7 @@ class FreeraspPlugin : Plugin() {
119
156
  * Therefore, if this happens, we want to kill the app.
120
157
  */
121
158
  @PluginMethod
122
- fun onInvalidCallback() {
159
+ fun onInvalidCallback(call: PluginCall) {
123
160
  android.os.Process.killProcess(android.os.Process.myPid())
124
161
  }
125
162
 
@@ -179,7 +216,7 @@ class FreeraspPlugin : Plugin() {
179
216
 
180
217
  activity?.runOnUiThread {
181
218
  try {
182
- Talsec.blockScreenCapture(context, enable)
219
+ Talsec.blockScreenCapture(activity, enable)
183
220
  call.resolve(JSObject().put("result", true))
184
221
  } catch (e: Exception) {
185
222
  call.reject(
@@ -224,24 +261,21 @@ class FreeraspPlugin : Plugin() {
224
261
  "Error during storeExternalId operation in freeRASP Native Plugin",
225
262
  "NativePluginError"
226
263
  )
264
+ return
227
265
  }
228
266
  }
229
267
 
230
- internal fun notifyListeners(threat: Threat) {
231
- notifyListeners(THREAT_CHANNEL_NAME, JSObject().put(THREAT_CHANNEL_KEY, threat.value), true)
232
- }
233
-
234
- internal fun notifyMalware(suspiciousApps: MutableList<SuspiciousAppInfo>) {
235
- // Perform the malware encoding on a background thread
236
- backgroundHandler.post {
237
-
238
- val encodedSuspiciousApps = suspiciousApps.toEncodedJSArray(context)
239
- mainHandler.post {
240
- val params = JSObject()
241
- .put(THREAT_CHANNEL_KEY, Threat.Malware.value)
242
- .put(MALWARE_CHANNEL_KEY, encodedSuspiciousApps)
243
- notifyListeners(THREAT_CHANNEL_NAME, params, true)
244
- }
268
+ @PluginMethod
269
+ fun removeExternalId(call: PluginCall) {
270
+ try {
271
+ Talsec.removeExternalId(context)
272
+ call.resolve(JSObject().put("result", true))
273
+ } catch (e: Exception) {
274
+ call.reject(
275
+ "Error during removeExternalId operation in freeRASP Native Plugin",
276
+ "NativePluginError"
277
+ )
278
+ return
245
279
  }
246
280
  }
247
281
 
@@ -253,6 +287,7 @@ class FreeraspPlugin : Plugin() {
253
287
  .watcherMail(configJson.getString("watcherMail"))
254
288
  .supportedAlternativeStores(androidConfig.getArraySafe("supportedAlternativeStores"))
255
289
  .prod(configJson.getBool("isProd") ?: true)
290
+ .killOnBypass(configJson.getBool("killOnBypass") ?: false)
256
291
 
257
292
  if (androidConfig.has("malwareConfig")) {
258
293
  val malwareConfig = androidConfig.getJSONObject("malwareConfig")
@@ -266,16 +301,54 @@ class FreeraspPlugin : Plugin() {
266
301
 
267
302
 
268
303
  companion object {
269
- private val THREAT_CHANNEL_NAME = (10000..999999999).random()
270
- .toString() // name of the channel over which threat callbacks are sent
271
- private val THREAT_CHANNEL_KEY = (10000..999999999).random()
272
- .toString() // key of the argument map under which threats are expected
273
- private val MALWARE_CHANNEL_KEY = (10000..999999999).random()
274
- .toString() // key of the argument map under which malware data is expected
275
304
  private val backgroundHandlerThread = HandlerThread("BackgroundThread").apply { start() }
276
305
  private val backgroundHandler = Handler(backgroundHandlerThread.looper)
277
306
  private val mainHandler = Handler(Looper.getMainLooper())
278
307
 
279
308
  internal var talsecStarted = false
309
+
310
+ internal fun notifyEvent(
311
+ event: BaseRaspEvent,
312
+ notifyListenersCallback: CapacitorCallback
313
+ ) {
314
+ val params = JSObject().put(event.channelKey, event.value)
315
+ notifyListenersCallback(event.channelName, params)
316
+ }
317
+
318
+ internal fun notifyMalware(
319
+ suspiciousApps: MutableList<SuspiciousAppInfo>,
320
+ context: Context,
321
+ notifyListenersCallback: CapacitorCallback
322
+ ) {
323
+ // Perform the malware encoding on a background thread
324
+ backgroundHandler.post {
325
+
326
+ val encodedSuspiciousApps = suspiciousApps.toEncodedJSArray(context)
327
+ mainHandler.post {
328
+ val params = JSObject()
329
+ .put(ThreatEvent.CHANNEL_KEY, ThreatEvent.Malware.value)
330
+ .put(ThreatEvent.MALWARE_CHANNEL_KEY, encodedSuspiciousApps)
331
+ notifyListenersCallback.invoke(ThreatEvent.CHANNEL_NAME, params)
332
+ }
333
+
334
+ }
335
+ }
336
+ }
337
+
338
+ internal class PluginListener(
339
+ private val context: Context,
340
+ private val pluginCallback: CapacitorCallback
341
+ ) : PluginThreatListener, PluginExecutionStateListener {
342
+ override fun threatDetected(threatEventType: ThreatEvent) {
343
+ notifyEvent(threatEventType, pluginCallback)
344
+ }
345
+
346
+ override fun malwareDetected(suspiciousApps: MutableList<SuspiciousAppInfo>) {
347
+ notifyMalware(suspiciousApps, context, pluginCallback)
348
+ }
349
+
350
+ override fun raspExecutionStateChanged(event: RaspExecutionStateEvent) {
351
+ notifyEvent(event, pluginCallback)
352
+ }
280
353
  }
281
354
  }
@@ -0,0 +1,121 @@
1
+ package com.aheaditec.freerasp
2
+
3
+ import android.content.Context
4
+ import com.aheaditec.talsec_security.security.api.SuspiciousAppInfo
5
+ import com.aheaditec.talsec_security.security.api.ThreatListener
6
+ import com.aheaditec.freerasp.dispatchers.ExecutionStateDispatcher
7
+ import com.aheaditec.freerasp.dispatchers.ThreatDispatcher
8
+ import com.aheaditec.freerasp.events.RaspExecutionStateEvent
9
+ import com.aheaditec.freerasp.events.ThreatEvent
10
+
11
+ internal object PluginThreatHandler {
12
+
13
+ internal val threatDispatcher = ThreatDispatcher()
14
+ internal val executionStateDispatcher = ExecutionStateDispatcher()
15
+
16
+ private val threatDetected = object : ThreatListener.ThreatDetected() {
17
+
18
+ override fun onRootDetected() {
19
+ threatDispatcher.dispatchThreat(ThreatEvent.PrivilegedAccess)
20
+ }
21
+
22
+ override fun onDebuggerDetected() {
23
+ threatDispatcher.dispatchThreat(ThreatEvent.Debug)
24
+ }
25
+
26
+ override fun onEmulatorDetected() {
27
+ threatDispatcher.dispatchThreat(ThreatEvent.Simulator)
28
+ }
29
+
30
+ override fun onTamperDetected() {
31
+ threatDispatcher.dispatchThreat(ThreatEvent.AppIntegrity)
32
+ }
33
+
34
+ override fun onUntrustedInstallationSourceDetected() {
35
+ threatDispatcher.dispatchThreat(ThreatEvent.UnofficialStore)
36
+ }
37
+
38
+ override fun onHookDetected() {
39
+ threatDispatcher.dispatchThreat(ThreatEvent.Hooks)
40
+ }
41
+
42
+ override fun onDeviceBindingDetected() {
43
+ threatDispatcher.dispatchThreat(ThreatEvent.DeviceBinding)
44
+ }
45
+
46
+ override fun onObfuscationIssuesDetected() {
47
+ threatDispatcher.dispatchThreat(ThreatEvent.ObfuscationIssues)
48
+ }
49
+
50
+ override fun onMalwareDetected(suspiciousAppInfos: MutableList<SuspiciousAppInfo>) {
51
+ threatDispatcher.dispatchMalware(suspiciousAppInfos ?: mutableListOf())
52
+ }
53
+
54
+ override fun onScreenshotDetected() {
55
+ threatDispatcher.dispatchThreat(ThreatEvent.Screenshot)
56
+ }
57
+
58
+ override fun onScreenRecordingDetected() {
59
+ threatDispatcher.dispatchThreat(ThreatEvent.ScreenRecording)
60
+ }
61
+
62
+ override fun onMultiInstanceDetected() {
63
+ threatDispatcher.dispatchThreat(ThreatEvent.MultiInstance)
64
+ }
65
+
66
+ override fun onUnsecureWifiDetected() {
67
+ threatDispatcher.dispatchThreat(ThreatEvent.UnsecureWifi)
68
+ }
69
+
70
+ override fun onTimeSpoofingDetected() {
71
+ threatDispatcher.dispatchThreat(ThreatEvent.TimeSpoofing)
72
+ }
73
+
74
+ override fun onLocationSpoofingDetected() {
75
+ threatDispatcher.dispatchThreat(ThreatEvent.LocationSpoofing)
76
+ }
77
+
78
+ override fun onAutomationDetected() {
79
+ threatDispatcher.dispatchThreat(ThreatEvent.Automation)
80
+ }
81
+ }
82
+
83
+ private val deviceState = object : ThreatListener.DeviceState() {
84
+
85
+ override fun onUnlockedDeviceDetected() {
86
+ threatDispatcher.dispatchThreat(ThreatEvent.Passcode)
87
+ }
88
+
89
+ override fun onHardwareBackedKeystoreNotAvailableDetected() {
90
+ threatDispatcher.dispatchThreat(ThreatEvent.SecureHardwareNotAvailable)
91
+ }
92
+
93
+ override fun onDeveloperModeDetected() {
94
+ threatDispatcher.dispatchThreat(ThreatEvent.DevMode)
95
+ }
96
+
97
+ override fun onADBEnabledDetected() {
98
+ threatDispatcher.dispatchThreat(ThreatEvent.ADBEnabled)
99
+ }
100
+
101
+ override fun onSystemVPNDetected() {
102
+ threatDispatcher.dispatchThreat(ThreatEvent.SystemVPN)
103
+ }
104
+ }
105
+
106
+ private val raspExecutionState = object : ThreatListener.RaspExecutionState() {
107
+ override fun onAllChecksFinished() {
108
+ executionStateDispatcher.dispatch(RaspExecutionStateEvent.AllChecksFinished)
109
+ }
110
+ }
111
+
112
+ private val internalListener = ThreatListener(threatDetected, deviceState, raspExecutionState)
113
+
114
+ internal fun registerListener(context: Context) {
115
+ internalListener.registerListener(context)
116
+ }
117
+
118
+ internal fun unregisterListener(context: Context) {
119
+ internalListener.unregisterListener(context)
120
+ }
121
+ }
@@ -11,6 +11,7 @@ import android.view.WindowManager.SCREEN_RECORDING_STATE_VISIBLE
11
11
  import androidx.annotation.RequiresApi
12
12
  import androidx.core.content.ContextCompat
13
13
  import com.aheaditec.talsec_security.security.api.Talsec
14
+ import com.aheaditec.freerasp.events.ThreatEvent
14
15
  import java.util.function.Consumer
15
16
 
16
17
  @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
@@ -18,14 +19,35 @@ internal object ScreenProtector {
18
19
  private const val TAG = "TalsecScreenProtector"
19
20
  private const val SCREEN_CAPTURE_PERMISSION = "android.permission.DETECT_SCREEN_CAPTURE"
20
21
  private const val SCREEN_RECORDING_PERMISSION = "android.permission.DETECT_SCREEN_RECORDING"
22
+
21
23
  private var registered = false
22
- private val screenCaptureCallback = ScreenCaptureCallback { Talsec.onScreenshotDetected() }
24
+ private val cachedThreats = mutableSetOf<ThreatEvent>()
25
+
26
+ private val screenCaptureCallback = ScreenCaptureCallback { handleThreat(ThreatEvent.Screenshot) }
23
27
  private val screenRecordCallback: Consumer<Int> = Consumer<Int> { state ->
24
28
  if (state == SCREEN_RECORDING_STATE_VISIBLE) {
25
- Talsec.onScreenRecordingDetected()
29
+ handleThreat(ThreatEvent.ScreenRecording)
30
+ }
31
+ }
32
+
33
+ private fun handleThreat(threat: ThreatEvent) {
34
+ if(!FreeraspPlugin.talsecStarted) {
35
+ cachedThreats.add(threat)
36
+ return
37
+ }
38
+
39
+ when (threat) {
40
+ ThreatEvent.Screenshot -> Talsec.onScreenshotDetected()
41
+ ThreatEvent.ScreenRecording -> Talsec.onScreenRecordingDetected()
42
+ else -> throw IllegalArgumentException("Unexpected Threat type: $threat")
26
43
  }
27
44
  }
28
45
 
46
+ internal fun flushCache() {
47
+ cachedThreats.forEach { handleThreat(it) }
48
+ cachedThreats.clear()
49
+ }
50
+
29
51
  /**
30
52
  * Registers screenshot and screen recording detector with the given activity
31
53
  *
@@ -0,0 +1,38 @@
1
+ package com.aheaditec.freerasp.dispatchers
2
+
3
+ import com.aheaditec.freerasp.events.RaspExecutionStateEvent
4
+ import com.aheaditec.freerasp.interfaces.PluginExecutionStateListener
5
+
6
+ internal class ExecutionStateDispatcher {
7
+ private val cache = mutableSetOf<RaspExecutionStateEvent>()
8
+
9
+ var listener: PluginExecutionStateListener? = null
10
+ set(value) {
11
+ field = value
12
+ if (value != null) {
13
+ flushCache(value)
14
+ }
15
+ }
16
+
17
+ fun dispatch(event: RaspExecutionStateEvent) {
18
+ val checkedListener = synchronized(cache) {
19
+ val currentListener = listener
20
+ if (currentListener != null) {
21
+ currentListener
22
+ } else {
23
+ cache.add(event)
24
+ null
25
+ }
26
+ }
27
+ checkedListener?.raspExecutionStateChanged(event)
28
+ }
29
+
30
+ private fun flushCache(registeredListener: PluginExecutionStateListener) {
31
+ val events = synchronized(cache) {
32
+ val snapshot = cache.toSet()
33
+ cache.clear()
34
+ snapshot
35
+ }
36
+ events.forEach { registeredListener.raspExecutionStateChanged(it) }
37
+ }
38
+ }