freerasp-react-native 3.4.0 → 3.6.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.
- package/README.md +13 -19
- package/android/build.gradle +3 -2
- package/android/gradle.properties +2 -1
- package/android/src/main/java/com/freeraspreactnative/FreeraspReactNativeModule.kt +58 -48
- package/android/src/main/java/com/freeraspreactnative/FreeraspThreatHandler.kt +52 -0
- package/android/src/main/java/com/freeraspreactnative/Threat.kt +44 -0
- package/ios/FreeraspReactNative.m +8 -1
- package/ios/FreeraspReactNative.swift +82 -13
- package/ios/TalsecRuntime.xcframework/Info.plist +5 -5
- package/ios/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/CurlWrapper.h +1 -1
- package/ios/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/TalsecRuntime-Swift.h +2 -2
- package/ios/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Info.plist +0 -0
- package/ios/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios.abi.json +142 -160
- package/ios/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios.private.swiftinterface +3 -2
- package/ios/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios.swiftdoc +0 -0
- package/ios/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios.swiftinterface +3 -2
- package/ios/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/TalsecRuntime +0 -0
- package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/CurlWrapper.h +1 -1
- package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/TalsecRuntime-Swift.h +4 -4
- package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Info.plist +0 -0
- package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.abi.json +142 -160
- package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface +3 -2
- package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.swiftdoc +0 -0
- package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.swiftinterface +3 -2
- package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.abi.json +142 -160
- package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface +3 -2
- package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.swiftdoc +0 -0
- package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.swiftinterface +3 -2
- package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/TalsecRuntime +0 -0
- package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/_CodeSignature/CodeResources +25 -25
- package/lib/commonjs/definitions.js +32 -0
- package/lib/commonjs/definitions.js.map +1 -0
- package/lib/commonjs/index.js +83 -20
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/utils.js +16 -0
- package/lib/commonjs/utils.js.map +1 -0
- package/lib/module/definitions.js +25 -0
- package/lib/module/definitions.js.map +1 -0
- package/lib/module/index.js +84 -21
- package/lib/module/index.js.map +1 -1
- package/lib/module/utils.js +8 -0
- package/lib/module/utils.js.map +1 -0
- package/lib/typescript/definitions.d.ts +43 -0
- package/lib/typescript/definitions.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +3 -32
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/utils.d.ts +3 -0
- package/lib/typescript/utils.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/definitions.ts +77 -0
- package/src/index.tsx +93 -60
- package/src/utils.ts +9 -0
- package/android/src/main/java/com/freeraspreactnative/FreeraspDeviceStateListener.kt +0 -25
package/README.md
CHANGED
|
@@ -9,7 +9,6 @@ freeRASP for React Native is a mobile in-app protection and security monitoring
|
|
|
9
9
|
# :notebook_with_decorative_cover: Table of contents
|
|
10
10
|
|
|
11
11
|
- [Overview](#overview)
|
|
12
|
-
- [Requirements](#requirements)
|
|
13
12
|
- [Usage](#usage)
|
|
14
13
|
- [(Optional) Create a new React Native demo application](#optional-create-a-new-react-native-demo-application)
|
|
15
14
|
- [Step 1: Install the plugin](#step-1-install-the-plugin)
|
|
@@ -65,13 +64,6 @@ Learn more about commercial features at [https://talsec.app](https://talsec.app)
|
|
|
65
64
|
|
|
66
65
|
Learn more about freemium freeRASP features at [GitHub main repository](https://github.com/talsec/Free-RASP-Community).
|
|
67
66
|
|
|
68
|
-
# Requirements
|
|
69
|
-
|
|
70
|
-
Following minimal version requirements have to be met
|
|
71
|
-
in order to run freeRASP in your app:
|
|
72
|
-
|
|
73
|
-
- `react-native` >= `0.65.3`
|
|
74
|
-
|
|
75
67
|
# Usage
|
|
76
68
|
|
|
77
69
|
We will guide you step-by-step, but you can always check the expected result in the example folder.
|
|
@@ -164,7 +156,7 @@ const config = {
|
|
|
164
156
|
|
|
165
157
|
- `packageName` _: string_ - package name of your app you chose when you created it
|
|
166
158
|
- `certificateHashes` _: string[]_ - hash of the certificate of the key which was used to sign the application. **Hash which is passed here must be encoded in Base64 form.** If you are not sure how to get your certificate hash, you can check out the guide on our [Github wiki](https://github.com/talsec/Free-RASP-Community/wiki/Getting-your-signing-certificate-hash-of-app). Multiple hashes are supported, e.g. if you are using a different one for the Huawei App Gallery.
|
|
167
|
-
- `supportedAlternativeStores` _: string[] | undefined_ - Google Play Store and Huawei AppGallery are supported out of the box, you **don't have to assign anything**. You can add other stores like the Samsung Galaxy Store in the example code (
|
|
159
|
+
- `supportedAlternativeStores` _: string[] | undefined_ - Google Play Store and Huawei AppGallery are supported out of the box, you **don't have to assign anything**. You can add other stores like the Samsung Galaxy Store in the example code (`com.sec.android.app.samsungapps`). For more information, visit the [Detecting Unofficial Installation](https://github.com/talsec/Free-RASP-Community/wiki/Threat-detection#detecting-unofficial-installation) wiki page.
|
|
168
160
|
|
|
169
161
|
1. `iosConfig` _: object | undefined_ - required for iOS devices, has following keys:
|
|
170
162
|
- `appBundleId` _: string_ - Bundle ID of your app
|
|
@@ -387,12 +379,14 @@ To receive Security Reports, fill out the _watcherMail_ field in [config](#confi
|
|
|
387
379
|
|
|
388
380
|

|
|
389
381
|
|
|
390
|
-
# :money_with_wings: Talsec Commercial Subscriptions
|
|
382
|
+
# :money_with_wings: Talsec Commercial Subscriptions
|
|
383
|
+
|
|
391
384
|
Talsec offers commercial plans on top of freeRASP (Business RASP+):
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
385
|
+
|
|
386
|
+
- No limits of Fair Usage Policy (100K App Downloads)
|
|
387
|
+
- No Data Collection from your app
|
|
388
|
+
- FinTech grade security, features and SLA (see more in [this post](https://github.com/orgs/talsec/discussions/5))
|
|
389
|
+
- Protect APIs and risk scoring by AppiCrypt®
|
|
396
390
|
|
|
397
391
|
Learn more at [talsec.app](https://talsec.app).
|
|
398
392
|
|
|
@@ -400,11 +394,11 @@ Not to overlook, the one of the most valued commercial features is [AppiCrypt®]
|
|
|
400
394
|
|
|
401
395
|
It allows easy-to-implement API protection and App Integrity verification on the backend to prevent API abuse:
|
|
402
396
|
|
|
403
|
-
-
|
|
404
|
-
-
|
|
405
|
-
-
|
|
406
|
-
-
|
|
407
|
-
-
|
|
397
|
+
- Bruteforce attacks
|
|
398
|
+
- Botnets
|
|
399
|
+
- API abuse by App impersonation
|
|
400
|
+
- Session-hijacking
|
|
401
|
+
- DDoS
|
|
408
402
|
|
|
409
403
|
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).
|
|
410
404
|
|
package/android/build.gradle
CHANGED
|
@@ -78,14 +78,15 @@ rootProject.allprojects {
|
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
def kotlin_version = getExtOrDefault("kotlinVersion")
|
|
81
|
+
def react_native_version = getExtOrDefault("reactNativeVersion")
|
|
81
82
|
|
|
82
83
|
dependencies {
|
|
83
84
|
// For < 0.71, this will be from the local maven repo
|
|
84
85
|
// For > 0.71, this will be replaced by `com.facebook.react:react-android:$version` by react gradle plugin
|
|
85
86
|
//noinspection GradleDynamicVersion
|
|
86
|
-
implementation "com.facebook.react:react-native"
|
|
87
|
+
implementation "com.facebook.react:react-native:$react_native_version"
|
|
87
88
|
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
|
88
|
-
implementation "com.aheaditec.talsec.security:TalsecSecurity-Community-ReactNative:
|
|
89
|
+
implementation "com.aheaditec.talsec.security:TalsecSecurity-Community-ReactNative:9.0.0"
|
|
89
90
|
}
|
|
90
91
|
|
|
91
92
|
if (isNewArchitectureEnabled()) {
|
|
@@ -2,4 +2,5 @@ FreeraspReactNative_kotlinVersion=1.7.0
|
|
|
2
2
|
FreeraspReactNative_minSdkVersion=23
|
|
3
3
|
FreeraspReactNative_targetSdkVersion=31
|
|
4
4
|
FreeraspReactNative_compileSdkVersion=33
|
|
5
|
-
FreeraspReactNative_ndkversion=21.4.7075529
|
|
5
|
+
FreeraspReactNative_ndkversion=21.4.7075529
|
|
6
|
+
FreeraspReactNative_reactNativeVersion=+
|
|
@@ -4,93 +4,85 @@ import com.aheaditec.talsec_security.security.api.Talsec
|
|
|
4
4
|
import com.aheaditec.talsec_security.security.api.TalsecConfig
|
|
5
5
|
import com.aheaditec.talsec_security.security.api.ThreatListener
|
|
6
6
|
import com.facebook.react.bridge.Arguments
|
|
7
|
+
import com.facebook.react.bridge.Promise
|
|
7
8
|
import com.facebook.react.bridge.ReactApplicationContext
|
|
8
9
|
import com.facebook.react.bridge.ReactContextBaseJavaModule
|
|
9
10
|
import com.facebook.react.bridge.ReactMethod
|
|
10
|
-
import com.facebook.react.bridge.WritableMap
|
|
11
11
|
import com.facebook.react.bridge.ReadableMap
|
|
12
|
+
import com.facebook.react.bridge.WritableArray
|
|
12
13
|
import com.facebook.react.modules.core.DeviceEventManagerModule
|
|
13
14
|
|
|
14
15
|
class FreeraspReactNativeModule(val reactContext: ReactApplicationContext) :
|
|
15
|
-
ReactContextBaseJavaModule(reactContext)
|
|
16
|
-
FreeraspDeviceStateListener.DeviceStateListener {
|
|
16
|
+
ReactContextBaseJavaModule(reactContext) {
|
|
17
17
|
|
|
18
|
-
private val listener = ThreatListener(
|
|
18
|
+
private val listener = ThreatListener(FreeraspThreatHandler, FreeraspThreatHandler)
|
|
19
19
|
|
|
20
20
|
override fun getName(): String {
|
|
21
21
|
return NAME
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
init {
|
|
25
|
+
appReactContext = reactContext
|
|
26
|
+
}
|
|
27
|
+
|
|
24
28
|
@ReactMethod
|
|
25
29
|
fun talsecStart(
|
|
26
|
-
options: ReadableMap
|
|
30
|
+
options: ReadableMap,
|
|
31
|
+
promise: Promise
|
|
27
32
|
) {
|
|
28
33
|
|
|
29
34
|
try {
|
|
30
35
|
val config = parseTalsecConfig(options)
|
|
31
|
-
|
|
36
|
+
FreeraspThreatHandler.listener = ThreatListener
|
|
32
37
|
listener.registerListener(reactContext)
|
|
33
38
|
Talsec.start(reactContext, config)
|
|
34
|
-
|
|
39
|
+
promise.resolve("freeRASP started")
|
|
35
40
|
|
|
36
41
|
} catch (e: Exception) {
|
|
37
42
|
val params = Arguments.createMap().apply {
|
|
38
43
|
putString("message", e.message)
|
|
39
44
|
}
|
|
40
|
-
|
|
45
|
+
promise.reject("initializationError", params)
|
|
41
46
|
}
|
|
42
47
|
}
|
|
43
48
|
|
|
49
|
+
/**
|
|
50
|
+
* Method to get the random identifiers of callbacks
|
|
51
|
+
*/
|
|
44
52
|
@ReactMethod
|
|
45
|
-
fun
|
|
46
|
-
|
|
53
|
+
fun getThreatIdentifiers(promise: Promise) {
|
|
54
|
+
promise.resolve(Threat.getThreatValues())
|
|
47
55
|
}
|
|
48
56
|
|
|
57
|
+
/**
|
|
58
|
+
* Method to setup the message passing between native and React Native
|
|
59
|
+
* @return list of [THREAT_CHANNEL_NAME, THREAT_CHANNEL_KEY]
|
|
60
|
+
*/
|
|
49
61
|
@ReactMethod
|
|
50
|
-
fun
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
sendOngoingPluginResult("privilegedAccess", null)
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
override fun onDebuggerDetected() {
|
|
59
|
-
sendOngoingPluginResult("debug", null)
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
override fun onEmulatorDetected() {
|
|
63
|
-
sendOngoingPluginResult("simulator", null)
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
override fun onTamperDetected() {
|
|
67
|
-
sendOngoingPluginResult("appIntegrity", null)
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
override fun onUntrustedInstallationSourceDetected() {
|
|
71
|
-
sendOngoingPluginResult("unofficialStore", null)
|
|
62
|
+
fun getThreatChannelData(promise: Promise) {
|
|
63
|
+
val channelData: WritableArray = Arguments.createArray()
|
|
64
|
+
channelData.pushString(THREAT_CHANNEL_NAME)
|
|
65
|
+
channelData.pushString(THREAT_CHANNEL_KEY)
|
|
66
|
+
promise.resolve(channelData)
|
|
72
67
|
}
|
|
73
68
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
override fun onObfuscationIssuesDetected() {
|
|
83
|
-
sendOngoingPluginResult("obfuscationIssues", null)
|
|
69
|
+
/**
|
|
70
|
+
* We never send an invalid callback over our channel.
|
|
71
|
+
* Therefore, if this happens, we want to kill the app.
|
|
72
|
+
*/
|
|
73
|
+
@ReactMethod
|
|
74
|
+
fun onInvalidCallback() {
|
|
75
|
+
android.os.Process.killProcess(android.os.Process.myPid())
|
|
84
76
|
}
|
|
85
77
|
|
|
86
|
-
|
|
87
|
-
|
|
78
|
+
@ReactMethod
|
|
79
|
+
fun addListener(@Suppress("UNUSED_PARAMETER") eventName: String) {
|
|
80
|
+
// Set up any upstream listeners or background tasks as necessary
|
|
88
81
|
}
|
|
89
82
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
.emit(eventName, params)
|
|
83
|
+
@ReactMethod
|
|
84
|
+
fun removeListeners(@Suppress("UNUSED_PARAMETER") count: Int) {
|
|
85
|
+
// Remove upstream listeners, stop unnecessary background tasks
|
|
94
86
|
}
|
|
95
87
|
|
|
96
88
|
private fun parseTalsecConfig(config: ReadableMap): TalsecConfig {
|
|
@@ -125,5 +117,23 @@ class FreeraspReactNativeModule(val reactContext: ReactApplicationContext) :
|
|
|
125
117
|
|
|
126
118
|
companion object {
|
|
127
119
|
const val NAME = "FreeraspReactNative"
|
|
120
|
+
val THREAT_CHANNEL_NAME = (10000..999999999).random()
|
|
121
|
+
.toString() // name of the channel over which threat callbacks are sent
|
|
122
|
+
val THREAT_CHANNEL_KEY = (10000..999999999).random()
|
|
123
|
+
.toString() // key of the argument map under which threats are expected
|
|
124
|
+
private lateinit var appReactContext: ReactApplicationContext
|
|
125
|
+
private fun notifyListeners(threat: Threat) {
|
|
126
|
+
val params = Arguments.createMap()
|
|
127
|
+
params.putInt(THREAT_CHANNEL_KEY, threat.value)
|
|
128
|
+
appReactContext
|
|
129
|
+
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
130
|
+
.emit(THREAT_CHANNEL_NAME, params)
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
internal object ThreatListener : FreeraspThreatHandler.TalsecReactNative {
|
|
135
|
+
override fun threatDetected(threatType: Threat) {
|
|
136
|
+
notifyListeners(threatType)
|
|
137
|
+
}
|
|
128
138
|
}
|
|
129
139
|
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
package com.freeraspreactnative
|
|
2
|
+
|
|
3
|
+
import com.aheaditec.talsec_security.security.api.ThreatListener
|
|
4
|
+
|
|
5
|
+
internal object FreeraspThreatHandler : ThreatListener.ThreatDetected, ThreatListener.DeviceState {
|
|
6
|
+
|
|
7
|
+
internal var listener: TalsecReactNative? = null
|
|
8
|
+
|
|
9
|
+
override fun onRootDetected() {
|
|
10
|
+
listener?.threatDetected(Threat.PrivilegedAccess)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
override fun onDebuggerDetected() {
|
|
14
|
+
listener?.threatDetected(Threat.Debug)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
override fun onEmulatorDetected() {
|
|
18
|
+
listener?.threatDetected(Threat.Simulator)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
override fun onTamperDetected() {
|
|
22
|
+
listener?.threatDetected(Threat.AppIntegrity)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
override fun onUntrustedInstallationSourceDetected() {
|
|
26
|
+
listener?.threatDetected(Threat.UnofficialStore)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
override fun onHookDetected() {
|
|
30
|
+
listener?.threatDetected(Threat.Hooks)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
override fun onDeviceBindingDetected() {
|
|
34
|
+
listener?.threatDetected(Threat.DeviceBinding)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
override fun onObfuscationIssuesDetected() {
|
|
38
|
+
listener?.threatDetected(Threat.ObfuscationIssues)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
override fun onUnlockedDeviceDetected() {
|
|
42
|
+
listener?.threatDetected(Threat.Passcode)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
override fun onHardwareBackedKeystoreNotAvailableDetected() {
|
|
46
|
+
listener?.threatDetected(Threat.SecureHardwareNotAvailable)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
internal interface TalsecReactNative {
|
|
50
|
+
fun threatDetected(threatType: Threat)
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
package com.freeraspreactnative
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.Arguments
|
|
4
|
+
import com.facebook.react.bridge.WritableArray
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Sealed class to represent the error codes.
|
|
8
|
+
*
|
|
9
|
+
* Sealed classes are used because of obfuscation - enums classes are not obfuscated well enough.
|
|
10
|
+
*
|
|
11
|
+
* @property value integer value of the error code.
|
|
12
|
+
*/
|
|
13
|
+
internal sealed class Threat(val value: Int) {
|
|
14
|
+
object AppIntegrity : Threat((10000..999999999).random())
|
|
15
|
+
object PrivilegedAccess : Threat((10000..999999999).random())
|
|
16
|
+
object Debug : Threat((10000..999999999).random())
|
|
17
|
+
object Hooks : Threat((10000..999999999).random())
|
|
18
|
+
object Passcode : Threat((10000..999999999).random())
|
|
19
|
+
object Simulator : Threat((10000..999999999).random())
|
|
20
|
+
object SecureHardwareNotAvailable : Threat((10000..999999999).random())
|
|
21
|
+
object DeviceBinding : Threat((10000..999999999).random())
|
|
22
|
+
object UnofficialStore : Threat((10000..999999999).random())
|
|
23
|
+
object ObfuscationIssues : Threat((10000..999999999).random())
|
|
24
|
+
|
|
25
|
+
companion object {
|
|
26
|
+
internal fun getThreatValues(): WritableArray {
|
|
27
|
+
return Arguments.fromList(
|
|
28
|
+
listOf(
|
|
29
|
+
AppIntegrity.value,
|
|
30
|
+
PrivilegedAccess.value,
|
|
31
|
+
Debug.value,
|
|
32
|
+
Hooks.value,
|
|
33
|
+
Passcode.value,
|
|
34
|
+
Simulator.value,
|
|
35
|
+
SecureHardwareNotAvailable.value,
|
|
36
|
+
DeviceBinding.value,
|
|
37
|
+
UnofficialStore.value,
|
|
38
|
+
ObfuscationIssues.value
|
|
39
|
+
)
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -4,7 +4,14 @@
|
|
|
4
4
|
|
|
5
5
|
@interface RCT_EXTERN_MODULE(FreeraspReactNative, RCTEventEmitter)
|
|
6
6
|
|
|
7
|
-
RCT_EXTERN_METHOD(talsecStart:(NSDictionary*)options
|
|
7
|
+
RCT_EXTERN_METHOD(talsecStart:(NSDictionary*)options
|
|
8
|
+
withResolver:(RCTPromiseResolveBlock)resolve
|
|
9
|
+
withRejecter:(RCTPromiseRejectBlock)reject)
|
|
10
|
+
RCT_EXTERN_METHOD(getThreatChannelData:(RCTPromiseResolveBlock)resolve
|
|
11
|
+
withRejecter:(RCTPromiseRejectBlock)reject)
|
|
12
|
+
RCT_EXTERN_METHOD(getThreatIdentifiers:(RCTPromiseResolveBlock)resolve
|
|
13
|
+
withRejecter:(RCTPromiseRejectBlock)reject)
|
|
14
|
+
RCT_EXTERN_METHOD(onInvalidCallback)
|
|
8
15
|
|
|
9
16
|
+ (BOOL)requiresMainQueueSetup
|
|
10
17
|
{
|
|
@@ -5,22 +5,26 @@ import TalsecRuntime
|
|
|
5
5
|
class FreeraspReactNative: RCTEventEmitter {
|
|
6
6
|
|
|
7
7
|
public static var shared:FreeraspReactNative?
|
|
8
|
+
|
|
9
|
+
let threatChannelKey = String(Int.random(in: 100_000..<999_999_999)) // key of the argument map under which threats are expected
|
|
10
|
+
let threatChannelName = String(Int.random(in: 100_000..<999_999_999)) // name of the channel over which threat callbacks are sent
|
|
11
|
+
let threatIdentifierList = (1...12).map { _ in Int.random(in: 100_000..<999_999_999) }
|
|
8
12
|
|
|
9
13
|
override init() {
|
|
10
14
|
super.init()
|
|
11
15
|
FreeraspReactNative.shared = self
|
|
12
16
|
}
|
|
13
17
|
|
|
14
|
-
@objc(talsecStart:)
|
|
15
|
-
func talsecStart(options: NSDictionary) -> Void {
|
|
18
|
+
@objc(talsecStart:withResolver:withRejecter:)
|
|
19
|
+
func talsecStart(options: NSDictionary, resolve: RCTPromiseResolveBlock, rejecter reject: RCTPromiseRejectBlock) -> Void {
|
|
16
20
|
do {
|
|
17
21
|
try initializeTalsec(talsecConfig: options)
|
|
18
22
|
}
|
|
19
23
|
catch let error as NSError {
|
|
20
|
-
|
|
24
|
+
reject("initialization_error", "Could not initialize freeRASP", error)
|
|
21
25
|
return
|
|
22
26
|
}
|
|
23
|
-
|
|
27
|
+
resolve("freeRASP started")
|
|
24
28
|
}
|
|
25
29
|
|
|
26
30
|
func initializeTalsec(talsecConfig: NSDictionary) throws {
|
|
@@ -41,25 +45,90 @@ class FreeraspReactNative: RCTEventEmitter {
|
|
|
41
45
|
let config = TalsecConfig(appBundleIds: [appBundleIds], appTeamId: appTeamId, watcherMailAddress: watcherMailAddress, isProd: isProd)
|
|
42
46
|
Talsec.start(config: config)
|
|
43
47
|
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Method to setup the message passing between native and React Native
|
|
51
|
+
*/
|
|
52
|
+
@objc(getThreatChannelData:withRejecter:)
|
|
53
|
+
private func getThreatChannelData(resolve: RCTPromiseResolveBlock, rejecter reject: RCTPromiseRejectBlock) -> Void {
|
|
54
|
+
resolve([threatChannelName, threatChannelKey])
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
func dispatchEvent(securityThreat: SecurityThreat) -> Void {
|
|
58
|
+
FreeraspReactNative.shared!.sendEvent(withName: threatChannelName, body: [threatChannelKey: securityThreat.callbackIdentifier])
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Method to get the random identifiers of callbacks
|
|
63
|
+
*/
|
|
64
|
+
@objc(getThreatIdentifiers:withRejecter:)
|
|
65
|
+
private func getThreatIdentifiers(resolve: RCTPromiseResolveBlock, rejecter reject: RCTPromiseRejectBlock) -> Void {
|
|
66
|
+
resolve(getThreatIdentifiers())
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* We never send an invalid callback over our channel.
|
|
71
|
+
* Therefore, if this happens, we want to kill the app.
|
|
72
|
+
*/
|
|
73
|
+
@objc(onInvalidCallback)
|
|
74
|
+
private func onInvalidCallback() -> Void {
|
|
75
|
+
abort()
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
private func getThreatIdentifiers() -> [Int] {
|
|
79
|
+
return SecurityThreat.allCases
|
|
80
|
+
.filter {
|
|
81
|
+
threat in threat.rawValue != "passcodeChange"
|
|
82
|
+
}
|
|
83
|
+
.map {
|
|
84
|
+
threat in threat.callbackIdentifier
|
|
85
|
+
}
|
|
86
|
+
}
|
|
44
87
|
|
|
45
88
|
override func supportedEvents() -> [String]! {
|
|
46
|
-
return [
|
|
89
|
+
return [threatChannelName]
|
|
47
90
|
}
|
|
48
91
|
}
|
|
49
92
|
|
|
50
|
-
extension
|
|
93
|
+
/// An extension to unify callback names with RN ones.
|
|
94
|
+
extension SecurityThreat {
|
|
51
95
|
|
|
96
|
+
var callbackIdentifier: Int {
|
|
97
|
+
switch self {
|
|
98
|
+
case .signature:
|
|
99
|
+
return FreeraspReactNative.shared!.threatIdentifierList[0]
|
|
100
|
+
case .jailbreak:
|
|
101
|
+
return FreeraspReactNative.shared!.threatIdentifierList[1]
|
|
102
|
+
case .debugger:
|
|
103
|
+
return FreeraspReactNative.shared!.threatIdentifierList[2]
|
|
104
|
+
case .runtimeManipulation:
|
|
105
|
+
return FreeraspReactNative.shared!.threatIdentifierList[3]
|
|
106
|
+
case .passcode:
|
|
107
|
+
return FreeraspReactNative.shared!.threatIdentifierList[4]
|
|
108
|
+
case .passcodeChange:
|
|
109
|
+
return FreeraspReactNative.shared!.threatIdentifierList[5]
|
|
110
|
+
case .simulator:
|
|
111
|
+
return FreeraspReactNative.shared!.threatIdentifierList[6]
|
|
112
|
+
case .missingSecureEnclave:
|
|
113
|
+
return FreeraspReactNative.shared!.threatIdentifierList[7]
|
|
114
|
+
case .deviceChange:
|
|
115
|
+
return FreeraspReactNative.shared!.threatIdentifierList[8]
|
|
116
|
+
case .deviceID:
|
|
117
|
+
return FreeraspReactNative.shared!.threatIdentifierList[9]
|
|
118
|
+
case .unofficialStore:
|
|
119
|
+
return FreeraspReactNative.shared!.threatIdentifierList[10]
|
|
120
|
+
@unknown default:
|
|
121
|
+
abort()
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
52
125
|
|
|
53
|
-
|
|
54
|
-
"missingSecureEnclave": "secureHardwareNotAvailable",
|
|
55
|
-
"device binding": "deviceBinding",
|
|
56
|
-
]
|
|
126
|
+
extension SecurityThreatCenter: SecurityThreatHandler {
|
|
57
127
|
|
|
58
128
|
public func threatDetected(_ securityThreat: TalsecRuntime.SecurityThreat) {
|
|
59
|
-
|
|
60
|
-
if (threatName == "passcodeChange") {
|
|
129
|
+
if (securityThreat.rawValue == "passcodeChange") {
|
|
61
130
|
return
|
|
62
131
|
}
|
|
63
|
-
FreeraspReactNative.shared!.
|
|
132
|
+
FreeraspReactNative.shared!.dispatchEvent(securityThreat: securityThreat)
|
|
64
133
|
}
|
|
65
134
|
}
|
|
@@ -6,30 +6,30 @@
|
|
|
6
6
|
<array>
|
|
7
7
|
<dict>
|
|
8
8
|
<key>LibraryIdentifier</key>
|
|
9
|
-
<string>ios-
|
|
9
|
+
<string>ios-arm64</string>
|
|
10
10
|
<key>LibraryPath</key>
|
|
11
11
|
<string>TalsecRuntime.framework</string>
|
|
12
12
|
<key>SupportedArchitectures</key>
|
|
13
13
|
<array>
|
|
14
14
|
<string>arm64</string>
|
|
15
|
-
<string>x86_64</string>
|
|
16
15
|
</array>
|
|
17
16
|
<key>SupportedPlatform</key>
|
|
18
17
|
<string>ios</string>
|
|
19
|
-
<key>SupportedPlatformVariant</key>
|
|
20
|
-
<string>simulator</string>
|
|
21
18
|
</dict>
|
|
22
19
|
<dict>
|
|
23
20
|
<key>LibraryIdentifier</key>
|
|
24
|
-
<string>ios-
|
|
21
|
+
<string>ios-arm64_x86_64-simulator</string>
|
|
25
22
|
<key>LibraryPath</key>
|
|
26
23
|
<string>TalsecRuntime.framework</string>
|
|
27
24
|
<key>SupportedArchitectures</key>
|
|
28
25
|
<array>
|
|
29
26
|
<string>arm64</string>
|
|
27
|
+
<string>x86_64</string>
|
|
30
28
|
</array>
|
|
31
29
|
<key>SupportedPlatform</key>
|
|
32
30
|
<string>ios</string>
|
|
31
|
+
<key>SupportedPlatformVariant</key>
|
|
32
|
+
<string>simulator</string>
|
|
33
33
|
</dict>
|
|
34
34
|
</array>
|
|
35
35
|
<key>CFBundlePackageType</key>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#if 0
|
|
2
2
|
#elif defined(__arm64__) && __arm64__
|
|
3
|
-
// Generated by Apple Swift version 5.8 (swiftlang-5.8.0.124.
|
|
3
|
+
// Generated by Apple Swift version 5.8.1 (swiftlang-5.8.0.124.5 clang-1403.0.22.11.100)
|
|
4
4
|
#ifndef TALSECRUNTIME_SWIFT_H
|
|
5
5
|
#define TALSECRUNTIME_SWIFT_H
|
|
6
6
|
#pragma clang diagnostic push
|
|
@@ -281,7 +281,7 @@ typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4)));
|
|
|
281
281
|
|
|
282
282
|
#if defined(__OBJC__)
|
|
283
283
|
|
|
284
|
-
SWIFT_EXTERN void
|
|
284
|
+
SWIFT_EXTERN void __FlQXVgtWTdusubZZgVYGfrP(void);
|
|
285
285
|
|
|
286
286
|
#endif
|
|
287
287
|
#if defined(__cplusplus)
|