Skip to content

Commit 18e9a39

Browse files
authored
chore(release): freeRASP 3.10.0 (#88)
* feat(ts): add malware detection * feat(ts): add malware detection * feat(example): add malware demo * chore(release): freeRASP 3.10.0 * docs: update changelog * chore(ts): refactoring * chore(example): update add apps to whiltelist * chore(Android): rename malware to malwareConfig * chore(ts): export types properly * feat(Android): make applicationInfo nullable * feat(Android): add error logs, improve array parsing * feat(ci): add prettier to ci * feat(iOS): update SDK to 6.6.3 * feat(Android): update SDK to 12.0.0 * chore(example): update example app * chore(example): update lockfile * ci: bump xcode version * docs: update changelog * ci: mark build ios optional
1 parent d51a8a6 commit 18e9a39

File tree

53 files changed

+1389
-701
lines changed

Some content is hidden

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

53 files changed

+1389
-701
lines changed

.eslintignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules/
2+
lib/

.eslintrc.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"root": true,
3+
"extends": [
4+
"@react-native-community",
5+
"prettier"
6+
],
7+
"rules": {
8+
"prettier/prettier": [
9+
"error",
10+
{
11+
"quoteProps": "consistent",
12+
"singleQuote": true,
13+
"tabWidth": 2,
14+
"trailingComma": "es5",
15+
"useTabs": false
16+
}
17+
],
18+
"no-alert": "off"
19+
}
20+
}

.github/workflows/ci.yml

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
uses: ./.github/actions/setup
1919

2020
- name: Lint files
21-
run: yarn lint
21+
run: yarn lint --max-warnings=0
2222

2323
- name: Typecheck files
2424
run: |
@@ -28,6 +28,9 @@ jobs:
2828
run: |
2929
yarn expo:typecheck
3030
31+
- name: Format check
32+
run: yarn prettier --check
33+
3134
# no tests yet 😥
3235
# test:
3336
# runs-on: ubuntu-latest
@@ -91,29 +94,31 @@ jobs:
9194
run: |
9295
yarn build:android
9396
94-
build-ios:
95-
runs-on: macos-14
96-
needs: build-library
97-
steps:
98-
- name: Checkout
99-
uses: actions/checkout@v4
97+
# !! Currently build iOS is not working due to issues with XCode version
98+
# build-ios:
99+
# runs-on: macos-14
100+
# needs: build-library
100101

101-
- name: Setup Xcode version
102-
uses: maxim-lobanov/[email protected]
103-
with:
104-
xcode-version: '14.3.1'
102+
# steps:
103+
# - name: Checkout
104+
# uses: actions/checkout@v4
105+
106+
# - name: Setup Xcode version
107+
# uses: maxim-lobanov/[email protected]
108+
# with:
109+
# xcode-version: '15.4.0'
105110

106111

107112

108-
- name: Setup
109-
uses: ./.github/actions/setup
113+
# - name: Setup
114+
# uses: ./.github/actions/setup
110115

111-
- name: Install cocoapods
112-
run: |
113-
cd example/ios
114-
pod install
116+
# - name: Install cocoapods
117+
# run: |
118+
# cd example/ios
119+
# pod install
115120

116-
- name: Build example for iOS
117-
working-directory: ./example
118-
run: |
119-
yarn build:ios
121+
# - name: Build example for iOS
122+
# working-directory: ./example
123+
# run: |
124+
# yarn build:ios

.prettierignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
plugin/build
1+
plugin/build
2+
lib/

CHANGELOG.md

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,39 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [3.10.0] - 2024-11-15
9+
10+
- Android SDK version: 12.0.0
11+
- iOS SDK version: 6.6.3
12+
13+
### React Native
14+
15+
#### Added
16+
17+
- Added configuration fields for malware detection
18+
19+
### Android
20+
21+
#### Added
22+
23+
- New feature: **malware detection** as a new callback for enhanced app security
24+
25+
#### Fixed
26+
27+
- Refactoring Magisk checks in the root detection
28+
29+
### iOS
30+
31+
#### Added
32+
33+
- Enhanced security with **[Serotonin Jailbreak](https://github.com/SerotoninApp/Serotonin) Detection** to identify compromised devices.
34+
35+
#### Changed
36+
37+
- Updated SDK code signing; it will now be signed with:
38+
- Team ID: PBDDS45LQS
39+
- Team Name: Lynx SFT s.r.o.
40+
841
## [3.9.3] - 2024-10-28
942
- Android SDK version: 11.1.3
1043
- iOS SDK version: 6.6.1
@@ -18,6 +51,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1851
- Android SDK version: 11.1.3
1952
- iOS SDK version: 6.6.0
2053

54+
- Android SDK version: 11.1.3
55+
- iOS SDK version: 6.6.0
56+
2157
### Android
2258

2359
#### Fixed
@@ -51,7 +87,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
5187

5288
### Android
5389

54-
#### Added
90+
#### Added
5591

5692
- Added the auditing of the internal execution for the future check optimization and overall security improvements.
5793

@@ -69,7 +105,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
69105

70106
### iOS
71107

72-
#### Added
108+
#### Added
73109

74110
- [Dopamine](https://github.com/opa334/Dopamine) jailbreak detection.
75111

android/build.gradle

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ buildscript {
1111
classpath "com.android.tools.build:gradle:7.2.1"
1212
// noinspection DifferentKotlinGradleVersion
1313
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
14+
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
1415
}
1516
}
1617

@@ -20,6 +21,7 @@ def isNewArchitectureEnabled() {
2021

2122
apply plugin: "com.android.library"
2223
apply plugin: "kotlin-android"
24+
apply plugin: 'kotlinx-serialization'
2325

2426
if (isNewArchitectureEnabled()) {
2527
apply plugin: "com.facebook.react"
@@ -87,7 +89,8 @@ dependencies {
8789
//noinspection GradleDynamicVersion
8890
implementation "com.facebook.react:react-native:$react_native_version"
8991
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
90-
implementation "com.aheaditec.talsec.security:TalsecSecurity-Community-ReactNative:11.1.3"
92+
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1"
93+
implementation "com.aheaditec.talsec.security:TalsecSecurity-Community-ReactNative:12.0.0"
9194
}
9295

9396
if (isNewArchitectureEnabled()) {

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

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.freeraspreactnative
22

3+
import com.aheaditec.talsec_security.security.api.SuspiciousAppInfo
34
import com.aheaditec.talsec_security.security.api.Talsec
45
import com.aheaditec.talsec_security.security.api.TalsecConfig
56
import com.aheaditec.talsec_security.security.api.ThreatListener
@@ -12,8 +13,14 @@ import com.facebook.react.bridge.ReadableMap
1213
import com.facebook.react.bridge.UiThreadUtil.runOnUiThread
1314
import com.facebook.react.bridge.WritableArray
1415
import com.facebook.react.modules.core.DeviceEventManagerModule
15-
16-
class FreeraspReactNativeModule(val reactContext: ReactApplicationContext) :
16+
import com.freeraspreactnative.utils.getArraySafe
17+
import com.freeraspreactnative.utils.getBooleanSafe
18+
import com.freeraspreactnative.utils.getMapThrowing
19+
import com.freeraspreactnative.utils.getNestedArraySafe
20+
import com.freeraspreactnative.utils.getStringThrowing
21+
import com.freeraspreactnative.utils.toEncodedWritableArray
22+
23+
class FreeraspReactNativeModule(private val reactContext: ReactApplicationContext) :
1724
ReactContextBaseJavaModule(reactContext) {
1825

1926
private val listener = ThreatListener(FreeraspThreatHandler, FreeraspThreatHandler)
@@ -42,8 +49,7 @@ class FreeraspReactNativeModule(val reactContext: ReactApplicationContext) :
4249

4350
promise.resolve("freeRASP started")
4451

45-
}
46-
catch (e: Exception) {
52+
} catch (e: Exception) {
4753
promise.reject("TalsecInitializationError", e.message, e)
4854
}
4955
}
@@ -65,6 +71,7 @@ class FreeraspReactNativeModule(val reactContext: ReactApplicationContext) :
6571
val channelData: WritableArray = Arguments.createArray()
6672
channelData.pushString(THREAT_CHANNEL_NAME)
6773
channelData.pushString(THREAT_CHANNEL_KEY)
74+
channelData.pushString(MALWARE_CHANNEL_KEY)
6875
promise.resolve(channelData)
6976
}
7077

@@ -87,6 +94,15 @@ class FreeraspReactNativeModule(val reactContext: ReactApplicationContext) :
8794
// Remove upstream listeners, stop unnecessary background tasks
8895
}
8996

97+
/**
98+
* Method to add apps to Malware whitelist, so they don't get flagged as malware
99+
*/
100+
@ReactMethod
101+
fun addToWhitelist(packageName: String, promise: Promise) {
102+
Talsec.addToWhitelist(reactContext, packageName)
103+
promise.resolve(true)
104+
}
105+
90106
private fun buildTalsecConfig(config: ReadableMap): TalsecConfig {
91107
val androidConfig = config.getMapThrowing("androidConfig")
92108
val packageName = androidConfig.getStringThrowing("packageName")
@@ -97,6 +113,14 @@ class FreeraspReactNativeModule(val reactContext: ReactApplicationContext) :
97113
.supportedAlternativeStores(androidConfig.getArraySafe("supportedAlternativeStores"))
98114
.prod(config.getBooleanSafe("isProd"))
99115

116+
if (androidConfig.hasKey("malwareConfig")) {
117+
val malwareConfig = androidConfig.getMapThrowing("malwareConfig")
118+
talsecBuilder.whitelistedInstallationSources(malwareConfig.getArraySafe("whitelistedInstallationSources"))
119+
talsecBuilder.blacklistedHashes(malwareConfig.getArraySafe("blacklistedHashes"))
120+
talsecBuilder.blacklistedPackageNames(malwareConfig.getArraySafe("blacklistedPackageNames"))
121+
talsecBuilder.suspiciousPermissions(malwareConfig.getNestedArraySafe("suspiciousPermissions"))
122+
}
123+
100124
return talsecBuilder.build()
101125
}
102126

@@ -106,6 +130,8 @@ class FreeraspReactNativeModule(val reactContext: ReactApplicationContext) :
106130
.toString() // name of the channel over which threat callbacks are sent
107131
val THREAT_CHANNEL_KEY = (10000..999999999).random()
108132
.toString() // key of the argument map under which threats are expected
133+
val MALWARE_CHANNEL_KEY = (10000..999999999).random()
134+
.toString() // key of the argument map under which malware data is expected
109135
private lateinit var appReactContext: ReactApplicationContext
110136
private fun notifyListeners(threat: Threat) {
111137
val params = Arguments.createMap()
@@ -114,11 +140,30 @@ class FreeraspReactNativeModule(val reactContext: ReactApplicationContext) :
114140
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
115141
.emit(THREAT_CHANNEL_NAME, params)
116142
}
143+
144+
/**
145+
* Sends malware detected event to React Native
146+
*/
147+
private fun notifyMalware(suspiciousApps: MutableList<SuspiciousAppInfo>) {
148+
val params = Arguments.createMap()
149+
params.putInt(THREAT_CHANNEL_KEY, Threat.Malware.value)
150+
params.putArray(
151+
MALWARE_CHANNEL_KEY, suspiciousApps.toEncodedWritableArray(appReactContext)
152+
)
153+
154+
appReactContext
155+
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
156+
.emit(THREAT_CHANNEL_NAME, params)
157+
}
117158
}
118159

119160
internal object ThreatListener : FreeraspThreatHandler.TalsecReactNative {
120161
override fun threatDetected(threatType: Threat) {
121162
notifyListeners(threatType)
122163
}
164+
165+
override fun malwareDetected(suspiciousApps: MutableList<SuspiciousAppInfo>) {
166+
notifyMalware(suspiciousApps)
167+
}
123168
}
124169
}

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ internal object FreeraspThreatHandler : ThreatListener.ThreatDetected, ThreatLis
3939
listener?.threatDetected(Threat.ObfuscationIssues)
4040
}
4141

42-
override fun onMalwareDetected(p0: MutableList<SuspiciousAppInfo>?) {}
42+
override fun onMalwareDetected(suspiciousAppInfos: MutableList<SuspiciousAppInfo>?) {
43+
listener?.malwareDetected(suspiciousAppInfos ?: mutableListOf())
44+
}
4345

4446
override fun onUnlockedDeviceDetected() {
4547
listener?.threatDetected(Threat.Passcode)
@@ -59,5 +61,7 @@ internal object FreeraspThreatHandler : ThreatListener.ThreatDetected, ThreatLis
5961

6062
internal interface TalsecReactNative {
6163
fun threatDetected(threatType: Threat)
64+
65+
fun malwareDetected(suspiciousApps: MutableList<SuspiciousAppInfo>)
6266
}
6367
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ internal sealed class Threat(val value: Int) {
2323
object ObfuscationIssues : Threat((10000..999999999).random())
2424
object SystemVPN : Threat((10000..999999999).random())
2525
object DevMode : Threat((10000..999999999).random())
26+
object Malware : Threat((10000..999999999).random())
2627

2728
companion object {
2829
internal fun getThreatValues(): WritableArray {
@@ -39,7 +40,8 @@ internal sealed class Threat(val value: Int) {
3940
DeviceBinding.value,
4041
UnofficialStore.value,
4142
ObfuscationIssues.value,
42-
DevMode.value
43+
DevMode.value,
44+
Malware.value
4345
)
4446
)
4547
}

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

Lines changed: 0 additions & 40 deletions
This file was deleted.

0 commit comments

Comments
 (0)