Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 3.10.0 #88

Merged
merged 19 commits into from
Nov 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules/
lib/
20 changes: 20 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"root": true,
"extends": [
"@react-native-community",
"prettier"
],
"rules": {
"prettier/prettier": [
"error",
{
"quoteProps": "consistent",
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "es5",
"useTabs": false
}
],
"no-alert": "off"
}
}
47 changes: 26 additions & 21 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
uses: ./.github/actions/setup

- name: Lint files
run: yarn lint
run: yarn lint --max-warnings=0

- name: Typecheck files
run: |
Expand All @@ -28,6 +28,9 @@ jobs:
run: |
yarn expo:typecheck

- name: Format check
run: yarn prettier --check

# no tests yet 😥
# test:
# runs-on: ubuntu-latest
Expand Down Expand Up @@ -91,29 +94,31 @@ jobs:
run: |
yarn build:android

build-ios:
runs-on: macos-14
needs: build-library
steps:
- name: Checkout
uses: actions/checkout@v4
# !! Currently build iOS is not working due to issues with XCode version
# build-ios:
# runs-on: macos-14
# needs: build-library

- name: Setup Xcode version
uses: maxim-lobanov/[email protected]
with:
xcode-version: '14.3.1'
# steps:
# - name: Checkout
# uses: actions/checkout@v4

# - name: Setup Xcode version
# uses: maxim-lobanov/[email protected]
# with:
# xcode-version: '15.4.0'



- name: Setup
uses: ./.github/actions/setup
# - name: Setup
# uses: ./.github/actions/setup

- name: Install cocoapods
run: |
cd example/ios
pod install
# - name: Install cocoapods
# run: |
# cd example/ios
# pod install

- name: Build example for iOS
working-directory: ./example
run: |
yarn build:ios
# - name: Build example for iOS
# working-directory: ./example
# run: |
# yarn build:ios
3 changes: 2 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
plugin/build
plugin/build
lib/
40 changes: 38 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,39 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [3.10.0] - 2024-11-15

- Android SDK version: 12.0.0
- iOS SDK version: 6.6.3

### React Native

#### Added

- Added configuration fields for malware detection

### Android

#### Added

- New feature: **malware detection** as a new callback for enhanced app security

#### Fixed

- Refactoring Magisk checks in the root detection

### iOS

#### Added

- Enhanced security with **[Serotonin Jailbreak](https://github.com/SerotoninApp/Serotonin) Detection** to identify compromised devices.

#### Changed

- Updated SDK code signing; it will now be signed with:
- Team ID: PBDDS45LQS
- Team Name: Lynx SFT s.r.o.

## [3.9.3] - 2024-10-28
- Android SDK version: 11.1.3
- iOS SDK version: 6.6.1
Expand All @@ -18,6 +51,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Android SDK version: 11.1.3
- iOS SDK version: 6.6.0

- Android SDK version: 11.1.3
- iOS SDK version: 6.6.0

### Android

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

### Android

#### Added
#### Added

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

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

### iOS

#### Added
#### Added

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

Expand Down
5 changes: 4 additions & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ buildscript {
classpath "com.android.tools.build:gradle:7.2.1"
// noinspection DifferentKotlinGradleVersion
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
}
}

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

apply plugin: "com.android.library"
apply plugin: "kotlin-android"
apply plugin: 'kotlinx-serialization'

if (isNewArchitectureEnabled()) {
apply plugin: "com.facebook.react"
Expand Down Expand Up @@ -87,7 +89,8 @@ dependencies {
//noinspection GradleDynamicVersion
implementation "com.facebook.react:react-native:$react_native_version"
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "com.aheaditec.talsec.security:TalsecSecurity-Community-ReactNative:11.1.3"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1"
implementation "com.aheaditec.talsec.security:TalsecSecurity-Community-ReactNative:12.0.0"
}

if (isNewArchitectureEnabled()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.freeraspreactnative

import com.aheaditec.talsec_security.security.api.SuspiciousAppInfo
import com.aheaditec.talsec_security.security.api.Talsec
import com.aheaditec.talsec_security.security.api.TalsecConfig
import com.aheaditec.talsec_security.security.api.ThreatListener
Expand All @@ -12,8 +13,14 @@ import com.facebook.react.bridge.ReadableMap
import com.facebook.react.bridge.UiThreadUtil.runOnUiThread
import com.facebook.react.bridge.WritableArray
import com.facebook.react.modules.core.DeviceEventManagerModule

class FreeraspReactNativeModule(val reactContext: ReactApplicationContext) :
import com.freeraspreactnative.utils.getArraySafe
import com.freeraspreactnative.utils.getBooleanSafe
import com.freeraspreactnative.utils.getMapThrowing
import com.freeraspreactnative.utils.getNestedArraySafe
import com.freeraspreactnative.utils.getStringThrowing
import com.freeraspreactnative.utils.toEncodedWritableArray

class FreeraspReactNativeModule(private val reactContext: ReactApplicationContext) :
ReactContextBaseJavaModule(reactContext) {

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

promise.resolve("freeRASP started")

}
catch (e: Exception) {
} catch (e: Exception) {
promise.reject("TalsecInitializationError", e.message, e)
}
}
Expand All @@ -65,6 +71,7 @@ class FreeraspReactNativeModule(val reactContext: ReactApplicationContext) :
val channelData: WritableArray = Arguments.createArray()
channelData.pushString(THREAT_CHANNEL_NAME)
channelData.pushString(THREAT_CHANNEL_KEY)
channelData.pushString(MALWARE_CHANNEL_KEY)
promise.resolve(channelData)
}

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

/**
* Method to add apps to Malware whitelist, so they don't get flagged as malware
*/
@ReactMethod
fun addToWhitelist(packageName: String, promise: Promise) {
Talsec.addToWhitelist(reactContext, packageName)
promise.resolve(true)
}

private fun buildTalsecConfig(config: ReadableMap): TalsecConfig {
val androidConfig = config.getMapThrowing("androidConfig")
val packageName = androidConfig.getStringThrowing("packageName")
Expand All @@ -97,6 +113,14 @@ class FreeraspReactNativeModule(val reactContext: ReactApplicationContext) :
.supportedAlternativeStores(androidConfig.getArraySafe("supportedAlternativeStores"))
.prod(config.getBooleanSafe("isProd"))

if (androidConfig.hasKey("malwareConfig")) {
val malwareConfig = androidConfig.getMapThrowing("malwareConfig")
talsecBuilder.whitelistedInstallationSources(malwareConfig.getArraySafe("whitelistedInstallationSources"))
talsecBuilder.blacklistedHashes(malwareConfig.getArraySafe("blacklistedHashes"))
talsecBuilder.blacklistedPackageNames(malwareConfig.getArraySafe("blacklistedPackageNames"))
talsecBuilder.suspiciousPermissions(malwareConfig.getNestedArraySafe("suspiciousPermissions"))
}

return talsecBuilder.build()
}

Expand All @@ -106,6 +130,8 @@ class FreeraspReactNativeModule(val reactContext: ReactApplicationContext) :
.toString() // name of the channel over which threat callbacks are sent
val THREAT_CHANNEL_KEY = (10000..999999999).random()
.toString() // key of the argument map under which threats are expected
val MALWARE_CHANNEL_KEY = (10000..999999999).random()
.toString() // key of the argument map under which malware data is expected
private lateinit var appReactContext: ReactApplicationContext
private fun notifyListeners(threat: Threat) {
val params = Arguments.createMap()
Expand All @@ -114,11 +140,30 @@ class FreeraspReactNativeModule(val reactContext: ReactApplicationContext) :
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
.emit(THREAT_CHANNEL_NAME, params)
}

/**
* Sends malware detected event to React Native
*/
private fun notifyMalware(suspiciousApps: MutableList<SuspiciousAppInfo>) {
val params = Arguments.createMap()
params.putInt(THREAT_CHANNEL_KEY, Threat.Malware.value)
params.putArray(
MALWARE_CHANNEL_KEY, suspiciousApps.toEncodedWritableArray(appReactContext)
)

appReactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
.emit(THREAT_CHANNEL_NAME, params)
}
}

internal object ThreatListener : FreeraspThreatHandler.TalsecReactNative {
override fun threatDetected(threatType: Threat) {
notifyListeners(threatType)
}

override fun malwareDetected(suspiciousApps: MutableList<SuspiciousAppInfo>) {
notifyMalware(suspiciousApps)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ internal object FreeraspThreatHandler : ThreatListener.ThreatDetected, ThreatLis
listener?.threatDetected(Threat.ObfuscationIssues)
}

override fun onMalwareDetected(p0: MutableList<SuspiciousAppInfo>?) {}
override fun onMalwareDetected(suspiciousAppInfos: MutableList<SuspiciousAppInfo>?) {
listener?.malwareDetected(suspiciousAppInfos ?: mutableListOf())
}

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

internal interface TalsecReactNative {
fun threatDetected(threatType: Threat)

fun malwareDetected(suspiciousApps: MutableList<SuspiciousAppInfo>)
}
}
4 changes: 3 additions & 1 deletion android/src/main/java/com/freeraspreactnative/Threat.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ internal sealed class Threat(val value: Int) {
object ObfuscationIssues : Threat((10000..999999999).random())
object SystemVPN : Threat((10000..999999999).random())
object DevMode : Threat((10000..999999999).random())
object Malware : Threat((10000..999999999).random())

companion object {
internal fun getThreatValues(): WritableArray {
Expand All @@ -39,7 +40,8 @@ internal sealed class Threat(val value: Int) {
DeviceBinding.value,
UnofficialStore.value,
ObfuscationIssues.value,
DevMode.value
DevMode.value,
Malware.value
)
)
}
Expand Down
40 changes: 0 additions & 40 deletions android/src/main/java/com/freeraspreactnative/Utils.kt

This file was deleted.

Loading
Loading