Skip to content

Commit 0d2fa8b

Browse files
authored
Merge pull request #12 from talsec/freerasp_2.0
Merge debug and release on iOS
2 parents 9906eb9 + ddecd97 commit 0d2fa8b

File tree

100 files changed

+164
-16832
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

100 files changed

+164
-16832
lines changed

README.md

Lines changed: 66 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,10 @@ freeRASP for React Native is a mobile in-app protection and security monitoring
1414
- [(Optional) Create a new React Native demo application](#optional-create-a-new-react-native-demo-application)
1515
- [Step 1: Install the plugin](#step-1-install-the-plugin)
1616
- [Step 2: Set up the dependencies](#step-2-set-up-the-dependencies)
17-
- [Step 3: Dev vs Release version](#step-3-dev-vs-release-version)
18-
- [Step 4: Import freeRASP into the app](#step-4-import-freerasp-into-the-app)
19-
- [Step 5: Setup the configuration, callbacks and initialize freeRASP](#step-5-setup-the-configuration-callbacks-and-initialize-freerasp)
20-
- [Step 6: Additional note about obfuscation](#step-6-additional-note-about-obfuscation)
21-
- [Step 7: User Data Policies](#step-7-user-data-policies)
17+
- [Step 3: Import freeRASP into the app](#step-3-import-freerasp-into-the-app)
18+
- [Step 4: Setup the configuration, callbacks and initialize freeRASP](#step-4-setup-the-configuration-callbacks-and-initialize-freerasp)
19+
- [Step 5: Additional note about obfuscation](#step-5-additional-note-about-obfuscation)
20+
- [Step 6: User Data Policies](#step-6-user-data-policies)
2221
- [Security Report](#security-report)
2322
- [Enterprise Services](#bar_chart-enterprise-services)
2423
- [Commercial version](#commercial-version)
@@ -88,111 +87,29 @@ or
8887

8988
### Android
9089

91-
freeRASP needs to have access to the maven repository containing freeRASP. Add following lines into the `android/build.gradle` file, in the `allprojects.repositories` section:
92-
93-
```gradle
94-
allprojects {
95-
repositories {
96-
google()
97-
mavenCentral()
98-
... your repositories
99-
maven{url = uri("https://nexus3-public.monetplus.cz/repository/ahead-talsec-free-rasp")}
100-
maven{url = uri("https://developer.huawei.com/repo/")}
101-
maven{url = uri("https://jitpack.io")}
102-
}
103-
}
104-
```
90+
_All dependencies of freeRASP for Android are resolved automatically._
10591

10692
### iOS
10793

10894
freeRASP React Native plugin uses Pods. Navigate to the `ios` folder and run:
10995

11096
$ pod install
11197

112-
## Step 3: Dev vs Release version
113-
114-
The Dev version is used to not complicate the development process of the application, e.g. if you would implement killing of the application on the debugger callback. It disables some checks which won't be triggered during the development process:
115-
116-
- Emulator-usage (simulator)
117-
- Debugging (debug)
118-
- Signing (appIntegrity)
119-
- Unofficial store (unofficialStore)
120-
121-
Which version of freeRASP is used is tied to the application's development stage - more precisely, how the application is compiled.
122-
123-
### Android
124-
125-
Android implementation of the React Native plugin detects selected development stage and automatically applies the suitable version of the library.
126-
127-
- `npx react-native run-android` (debug) -> uses dev version of freeRASP
128-
- `npx react-native run-android --variant release` (release) -> uses release version of freeRASP
129-
130-
### iOS
131-
132-
For the iOS implemtation, it's neccesary to add script into the Xcode environment, that automatically switches between the library dev/release versions according to selected development stage. Then, it is necessary to embedd a symlink to correct TalsecRuntime.xcframework.
133-
134-
1. Add pre-built script for changing the Debug and Release versions of the framework:
135-
- Open up the **.xcworkspace** file
136-
- Go to **Product** -> **Scheme** -> **Edit Scheme...** -> **Build (dropdown arrow)** -> **Pre-actions**
137-
- Hit **+** and then **New Run Script Action**
138-
- Set **Provide build setting from** to your application
139-
- Copy-paste following script:
140-
```shell
141-
cd "${SRCROOT}/../node_modules/freerasp-react-native/ios"
142-
if [ "${CONFIGURATION}" = "Release" ]; then
143-
rm -rf ./TalsecRuntime.xcframework
144-
ln -s ./Release/TalsecRuntime.xcframework/ TalsecRuntime.xcframework
145-
else
146-
rm -rf ./TalsecRuntime.xcframework
147-
ln -s ./Debug/TalsecRuntime.xcframework/ TalsecRuntime.xcframework
148-
fi
149-
```
150-
- **Close**
151-
2. Add dependency on the symlink
152-
- Go to your **Target** -> **Build Phases** -> **Link Binary With Libraries**
153-
- Add dependency (drag & drop right after **libPods**) on the symlink on the following location:
154-
_AwesomeProject/node_modules/freerasp-react-native/ios/TalsecRuntime.xcframework_
155-
- If there is no symlink, try to create it manually in that folder by the following command:
156-
- $ ln -s ./Debug/TalsecRuntime.xcframework/ TalsecRuntime.xcframework
157-
158-
Followingly:
159-
160-
- `npx react-native run-ios` (debug) -> uses dev version of freeRASP
161-
- `npx react-native run-ios --configuration Release` (release) -> uses release version of freeRASP
162-
163-
## Step 4: Import freeRASP into the app
98+
## Step 3: Import freeRASP into the app
16499

165100
We provide a custom hook that handles all required logic as registration of freeRASP, mounting and unmounting of listeners for you. Import the hook into your app:
166101

167102
```ts
168103
import { useFreeRasp } from 'freerasp-react-native';
169104
```
170105

171-
## Step 5: Setup the configuration, callbacks and initialize freeRASP
106+
## Step 4: Setup the configuration, callbacks and initialize freeRASP
172107

173-
First, the configuration and callbacks will be explained. Then the **Initialization** chapter shows the implementation.
108+
First, the configuration and callbacks will be explained. Then the [Initialization](#initialization) chapter shows the implementation.
174109

175110
### Configuration
176111

177-
You need to provide configuration for freeRASP to work properly and initialize it. The freeRASP configuration contains configs for both Android and iOS. You must fill all the required values for the plugin to work.
178-
179-
For Android:
180-
181-
- `packageName` - package name of your app you chose when you created it
182-
- `certificateHashes` - 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.
183-
- `supportedAlternativeStores` _(optional)_ - If you publish on the Google Play Store and/or Huawei AppGallery, you **don't have to assign anything** there as those are supported out of the box.
184-
185-
For iOS similarly to Android, `appBundleId` and `appTeamId` are required.
186-
187-
Lastly, pass a mail address to `watcherMail` to be able to get reports. Mail has a strict form `[email protected]` which is passed as String.
188-
189-
### Callbacks
190-
191-
freeRASP executes periodical checks when the application is running. Handle the detected threats in the **listeners**. For example, you can log the event, show a window to the user or kill the application. Visit our [wiki](https://github.com/talsec/Free-RASP-Community/wiki/Threat-detection) to learn more details about the performed checks and their importance for app security.
192-
193-
### Initialization
194-
195-
You should initialize the freeRASP in the entry point to your app, which is usually in `App.jsx` or `App.tsx`. Just copy & paste this code inside your root component / function, then setup the configuration and reactions to listeners:
112+
You need to provide configuration for freeRASP to work properly and initialize it. The freeRASP configuration is an JavaScript object that contains configs for both Android and iOS, as well as common configuration. You must fill all the required values for the plugin to work. Use the following template to provide configuration to the Talsec plugin. You can find detailed description of the configuration below.
196113

197114
```ts
198115
// app configuration
@@ -207,52 +124,88 @@ const config = {
207124
appTeamId: 'your_team_ID',
208125
},
209126
watcherMail: '[email protected]',
127+
isProd: true,
210128
};
129+
```
130+
131+
#### The configuration object should consist of:
132+
133+
1. `androidConfig` _: object | undefined_ - required for Android devices, has following keys:
134+
135+
- `packageName` _: string_ - package name of your app you chose when you created it
136+
- `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.
137+
- `supportedAlternativeStores` _: string[] | undefined_ - If you publish on the Google Play Store and/or Huawei AppGallery, you **don't have to assign anything** there as those are supported out of the box.
138+
139+
1. `iosConfig` _: object | undefined_ - required for iOS devices, has following keys:
140+
- `appBundleId` _: string_ - Bundle ID of your app
141+
- `appTeamId` _: string_ - the Apple Team ID
142+
1. `watcherMail` _: string_ - your mail address where you wish to receive reports. Mail has a strict form `[email protected]` which is passed as String.
143+
1. `isProd` _: boolean | undefined_ - defaults to `true` when undefined. If you want to use the Dev version to disable checks described [in the chapter below](#dev-vs-release-version), set the parameter to `false`. Make sure that you have the Release version in the production (i.e. isProd set to true)!
144+
145+
If you are developing only for one of the platforms, you can skip the configuration part for the other one, i.e., delete the unused configuration.
211146

147+
#### Dev vs Release version
148+
149+
The Dev version is used to not complicate the development process of the application, e.g. if you would implement killing of the application on the debugger callback. It disables some checks which won't be triggered during the development process:
150+
151+
- Emulator-usage (simulator)
152+
- Debugging (debug)
153+
- Signing (appIntegrity)
154+
- Unofficial store (unofficialStore)
155+
156+
### Callbacks
157+
158+
freeRASP executes periodical checks when the application is running. Handle the detected threats in the **listeners**. For example, you can log the event, show a window to the user or kill the application. [Visit our wiki](https://github.com/talsec/Free-RASP-Community/wiki/Threat-detection) to learn more details about the performed checks and their importance for app security.
159+
160+
### Initialization
161+
162+
You should initialize the freeRASP in the entry point to your app, which is usually in `App.jsx` or `App.tsx`. Just copy & paste this code inside your root component / function, then setup the configuration and reactions to listeners:
163+
164+
```ts
212165
// reactions for detected threats
213166
const actions = {
214167
// Android & iOS
215-
'privilegedAccess': () => {
168+
privilegedAccess: () => {
216169
console.log('privilegedAccess');
217170
},
218171
// Android & iOS
219-
'debug': () => {
172+
debug: () => {
220173
console.log('debug');
221174
},
222175
// Android & iOS
223-
'simulator': () => {
176+
simulator: () => {
224177
console.log('simulator');
225178
},
226179
// Android & iOS
227-
'appIntegrity': () => {
180+
appIntegrity: () => {
228181
console.log('appIntegrity');
229182
},
230183
// Android & iOS
231-
'unofficialStore': () => {
184+
unofficialStore: () => {
232185
console.log('unofficialStore');
233186
},
234187
// Android & iOS
235-
'hooks': () => {
188+
hooks: () => {
236189
console.log('hooks');
237190
},
238191
// Android & iOS
239-
'device binding': () => {
240-
console.log('device binding');
192+
deviceBinding: () => {
193+
console.log('deviceBinding');
241194
},
242195
// Android & iOS
243-
'secureHardwareNotAvailable': () => {
196+
secureHardwareNotAvailable: () => {
244197
console.log('secureHardwareNotAvailable');
245198
},
246199
// Android & iOS
247-
'passcode': () => {
200+
passcode: () => {
248201
console.log('passcode');
249202
},
250203
// iOS only
251-
'deviceID': () => {
204+
deviceID: () => {
252205
console.log('deviceID');
253206
},
254207
// iOS only
255-
'passcodeChange': () => {
208+
passcodeChange: () => {
256209
console.log('passcodeChange');
257210
},
258211
};
@@ -262,17 +215,21 @@ useFreeRasp(config, actions);
262215

263216
When freeRASP initializes correctly, you should see `freeRASP initialized` message in logs. Otherwise, you'll see warning with description of what went wrong.
264217

265-
_You can override this default behavior by extending the `actions` object with `'started'` key (to change action after successful initialization), and `'initializationError'` key (to set up action after unsuccessful initialization)_
218+
_You can override this default behavior by extending the `actions` object with `started` key (to change action after successful initialization), and `initializationError` key (to set up action after unsuccessful initialization)_
219+
220+
## Step 5: Additional note about obfuscation
266221

267-
## Step 6: Additional note about obfuscation
268222
The freeRASP contains public API, so the integration process is as simple as possible. Unfortunately, this public API also creates opportunities for the attacker to use publicly available information to interrupt freeRASP operations or modify your custom reaction implementation in threat callbacks. In order for freeRASP to be as effective as possible, it is highly recommended to apply obfuscation to the final package/application, making the public API more difficult to find and also partially randomized for each application so it cannot be automatically abused by generic hooking scripts.
269223

270224
### Android
225+
271226
The majority of Android projects support code shrinking and obfuscation without any additional need for setup. The owner of the project can define the set of rules that are usually automatically used when the application is built in the release mode. For more information, please visit the official documentation
272-
* https://developer.android.com/studio/build/shrink-code
273-
* https://www.guardsquare.com/manual/configuration/usage
227+
228+
- https://developer.android.com/studio/build/shrink-code
229+
- https://www.guardsquare.com/manual/configuration/usage
274230

275231
You can make sure, that the obfuscation is enabled by checking the value of **minifyEnabled** property in your **module's build.gradle** file.
232+
276233
```gradle
277234
android {
278235
...
@@ -287,8 +244,7 @@ android {
287244
}
288245
```
289246

290-
291-
## Step 7: User Data Policies
247+
## Step 6: User Data Policies
292248

293249
Google Play [requires](https://support.google.com/googleplay/android-developer/answer/10787469?hl=en) all app publishers to declare how they collect and handle user data for the apps they publish on Google Play. They should inform users properly of the data collected by the apps and how the data is shared and processed. Therefore, Google will reject the apps which do not comply with the policy.
294250

android/build.gradle

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,13 @@ android {
6161
repositories {
6262
mavenCentral()
6363
google()
64-
maven{url = uri("https://nexus3-public.monetplus.cz/repository/ahead-talsec-free-rasp")}
65-
maven{url = uri("https://developer.huawei.com/repo/")}
66-
maven{url = uri("https://jitpack.io")}
64+
}
65+
66+
rootProject.allprojects {
67+
repositories {
68+
maven{url "https://nexus3-public.monetplus.cz/repository/ahead-talsec-free-rasp"}
69+
maven{url "https://jitpack.io"}
70+
}
6771
}
6872

6973
def kotlin_version = getExtOrDefault("kotlinVersion")
@@ -74,8 +78,7 @@ dependencies {
7478
//noinspection GradleDynamicVersion
7579
implementation "com.facebook.react:react-native"
7680
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
77-
debugImplementation "com.aheaditec.talsec.security:TalsecSecurity-Community-ReactNative:6.0.0-dev"
78-
releaseImplementation "com.aheaditec.talsec.security:TalsecSecurity-Community-ReactNative:6.0.0-release"
81+
implementation "com.aheaditec.talsec.security:TalsecSecurity-Community-ReactNative:7.0.0"
7982
}
8083

8184
if (isNewArchitectureEnabled()) {

android/src/main/java/com/freeraspreactnative/FreeraspReactNativeModule.kt

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ import com.facebook.react.bridge.ReadableMap
1212
import com.facebook.react.modules.core.DeviceEventManagerModule
1313

1414
class FreeraspReactNativeModule(val reactContext: ReactApplicationContext) :
15-
ReactContextBaseJavaModule(reactContext), ThreatListener.ThreatDetected, FreeraspDeviceStateListener.DeviceStateListener {
15+
ReactContextBaseJavaModule(reactContext), ThreatListener.ThreatDetected,
16+
FreeraspDeviceStateListener.DeviceStateListener {
1617

1718
private val listener = ThreatListener(this, FreeraspDeviceStateListener)
1819

@@ -75,7 +76,7 @@ class FreeraspReactNativeModule(val reactContext: ReactApplicationContext) :
7576
}
7677

7778
override fun onDeviceBindingDetected() {
78-
sendOngoingPluginResult("device binding", null)
79+
sendOngoingPluginResult("deviceBinding", null)
7980
}
8081

8182
override fun deviceStateChangeDetected(threatType: String) {
@@ -104,7 +105,18 @@ class FreeraspReactNativeModule(val reactContext: ReactApplicationContext) :
104105
alternativeStores.add(stores.getString(i))
105106
}
106107
}
107-
return TalsecConfig(packageName, certificateHashes.toTypedArray(), watcherMail, alternativeStores.toTypedArray())
108+
var isProd = true
109+
if (config.hasKey("isProd")) {
110+
isProd = config.getBoolean("isProd")
111+
}
112+
113+
return TalsecConfig(
114+
packageName,
115+
certificateHashes.toTypedArray(),
116+
watcherMail,
117+
alternativeStores.toTypedArray(),
118+
isProd
119+
)
108120
}
109121

110122
companion object {

example/android/build.gradle

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,5 @@ allprojects {
4646
}
4747
}
4848
google()
49-
maven { url 'https://www.jitpack.io' }
50-
maven{url = uri("https://nexus3-public.monetplus.cz/repository/ahead-talsec-free-rasp")}
51-
maven{url = uri("https://developer.huawei.com/repo/")}
5249
}
5350
}

0 commit comments

Comments
 (0)