freerasp-react-native 3.13.0 → 3.14.1

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 (123) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/README.md +4 -2
  3. package/android/build.gradle +3 -3
  4. package/android/gradle.properties +2 -2
  5. package/android/proguard-rules.pro +8 -0
  6. package/android/src/main/java/com/freeraspreactnative/FreeraspReactNativeModule.kt +59 -10
  7. package/android/src/main/java/com/freeraspreactnative/FreeraspThreatHandler.kt +8 -0
  8. package/android/src/main/java/com/freeraspreactnative/ScreenProtector.kt +164 -0
  9. package/android/src/main/java/com/freeraspreactnative/Threat.kt +5 -1
  10. package/android/src/main/java/com/freeraspreactnative/utils/Extensions.kt +1 -1
  11. package/example/Gemfile +6 -2
  12. package/example/Gemfile.lock +121 -0
  13. package/example/android/app/build.gradle +64 -265
  14. package/example/android/app/src/debug/AndroidManifest.xml +1 -5
  15. package/example/android/app/src/main/AndroidManifest.xml +5 -3
  16. package/example/android/app/src/main/java/com/freerasp/rn/example/MainActivity.kt +22 -0
  17. package/example/android/app/src/main/java/com/freerasp/rn/example/MainApplication.kt +44 -0
  18. package/example/android/app/src/main/res/drawable/rn_edit_text_material.xml +3 -2
  19. package/example/android/app/src/main/res/values/strings.xml +1 -1
  20. package/example/android/build.gradle +16 -45
  21. package/example/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  22. package/example/android/gradle/wrapper/gradle-wrapper.properties +3 -1
  23. package/example/android/gradle.properties +5 -6
  24. package/example/android/gradlew +30 -13
  25. package/example/android/gradlew.bat +21 -16
  26. package/example/android/settings.gradle +5 -10
  27. package/example/app.json +3 -3
  28. package/example/index.js +4 -0
  29. package/example/ios/FreeraspRNExample/AppDelegate.swift +30 -0
  30. package/example/ios/{FreeraspReactNativeExample → FreeraspRNExample}/Info.plist +8 -12
  31. package/example/ios/{FreeraspReactNativeExample → FreeraspRNExample}/LaunchScreen.storyboard +1 -1
  32. package/example/ios/FreeraspRNExample/PrivacyInfo.xcprivacy +37 -0
  33. package/example/ios/FreeraspRNExample.xcodeproj/project.pbxproj +488 -0
  34. package/example/ios/{FreeraspReactNativeExample.xcodeproj/xcshareddata/xcschemes/FreeraspReactNativeExample.xcscheme → FreeraspRNExample.xcodeproj/xcshareddata/xcschemes/FreeraspRNExample.xcscheme} +12 -12
  35. package/example/ios/{FreeraspReactNativeExample.xcworkspace → FreeraspRNExample.xcworkspace}/contents.xcworkspacedata +1 -1
  36. package/example/ios/Podfile +19 -32
  37. package/example/metro.config.js +13 -14
  38. package/example/package.json +23 -12
  39. package/example/src/App.tsx +18 -0
  40. package/example/src/DemoApp.tsx +181 -79
  41. package/example/src/MalwareModal.tsx +2 -12
  42. package/example/src/checks.ts +2 -0
  43. package/example/yarn.lock +3825 -1613
  44. package/ios/FreeraspReactNative.swift +6 -2
  45. package/ios/TalsecRuntime.xcframework/Info.plist +5 -5
  46. package/ios/TalsecRuntime.xcframework/_CodeSignature/CodeDirectory +0 -0
  47. package/ios/TalsecRuntime.xcframework/_CodeSignature/CodeRequirements-1 +0 -0
  48. package/ios/TalsecRuntime.xcframework/_CodeSignature/CodeResources +87 -87
  49. package/ios/TalsecRuntime.xcframework/_CodeSignature/CodeSignature +0 -0
  50. package/ios/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/CurlWrapper.h +1 -1
  51. package/ios/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/TalsecRuntime-Swift.h +1 -1
  52. package/ios/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/curl.h +7 -7
  53. package/ios/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/multi.h +4 -4
  54. package/ios/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/options.h +1 -1
  55. package/ios/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/urlapi.h +1 -1
  56. package/ios/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Info.plist +0 -0
  57. package/ios/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios.abi.json +316 -178
  58. package/ios/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios.private.swiftinterface +2 -0
  59. package/ios/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios.swiftdoc +0 -0
  60. package/ios/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios.swiftinterface +2 -0
  61. package/ios/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/TalsecRuntime +0 -0
  62. package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/CurlWrapper.h +1 -1
  63. package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/TalsecRuntime-Swift.h +2 -2
  64. package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/curl.h +7 -7
  65. package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/multi.h +4 -4
  66. package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/options.h +1 -1
  67. package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/urlapi.h +1 -1
  68. package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Info.plist +0 -0
  69. package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.abi.json +316 -178
  70. package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface +2 -0
  71. package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.swiftdoc +0 -0
  72. package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.swiftinterface +2 -0
  73. package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.abi.json +316 -178
  74. package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface +2 -0
  75. package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.swiftdoc +0 -0
  76. package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.swiftinterface +2 -0
  77. package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/TalsecRuntime +0 -0
  78. package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/_CodeSignature/CodeResources +33 -33
  79. package/lib/commonjs/index.js +25 -3
  80. package/lib/commonjs/index.js.map +1 -1
  81. package/lib/commonjs/threat.js +3 -1
  82. package/lib/commonjs/threat.js.map +1 -1
  83. package/lib/module/index.js +19 -1
  84. package/lib/module/index.js.map +1 -1
  85. package/lib/module/threat.js +3 -1
  86. package/lib/module/threat.js.map +1 -1
  87. package/lib/typescript/src/index.d.ts +2 -0
  88. package/lib/typescript/src/index.d.ts.map +1 -1
  89. package/lib/typescript/src/threat.d.ts +2 -0
  90. package/lib/typescript/src/threat.d.ts.map +1 -1
  91. package/lib/typescript/src/types.d.ts +2 -0
  92. package/lib/typescript/src/types.d.ts.map +1 -1
  93. package/package.json +1 -1
  94. package/src/index.tsx +24 -0
  95. package/src/threat.ts +6 -0
  96. package/src/types.ts +2 -0
  97. package/example/android/app/_BUCK +0 -55
  98. package/example/android/app/build_defs.bzl +0 -19
  99. package/example/android/app/src/debug/java/com/freeraspreactnativeexample/ReactNativeFlipper.java +0 -73
  100. package/example/android/app/src/main/java/com/freeraspreactnativeexample/MainActivity.java +0 -48
  101. package/example/android/app/src/main/java/com/freeraspreactnativeexample/MainApplication.java +0 -91
  102. package/example/android/app/src/main/java/com/freeraspreactnativeexample/newarchitecture/MainApplicationReactNativeHost.java +0 -116
  103. package/example/android/app/src/main/java/com/freeraspreactnativeexample/newarchitecture/components/MainComponentsRegistry.java +0 -36
  104. package/example/android/app/src/main/java/com/freeraspreactnativeexample/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java +0 -48
  105. package/example/android/app/src/main/jni/CMakeLists.txt +0 -7
  106. package/example/android/app/src/main/jni/MainApplicationModuleProvider.cpp +0 -32
  107. package/example/android/app/src/main/jni/MainApplicationModuleProvider.h +0 -16
  108. package/example/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp +0 -45
  109. package/example/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h +0 -38
  110. package/example/android/app/src/main/jni/MainComponentsRegistry.cpp +0 -65
  111. package/example/android/app/src/main/jni/MainComponentsRegistry.h +0 -32
  112. package/example/android/app/src/main/jni/OnLoad.cpp +0 -11
  113. package/example/ios/File.swift +0 -6
  114. package/example/ios/FreeraspReactNativeExample/AppDelegate.h +0 -8
  115. package/example/ios/FreeraspReactNativeExample/AppDelegate.mm +0 -133
  116. package/example/ios/FreeraspReactNativeExample/main.m +0 -10
  117. package/example/ios/FreeraspReactNativeExample-Bridging-Header.h +0 -3
  118. package/example/ios/FreeraspReactNativeExample.xcodeproj/project.pbxproj +0 -729
  119. package/example/ios/FreeraspReactNativeExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -8
  120. package/example/ios/FreeraspReactNativeExampleTests/FreeraspReactNativeExampleTests.m +0 -66
  121. package/example/ios/FreeraspReactNativeExampleTests/Info.plist +0 -24
  122. /package/example/ios/{FreeraspReactNativeExample → FreeraspRNExample}/Images.xcassets/AppIcon.appiconset/Contents.json +0 -0
  123. /package/example/ios/{FreeraspReactNativeExample → FreeraspRNExample}/Images.xcassets/Contents.json +0 -0
package/CHANGELOG.md CHANGED
@@ -5,6 +5,61 @@ 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
+ ## [3.14.1] - 2024-03-10
9
+
10
+ - iOS SDK version: 6.8.0
11
+ - Android SDK version: 14.0.1
12
+
13
+ ### React Native
14
+
15
+ #### Fixed
16
+
17
+ - Take Android targetSdkVersion, compileSdkVersion from plugin only
18
+
19
+ ## [3.14.0] - 2024-03-05
20
+
21
+ - iOS SDK version: 6.8.0
22
+ - Android SDK version: 14.0.1
23
+
24
+ ### React Native
25
+
26
+ #### Added
27
+
28
+ - `blockScreenCapture` method to block/unblock screen capture
29
+ - `isScreenCaptureBlocked` method to get the current screen capture blocking status
30
+ - New callbacks:
31
+ - `screenshot`: Detects when a screenshot is taken
32
+ - `screenRecording`: Detects when screen recording is active
33
+
34
+ #### Changed
35
+
36
+ - Raised Android compileSDK level to 35
37
+
38
+ #### Fixed
39
+
40
+ - Compatibility issues with RN New Architecture
41
+ - Added proguard rules for malware data serialization in release mode on Android
42
+
43
+ ### Android
44
+
45
+ #### Added
46
+
47
+ - Passive and active screenshot/screen recording protection
48
+
49
+ #### Changed
50
+
51
+ - Improved root detection
52
+
53
+ #### Fixed
54
+
55
+ - Proguard rules to address warnings from okhttp dependency
56
+
57
+ ### iOS
58
+
59
+ #### Added
60
+
61
+ - Passive Screenshot/Screen Recording detection
62
+
8
63
  ## [3.13.0] - 2024-12-20
9
64
 
10
65
  - iOS SDK version: 6.6.3
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- ![FreeRasp](https://raw.githubusercontent.com/talsec/Free-RASP-Community/master/visuals/freeRASPforRN.png)
1
+ ![FreeRasp](https://raw.githubusercontent.com/talsec/Free-RASP-Community/master/visuals/freeRASP.png)
2
2
 
3
3
  ![GitHub Repo stars](https://img.shields.io/github/stars/talsec/Free-RASP-Community?color=green) ![GitHub](https://img.shields.io/github/license/talsec/Free-RASP-Community) ![GitHub](https://img.shields.io/github/last-commit/talsec/Free-RASP-Community) ![Publisher](https://img.shields.io/pub/publisher/freerasp) [![42matters](https://42matters.com/badges/sdk-installations/talsec)](https://42matters.com/sdks/android/talsec)
4
4
 
@@ -8,7 +8,7 @@
8
8
 
9
9
  freeRASP for React Native 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.
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). :loudspeaker:
12
12
 
13
13
  # Overview
14
14
 
@@ -54,6 +54,8 @@ 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:
58
+
57
59
  ## :link: Integration Guide
58
60
 
59
61
  For integrating freeRASP on the React Native 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.
@@ -40,11 +40,11 @@ def getIntegerDefault(name) {
40
40
  }
41
41
 
42
42
  android {
43
- compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")
43
+ compileSdkVersion getIntegerDefault("compileSdkVersion")
44
44
 
45
45
  defaultConfig {
46
46
  minSdkVersion getIntegerDefault("minSdkVersion")
47
- targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
47
+ targetSdkVersion getIntegerDefault("targetSdkVersion")
48
48
  buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
49
49
  }
50
50
  buildTypes {
@@ -90,7 +90,7 @@ dependencies {
90
90
  implementation "com.facebook.react:react-native:$react_native_version"
91
91
  implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
92
92
  implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1"
93
- implementation "com.aheaditec.talsec.security:TalsecSecurity-Community-ReactNative:13.2.0"
93
+ implementation "com.aheaditec.talsec.security:TalsecSecurity-Community-ReactNative:14.0.1"
94
94
  }
95
95
 
96
96
  if (isNewArchitectureEnabled()) {
@@ -1,6 +1,6 @@
1
1
  FreeraspReactNative_kotlinVersion=1.7.0
2
2
  FreeraspReactNative_minSdkVersion=23
3
- FreeraspReactNative_targetSdkVersion=31
4
- FreeraspReactNative_compileSdkVersion=33
3
+ FreeraspReactNative_targetSdkVersion=35
4
+ FreeraspReactNative_compileSdkVersion=35
5
5
  FreeraspReactNative_ndkversion=21.4.7075529
6
6
  FreeraspReactNative_reactNativeVersion=+
@@ -1,2 +1,10 @@
1
1
  -dontwarn java.lang.invoke.StringConcatFactory
2
2
  -keep class com.freeraspreactnative.FreeraspReactNativePackage { public *; }
3
+
4
+ -if @kotlinx.serialization.Serializable class **
5
+ -keep class <1> {
6
+ *;
7
+ }
8
+
9
+ -keep class com.freeraspreactnative.models.RNSuspiciousAppInfo$Companion
10
+ -keep class com.freeraspreactnative.models.RNPackageInfo$Companion
@@ -1,5 +1,6 @@
1
1
  package com.freeraspreactnative
2
2
 
3
+ import android.os.Build
3
4
  import android.os.Handler
4
5
  import android.os.HandlerThread
5
6
  import android.os.Looper
@@ -31,11 +32,15 @@ class FreeraspReactNativeModule(private val reactContext: ReactApplicationContex
31
32
  private val listener = ThreatListener(FreeraspThreatHandler, FreeraspThreatHandler)
32
33
  private val lifecycleListener = object : LifecycleEventListener {
33
34
  override fun onHostResume() {
34
- // do nothing
35
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
36
+ currentActivity?.let { ScreenProtector.register(it) }
37
+ }
35
38
  }
36
39
 
37
40
  override fun onHostPause() {
38
- // do nothing
41
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
42
+ currentActivity?.let { ScreenProtector.unregister(it) }
43
+ }
39
44
  }
40
45
 
41
46
  override fun onHostDestroy() {
@@ -54,8 +59,7 @@ class FreeraspReactNativeModule(private val reactContext: ReactApplicationContex
54
59
 
55
60
  @ReactMethod
56
61
  fun talsecStart(
57
- options: ReadableMap,
58
- promise: Promise
62
+ options: ReadableMap, promise: Promise
59
63
  ) {
60
64
 
61
65
  try {
@@ -64,10 +68,18 @@ class FreeraspReactNativeModule(private val reactContext: ReactApplicationContex
64
68
  listener.registerListener(reactContext)
65
69
  runOnUiThread {
66
70
  Talsec.start(reactContext, config)
71
+ mainHandler.post {
72
+ talsecStarted = true
73
+ // This code must be called only AFTER Talsec.start
74
+ currentActivity?.let { activity ->
75
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
76
+ ScreenProtector.register(activity)
77
+ }
78
+ }
79
+ promise.resolve("freeRASP started")
80
+ }
67
81
  }
68
82
 
69
- promise.resolve("freeRASP started")
70
-
71
83
  } catch (e: Exception) {
72
84
  promise.reject("TalsecInitializationError", e.message, e)
73
85
  }
@@ -136,6 +148,43 @@ class FreeraspReactNativeModule(private val reactContext: ReactApplicationContex
136
148
  }
137
149
  }
138
150
 
151
+ /**
152
+ * Method Block/Unblock screen capture
153
+ * @param enable boolean for whether want to block or unblock the screen capture
154
+ */
155
+ @ReactMethod
156
+ fun blockScreenCapture(enable: Boolean, promise: Promise) {
157
+ val activity = currentActivity ?: run {
158
+ promise.reject(
159
+ "NativePluginError", "Cannot block screen capture, activity is null."
160
+ )
161
+ return
162
+ }
163
+
164
+ runOnUiThread {
165
+ try {
166
+ Talsec.blockScreenCapture(activity, enable)
167
+ promise.resolve("Screen capture is now ${if (enable) "Blocked" else "Enabled"}.")
168
+ } catch (e: Exception) {
169
+ promise.reject("NativePluginError", "Error in blockScreenCapture: ${e.message}")
170
+ }
171
+ }
172
+ }
173
+
174
+ /**
175
+ * Method Returns whether screen capture is blocked or not
176
+ * @return boolean for is screem capture blocked or not
177
+ */
178
+ @ReactMethod
179
+ fun isScreenCaptureBlocked(promise: Promise) {
180
+ try {
181
+ val isBlocked = Talsec.isScreenCaptureBlocked()
182
+ promise.resolve(isBlocked)
183
+ } catch (e: Exception) {
184
+ promise.reject("NativePluginError", "Error in isScreenCaptureBlocked: ${e.message}")
185
+ }
186
+ }
187
+
139
188
  private fun buildTalsecConfig(config: ReadableMap): TalsecConfig {
140
189
  val androidConfig = config.getMapThrowing("androidConfig")
141
190
  val packageName = androidConfig.getStringThrowing("packageName")
@@ -172,11 +221,12 @@ class FreeraspReactNativeModule(private val reactContext: ReactApplicationContex
172
221
 
173
222
  private lateinit var appReactContext: ReactApplicationContext
174
223
 
224
+ internal var talsecStarted = false
225
+
175
226
  private fun notifyListeners(threat: Threat) {
176
227
  val params = Arguments.createMap()
177
228
  params.putInt(THREAT_CHANNEL_KEY, threat.value)
178
- appReactContext
179
- .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
229
+ appReactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
180
230
  .emit(THREAT_CHANNEL_NAME, params)
181
231
  }
182
232
 
@@ -196,8 +246,7 @@ class FreeraspReactNativeModule(private val reactContext: ReactApplicationContex
196
246
  MALWARE_CHANNEL_KEY, encodedSuspiciousApps
197
247
  )
198
248
 
199
- appReactContext
200
- .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
249
+ appReactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
201
250
  .emit(THREAT_CHANNEL_NAME, params)
202
251
  }
203
252
  }
@@ -63,6 +63,14 @@ internal object FreeraspThreatHandler : ThreatListener.ThreatDetected, ThreatLis
63
63
  listener?.threatDetected(Threat.SystemVPN)
64
64
  }
65
65
 
66
+ override fun onScreenshotDetected() {
67
+ listener?.threatDetected(Threat.Screenshot)
68
+ }
69
+
70
+ override fun onScreenRecordingDetected() {
71
+ listener?.threatDetected(Threat.ScreenRecording)
72
+ }
73
+
66
74
  internal interface TalsecReactNative {
67
75
  fun threatDetected(threatType: Threat)
68
76
 
@@ -0,0 +1,164 @@
1
+ package com.freeraspreactnative
2
+
3
+ import android.annotation.SuppressLint
4
+ import android.annotation.TargetApi
5
+ import android.app.Activity
6
+ import android.app.Activity.ScreenCaptureCallback
7
+ import android.content.Context
8
+ import android.content.pm.PackageManager
9
+ import android.os.Build
10
+ import android.util.Log
11
+ import android.view.WindowManager.SCREEN_RECORDING_STATE_VISIBLE
12
+ import androidx.annotation.RequiresApi
13
+ import androidx.core.content.ContextCompat
14
+
15
+ import com.aheaditec.talsec_security.security.api.Talsec
16
+ import java.util.function.Consumer
17
+
18
+ @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
19
+ internal object ScreenProtector {
20
+ private const val TAG = "TalsecScreenProtector"
21
+ private const val SCREEN_CAPTURE_PERMISSION = "android.permission.DETECT_SCREEN_CAPTURE"
22
+ private const val SCREEN_RECORDING_PERMISSION = "android.permission.DETECT_SCREEN_RECORDING"
23
+ private var registered = false
24
+ private val screenCaptureCallback = ScreenCaptureCallback { Talsec.onScreenshotDetected() }
25
+ private val screenRecordCallback: Consumer<Int> = Consumer<Int> { state ->
26
+ if (state == SCREEN_RECORDING_STATE_VISIBLE) {
27
+ Talsec.onScreenRecordingDetected()
28
+ }
29
+ }
30
+
31
+ /**
32
+ * Registers screenshot and screen recording detector with the given activity
33
+ *
34
+ * **IMPORTANT**: android.permission.DETECT_SCREEN_CAPTURE and
35
+ * android.permission.DETECT_SCREEN_RECORDING must be
36
+ * granted for the app in the AndroidManifest.xml
37
+ */
38
+ internal fun register(activity: Activity) {
39
+ if (!FreeraspReactNativeModule.talsecStarted || registered) {
40
+ return
41
+ }
42
+
43
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
44
+ registerScreenCapture(activity)
45
+ }
46
+
47
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
48
+ registerScreenRecording(activity)
49
+ }
50
+ registered = true
51
+ }
52
+
53
+ /**
54
+ * Register Talsec Screen Capture (screenshot) Detector for given activity instance.
55
+ * The MainActivity of the app is registered by the plugin itself, other
56
+ * activities bust be registered manually as described in the integration guide.
57
+ *
58
+ * Missing permission is suppressed because the decision to use the screen
59
+ * capture API is made by developer, and not enforced by the library.
60
+ *
61
+ * **IMPORTANT**: android.permission.DETECT_SCREEN_CAPTURE (API 34+) must be
62
+ * granted for the app in the AndroidManifest.xml
63
+ */
64
+ @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
65
+ @SuppressLint("MissingPermission")
66
+ private fun registerScreenCapture(activity: Activity) {
67
+ val context = activity.applicationContext
68
+ if (!hasPermission(context, SCREEN_CAPTURE_PERMISSION)) {
69
+ reportMissingPermission("screenshot", SCREEN_CAPTURE_PERMISSION)
70
+ return
71
+ }
72
+
73
+ activity.registerScreenCaptureCallback(context.mainExecutor, screenCaptureCallback)
74
+ }
75
+
76
+ /**
77
+ * Register Talsec Screen Recording Detector for given activity instance.
78
+ * The MainActivity of the app is registered by the plugin itself, other
79
+ * activities bust be registered manually as described in the integration guide.
80
+ *
81
+ * Missing permission is suppressed because the decision to use the screen
82
+ * capture API is made by developer, and not enforced by the library.
83
+ *
84
+ * **IMPORTANT**: android.permission.DETECT_SCREEN_RECORDING (API 35+) must be
85
+ * granted for the app in the AndroidManifest.xml
86
+ */
87
+ @SuppressLint("MissingPermission")
88
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
89
+ private fun registerScreenRecording(activity: Activity) {
90
+ val context = activity.applicationContext
91
+ if (!hasPermission(context, SCREEN_RECORDING_PERMISSION)) {
92
+ reportMissingPermission("screen record", SCREEN_RECORDING_PERMISSION)
93
+ return
94
+ }
95
+
96
+ val initialState = activity.windowManager.addScreenRecordingCallback(
97
+ context.mainExecutor, screenRecordCallback
98
+ )
99
+ screenRecordCallback.accept(initialState)
100
+
101
+ }
102
+
103
+ /**
104
+ * Unregisters screenshot and screen recording detector with the given activity
105
+ *
106
+ * **IMPORTANT**: android.permission.DETECT_SCREEN_CAPTURE and
107
+ * android.permission.DETECT_SCREEN_RECORDING must be
108
+ * granted for the app in the AndroidManifest.xml
109
+ */
110
+ @SuppressLint("MissingPermission")
111
+ @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
112
+ internal fun unregister(activity: Activity) {
113
+ if (!FreeraspReactNativeModule.talsecStarted || !registered) {
114
+ return
115
+ }
116
+
117
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
118
+ unregisterScreenCapture(activity)
119
+ }
120
+
121
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
122
+ unregisterScreenRecording(activity)
123
+ }
124
+ registered = false
125
+ }
126
+
127
+ // Missing permission is suppressed because the decision to use the screen capture API is made
128
+ // by developer, and not enforced by the library.
129
+ @SuppressLint("MissingPermission")
130
+ @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
131
+ private fun unregisterScreenCapture(activity: Activity) {
132
+ val context = activity.applicationContext
133
+ if (!hasPermission(context, SCREEN_CAPTURE_PERMISSION)) {
134
+ return
135
+ }
136
+ activity.unregisterScreenCaptureCallback(screenCaptureCallback)
137
+ }
138
+
139
+ // Missing permission is suppressed because the decision to use the screen capture API is made
140
+ // by developer, and not enforced by the library.
141
+ @SuppressLint("MissingPermission")
142
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
143
+ private fun unregisterScreenRecording(activity: Activity) {
144
+ val context = activity.applicationContext
145
+ if (!hasPermission(context, SCREEN_RECORDING_PERMISSION)) {
146
+ return
147
+ }
148
+
149
+ activity.windowManager?.removeScreenRecordingCallback(screenRecordCallback)
150
+ }
151
+
152
+ private fun hasPermission(context: Context, permission: String): Boolean {
153
+ return ContextCompat.checkSelfPermission(
154
+ context, permission
155
+ ) == PackageManager.PERMISSION_GRANTED
156
+ }
157
+
158
+ private fun reportMissingPermission(protectionType: String, permission: String) {
159
+ Log.e(
160
+ TAG,
161
+ "Failed to register $protectionType callback. Check if $permission permission is granted in AndroidManifest.xml"
162
+ )
163
+ }
164
+ }
@@ -25,6 +25,8 @@ internal sealed class Threat(val value: Int) {
25
25
  object DevMode : Threat((10000..999999999).random())
26
26
  object Malware : Threat((10000..999999999).random())
27
27
  object ADBEnabled : Threat((10000..999999999).random())
28
+ object Screenshot : Threat((10000..999999999).random())
29
+ object ScreenRecording : Threat((10000..999999999).random())
28
30
 
29
31
  companion object {
30
32
  internal fun getThreatValues(): WritableArray {
@@ -43,7 +45,9 @@ internal sealed class Threat(val value: Int) {
43
45
  ObfuscationIssues.value,
44
46
  DevMode.value,
45
47
  Malware.value,
46
- ADBEnabled.value
48
+ ADBEnabled.value,
49
+ Screenshot.value,
50
+ ScreenRecording.value
47
51
  )
48
52
  )
49
53
  }
@@ -61,7 +61,7 @@ internal fun ReadableMap.getNestedArraySafe(key: String): Array<Array<String>> {
61
61
  if (this.hasKey(key)) {
62
62
  val inputArray = this.getArray(key)!!
63
63
  for (i in 0 until inputArray.size()) {
64
- outArray.add(inputArray.getArray(i).toPrimitiveArray())
64
+ inputArray.getArray(i)?.let { outArray.add(it.toPrimitiveArray()) }
65
65
  }
66
66
  }
67
67
  return outArray.toTypedArray()
package/example/Gemfile CHANGED
@@ -1,6 +1,10 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
4
- ruby '2.7.5'
4
+ ruby ">= 2.6.10"
5
5
 
6
- gem 'cocoapods', '~> 1.11', '>= 1.11.2'
6
+ # Exclude problematic versions of cocoapods and activesupport that causes build failures.
7
+ gem 'cocoapods', '>= 1.13', '!= 1.15.0', '!= 1.15.1'
8
+ gem 'activesupport', '>= 6.1.7.5', '!= 7.1.0'
9
+ gem 'xcodeproj', '< 1.26.0'
10
+ gem 'concurrent-ruby', '< 1.3.4'
@@ -0,0 +1,121 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ CFPropertyList (3.0.7)
5
+ base64
6
+ nkf
7
+ rexml
8
+ activesupport (7.1.5.1)
9
+ base64
10
+ benchmark (>= 0.3)
11
+ bigdecimal
12
+ concurrent-ruby (~> 1.0, >= 1.0.2)
13
+ connection_pool (>= 2.2.5)
14
+ drb
15
+ i18n (>= 1.6, < 2)
16
+ logger (>= 1.4.2)
17
+ minitest (>= 5.1)
18
+ mutex_m
19
+ securerandom (>= 0.3)
20
+ tzinfo (~> 2.0)
21
+ addressable (2.8.7)
22
+ public_suffix (>= 2.0.2, < 7.0)
23
+ algoliasearch (1.27.5)
24
+ httpclient (~> 2.8, >= 2.8.3)
25
+ json (>= 1.5.1)
26
+ atomos (0.1.3)
27
+ base64 (0.2.0)
28
+ benchmark (0.4.0)
29
+ bigdecimal (3.1.9)
30
+ claide (1.1.0)
31
+ cocoapods (1.15.2)
32
+ addressable (~> 2.8)
33
+ claide (>= 1.0.2, < 2.0)
34
+ cocoapods-core (= 1.15.2)
35
+ cocoapods-deintegrate (>= 1.0.3, < 2.0)
36
+ cocoapods-downloader (>= 2.1, < 3.0)
37
+ cocoapods-plugins (>= 1.0.0, < 2.0)
38
+ cocoapods-search (>= 1.0.0, < 2.0)
39
+ cocoapods-trunk (>= 1.6.0, < 2.0)
40
+ cocoapods-try (>= 1.1.0, < 2.0)
41
+ colored2 (~> 3.1)
42
+ escape (~> 0.0.4)
43
+ fourflusher (>= 2.3.0, < 3.0)
44
+ gh_inspector (~> 1.0)
45
+ molinillo (~> 0.8.0)
46
+ nap (~> 1.0)
47
+ ruby-macho (>= 2.3.0, < 3.0)
48
+ xcodeproj (>= 1.23.0, < 2.0)
49
+ cocoapods-core (1.15.2)
50
+ activesupport (>= 5.0, < 8)
51
+ addressable (~> 2.8)
52
+ algoliasearch (~> 1.0)
53
+ concurrent-ruby (~> 1.1)
54
+ fuzzy_match (~> 2.0.4)
55
+ nap (~> 1.0)
56
+ netrc (~> 0.11)
57
+ public_suffix (~> 4.0)
58
+ typhoeus (~> 1.0)
59
+ cocoapods-deintegrate (1.0.5)
60
+ cocoapods-downloader (2.1)
61
+ cocoapods-plugins (1.0.0)
62
+ nap
63
+ cocoapods-search (1.0.1)
64
+ cocoapods-trunk (1.6.0)
65
+ nap (>= 0.8, < 2.0)
66
+ netrc (~> 0.11)
67
+ cocoapods-try (1.2.0)
68
+ colored2 (3.1.2)
69
+ concurrent-ruby (1.3.3)
70
+ connection_pool (2.5.0)
71
+ drb (2.2.1)
72
+ escape (0.0.4)
73
+ ethon (0.16.0)
74
+ ffi (>= 1.15.0)
75
+ ffi (1.17.1)
76
+ fourflusher (2.3.1)
77
+ fuzzy_match (2.0.4)
78
+ gh_inspector (1.1.3)
79
+ httpclient (2.9.0)
80
+ mutex_m
81
+ i18n (1.14.7)
82
+ concurrent-ruby (~> 1.0)
83
+ json (2.10.1)
84
+ logger (1.6.6)
85
+ minitest (5.25.4)
86
+ molinillo (0.8.0)
87
+ mutex_m (0.3.0)
88
+ nanaimo (0.3.0)
89
+ nap (1.1.0)
90
+ netrc (0.11.0)
91
+ nkf (0.2.0)
92
+ public_suffix (4.0.7)
93
+ rexml (3.4.1)
94
+ ruby-macho (2.5.1)
95
+ securerandom (0.3.2)
96
+ typhoeus (1.4.1)
97
+ ethon (>= 0.9.0)
98
+ tzinfo (2.0.6)
99
+ concurrent-ruby (~> 1.0)
100
+ xcodeproj (1.25.1)
101
+ CFPropertyList (>= 2.3.3, < 4.0)
102
+ atomos (~> 0.1.3)
103
+ claide (>= 1.0.2, < 2.0)
104
+ colored2 (~> 3.1)
105
+ nanaimo (~> 0.3.0)
106
+ rexml (>= 3.3.6, < 4.0)
107
+
108
+ PLATFORMS
109
+ ruby
110
+
111
+ DEPENDENCIES
112
+ activesupport (>= 6.1.7.5, != 7.1.0)
113
+ cocoapods (>= 1.13, != 1.15.1, != 1.15.0)
114
+ concurrent-ruby (< 1.3.4)
115
+ xcodeproj (< 1.26.0)
116
+
117
+ RUBY VERSION
118
+ ruby 2.7.6p219
119
+
120
+ BUNDLED WITH
121
+ 2.1.4