capacitor-freerasp 1.5.3 → 1.7.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/CHANGELOG.md +55 -0
- package/README.md +6 -8
- package/android/build.gradle +8 -1
- package/android/src/main/java/com/aheaditec/freerasp/FreeraspPlugin.kt +38 -2
- package/android/src/main/java/com/aheaditec/freerasp/Threat.kt +5 -1
- package/android/src/main/java/com/aheaditec/freerasp/ThreatHandler.kt +7 -1
- package/android/src/main/java/com/aheaditec/freerasp/models/CapSuspiciousAppInfo.kt +25 -0
- package/android/src/main/java/com/aheaditec/freerasp/utils/Extensions.kt +96 -0
- package/android/src/main/java/com/aheaditec/freerasp/utils/Utils.kt +81 -0
- package/dist/esm/definitions.d.ts +32 -5
- package/dist/esm/definitions.js +5 -1
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/index.d.ts +4 -3
- package/dist/esm/index.js +30 -8
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/utils.js.map +1 -1
- package/dist/plugin.cjs.js +32 -26
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +32 -26
- package/dist/plugin.js.map +1 -1
- package/ios/Plugin/TalsecRuntime.xcframework/_CodeSignature/CodeDirectory +0 -0
- package/ios/Plugin/TalsecRuntime.xcframework/_CodeSignature/CodeRequirements +0 -0
- package/ios/Plugin/TalsecRuntime.xcframework/_CodeSignature/CodeRequirements-1 +0 -0
- package/ios/Plugin/TalsecRuntime.xcframework/_CodeSignature/CodeResources +60 -60
- package/ios/Plugin/TalsecRuntime.xcframework/_CodeSignature/CodeSignature +0 -0
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/CurlWrapper.h +1 -1
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/TalsecRuntime-Swift.h +1 -1
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/curl.h +7 -7
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/multi.h +4 -4
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/options.h +1 -1
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/urlapi.h +1 -1
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Info.plist +0 -0
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios.abi.json +135 -135
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/TalsecRuntime +0 -0
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/CurlWrapper.h +1 -1
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/TalsecRuntime-Swift.h +2 -2
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/curl.h +7 -7
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/multi.h +4 -4
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/options.h +1 -1
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/urlapi.h +1 -1
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Info.plist +0 -0
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.abi.json +135 -135
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.abi.json +135 -135
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/TalsecRuntime +0 -0
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/_CodeSignature/CodeResources +21 -21
- package/package.json +6 -5
- package/android/src/main/java/com/aheaditec/freerasp/Utils.kt +0 -22
- package/dist/esm/web.d.ts +0 -16
- package/dist/esm/web.js +0 -17
- package/dist/esm/web.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,7 +5,60 @@ 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
|
+
## [1.7.0] - 2024-11-19
|
|
9
|
+
|
|
10
|
+
### Capacitor
|
|
11
|
+
|
|
12
|
+
#### Added
|
|
13
|
+
|
|
14
|
+
- Added `adbEnabled` callback, which allows you to detect USB debugging option enabled in the developer settings on the device
|
|
15
|
+
|
|
16
|
+
### Android
|
|
17
|
+
|
|
18
|
+
#### Added
|
|
19
|
+
|
|
20
|
+
- ADB detection feature
|
|
21
|
+
|
|
22
|
+
## [1.6.0] - 2024-11-15
|
|
23
|
+
|
|
24
|
+
- Android SDK version: 12.0.0
|
|
25
|
+
- iOS SDK version: 6.6.3
|
|
26
|
+
|
|
27
|
+
### Capacitor
|
|
28
|
+
|
|
29
|
+
#### Added
|
|
30
|
+
|
|
31
|
+
- Added configuration fields for malware detection
|
|
32
|
+
|
|
33
|
+
#### Fixed
|
|
34
|
+
|
|
35
|
+
- Resolved compatibilty issues with JDK 21 [(issue #21)](https://github.com/talsec/Free-RASP-Capacitor/issues/21)
|
|
36
|
+
|
|
37
|
+
### Android
|
|
38
|
+
|
|
39
|
+
#### Added
|
|
40
|
+
|
|
41
|
+
- New feature: **malware detection** as a new callback for enhanced app security
|
|
42
|
+
|
|
43
|
+
#### Fixed
|
|
44
|
+
|
|
45
|
+
- Refactoring Magisk checks in the root detection
|
|
46
|
+
|
|
47
|
+
### iOS
|
|
48
|
+
|
|
49
|
+
#### Added
|
|
50
|
+
|
|
51
|
+
- Enhanced security with **[Serotonin Jailbreak](https://github.com/SerotoninApp/Serotonin) Detection** to identify compromised devices.
|
|
52
|
+
|
|
53
|
+
#### Changed
|
|
54
|
+
|
|
55
|
+
- Updated SDK code signing; it will now be signed with:
|
|
56
|
+
- Team ID: PBDDS45LQS
|
|
57
|
+
- Team Name: Lynx SFT s.r.o.
|
|
58
|
+
|
|
8
59
|
## [1.5.3] - 2024-10-28
|
|
60
|
+
- Android SDK version: 11.1.3
|
|
61
|
+
- iOS SDK version: 6.6.1
|
|
9
62
|
|
|
10
63
|
### iOS
|
|
11
64
|
|
|
@@ -13,6 +66,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
13
66
|
- Renewed the signing certificate
|
|
14
67
|
|
|
15
68
|
## [1.5.2] - 2024-10-18
|
|
69
|
+
- Android SDK version: 11.1.3
|
|
70
|
+
- iOS SDK version: 6.6.0
|
|
16
71
|
|
|
17
72
|
### Android
|
|
18
73
|
|
package/README.md
CHANGED
|
@@ -10,7 +10,6 @@ freeRASP for Capacitor is a mobile in-app protection and security monitoring plu
|
|
|
10
10
|
|
|
11
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
|
-
|
|
14
13
|
# Overview
|
|
15
14
|
|
|
16
15
|
The freeRASP is available for Flutter, Cordova, Capacitor, React Native, Android, and iOS developers. We encourage community contributions, investigations of attack cases, joint data research, and other activities aiming to make better app security and app safety for end-users.
|
|
@@ -46,6 +45,11 @@ Learn more about commercial features at [https://talsec.app](https://talsec.app)
|
|
|
46
45
|
|
|
47
46
|
Learn more about freemium freeRASP features at [GitHub main repository](https://github.com/talsec/Free-RASP-Community).
|
|
48
47
|
|
|
48
|
+
## :radioactive: freeMalwareDetection
|
|
49
|
+
**freeMalwareDetection** is a powerful feature designed to enhance the security of your Android application by quickly and efficiently scanning for malicious or suspicious applications (e.g. Android malware) based on various blacklists and security policies. It helps to detect apps with suspicious package names, hashes, or potentially dangerous permissions.
|
|
50
|
+
|
|
51
|
+
After the integration of freeRASP, make sure you visit the [freeMalwareDetection](https://docs.talsec.app/freemalwaredetection) repository to learn more about this feature!
|
|
52
|
+
|
|
49
53
|
# :book: Discover the Official freeRASP Documentation
|
|
50
54
|
|
|
51
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,12 +60,6 @@ For integrating freeRASP on the Capacitor platform, be sure to follow all the st
|
|
|
56
60
|
|
|
57
61
|
Be sure to bookmark it and stay informed! :books: :sparkles:.
|
|
58
62
|
|
|
59
|
-
## :scroll: Reference to Legacy Documentation
|
|
60
|
-
|
|
61
|
-
If you have any suggestions for improvement or notice anything that could be clarified in the new GitBook documentation, please open an issue. Your feedback helps us maintain high-quality resources for all users.
|
|
62
|
-
|
|
63
|
-
For information on older integration methods, you can refer to the [freeRASP wiki](https://github.com/talsec/Free-RASP-Capacitor/wiki), which includes comprehensive legacy details and guidance. Additionally, the old integration can be found when you checkout to a specific tag. Your input is invaluable in helping us improve our resources and provide even better support for your needs.
|
|
64
|
-
|
|
65
63
|
# :rocket: What's New and Changelog
|
|
66
64
|
|
|
67
65
|
Stay informed and make the most of freeRASP by checking out [What's New and Changelog](https://docs.talsec.app/freerasp/whats-new-and-changelog)! Here, you’ll discover the latest features, enhancements, and bug fixes we’ve implemented to improve your experience across all platforms, including Android, iOS, Flutter, React Native, Capacitor, and Cordova.
|
|
@@ -76,4 +74,4 @@ You can check out the project board [here](https://github.com/orgs/talsec/projec
|
|
|
76
74
|
|
|
77
75
|
# :page_facing_up: License
|
|
78
76
|
|
|
79
|
-
This project is provided as freemium software, i.e. there is a fair usage policy that imposes some limitations on the free usage. The SDK software consists of open-source and binary parts, which is the property of Talsec. The open-source part is licensed under the MIT License - see the LICENSE file for details.
|
|
77
|
+
This project is provided as freemium software, i.e. there is a fair usage policy that imposes some limitations on the free usage. The SDK software consists of open-source and binary parts, which is the property of Talsec. The open-source part is licensed under the MIT License - see the LICENSE file for details.
|
package/android/build.gradle
CHANGED
|
@@ -17,11 +17,13 @@ buildscript {
|
|
|
17
17
|
dependencies {
|
|
18
18
|
classpath 'com.android.tools.build:gradle:8.0.0'
|
|
19
19
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
|
20
|
+
classpath "org.jetbrains.kotlin:kotlin-serialization:1.9.25"
|
|
20
21
|
}
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
apply plugin: 'com.android.library'
|
|
24
25
|
apply plugin: 'org.jetbrains.kotlin.android'
|
|
26
|
+
apply plugin: 'kotlinx-serialization'
|
|
25
27
|
|
|
26
28
|
android {
|
|
27
29
|
namespace "com.aheaditec.freerasp"
|
|
@@ -48,6 +50,10 @@ android {
|
|
|
48
50
|
sourceCompatibility JavaVersion.VERSION_17
|
|
49
51
|
targetCompatibility JavaVersion.VERSION_17
|
|
50
52
|
}
|
|
53
|
+
|
|
54
|
+
kotlinOptions {
|
|
55
|
+
jvmTarget = "17"
|
|
56
|
+
}
|
|
51
57
|
}
|
|
52
58
|
|
|
53
59
|
repositories {
|
|
@@ -67,9 +73,10 @@ dependencies {
|
|
|
67
73
|
implementation project(':capacitor-android')
|
|
68
74
|
implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
|
|
69
75
|
implementation "androidx.core:core-ktx:$androidCoreKtxVersion"
|
|
76
|
+
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3"
|
|
70
77
|
testImplementation "junit:junit:$junitVersion"
|
|
71
78
|
androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
|
|
72
79
|
androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
|
|
73
80
|
|
|
74
|
-
implementation 'com.aheaditec.talsec.security:TalsecSecurity-Community-Capacitor:
|
|
81
|
+
implementation 'com.aheaditec.talsec.security:TalsecSecurity-Community-Capacitor:13.0.0'
|
|
75
82
|
}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
package com.aheaditec.freerasp
|
|
2
2
|
|
|
3
|
+
import com.aheaditec.freerasp.utils.getArraySafe
|
|
4
|
+
import com.aheaditec.freerasp.utils.getNestedArraySafe
|
|
5
|
+
import com.aheaditec.freerasp.utils.toEncodedJSArray
|
|
6
|
+
import com.aheaditec.talsec_security.security.api.SuspiciousAppInfo
|
|
3
7
|
import com.aheaditec.talsec_security.security.api.Talsec
|
|
4
8
|
import com.aheaditec.talsec_security.security.api.TalsecConfig
|
|
5
9
|
import com.aheaditec.talsec_security.security.api.ThreatListener
|
|
@@ -31,7 +35,6 @@ class FreeraspPlugin : Plugin() {
|
|
|
31
35
|
bridge.activity.runOnUiThread {
|
|
32
36
|
Talsec.start(context, talsecConfig)
|
|
33
37
|
}
|
|
34
|
-
Talsec.start(context, talsecConfig)
|
|
35
38
|
call.resolve(JSObject().put("started", true))
|
|
36
39
|
} catch (e: Exception) {
|
|
37
40
|
call.reject("Error during Talsec Native plugin initialization - ${e.message}", "TalsecInitializationError", e)
|
|
@@ -70,7 +73,7 @@ class FreeraspPlugin : Plugin() {
|
|
|
70
73
|
fun getThreatChannelData(call: PluginCall) {
|
|
71
74
|
val channelData = JSONArray(
|
|
72
75
|
(listOf(
|
|
73
|
-
THREAT_CHANNEL_NAME, THREAT_CHANNEL_KEY
|
|
76
|
+
THREAT_CHANNEL_NAME, THREAT_CHANNEL_KEY, MALWARE_CHANNEL_KEY
|
|
74
77
|
))
|
|
75
78
|
)
|
|
76
79
|
call.resolve(JSObject().put("ids", channelData))
|
|
@@ -85,10 +88,34 @@ class FreeraspPlugin : Plugin() {
|
|
|
85
88
|
android.os.Process.killProcess(android.os.Process.myPid())
|
|
86
89
|
}
|
|
87
90
|
|
|
91
|
+
/**
|
|
92
|
+
* Add app with given package name to Talsec Malware Whitelist
|
|
93
|
+
* @param packageName - package name of the whitelisted app
|
|
94
|
+
* @return true if successful
|
|
95
|
+
*/
|
|
96
|
+
@PluginMethod
|
|
97
|
+
fun addToWhitelist(call: PluginCall) {
|
|
98
|
+
val packageName = call.getString("packageName")
|
|
99
|
+
if (packageName.isNullOrEmpty()) {
|
|
100
|
+
call.reject(
|
|
101
|
+
"Package name argument is missing or empty in the call",
|
|
102
|
+
"MissingArgumentError"
|
|
103
|
+
)
|
|
104
|
+
return
|
|
105
|
+
}
|
|
106
|
+
Talsec.addToWhitelist(context, packageName)
|
|
107
|
+
call.resolve(JSObject().put("result", true))
|
|
108
|
+
}
|
|
109
|
+
|
|
88
110
|
internal fun notifyListeners(threat: Threat) {
|
|
89
111
|
notifyListeners(THREAT_CHANNEL_NAME, JSObject().put(THREAT_CHANNEL_KEY, threat.value), true)
|
|
90
112
|
}
|
|
91
113
|
|
|
114
|
+
internal fun notifyMalware(suspiciousApps: MutableList<SuspiciousAppInfo>) {
|
|
115
|
+
notifyListeners(THREAT_CHANNEL_NAME, JSObject().put(THREAT_CHANNEL_KEY, Threat.Malware.value).put(
|
|
116
|
+
MALWARE_CHANNEL_KEY, suspiciousApps.toEncodedJSArray(context)), true)
|
|
117
|
+
}
|
|
118
|
+
|
|
92
119
|
private fun buildTalsecConfigThrowing(configJson: JSObject): TalsecConfig {
|
|
93
120
|
val androidConfig = configJson.getJSONObject("androidConfig")
|
|
94
121
|
val packageName = androidConfig.getString("packageName")
|
|
@@ -98,6 +125,13 @@ class FreeraspPlugin : Plugin() {
|
|
|
98
125
|
.supportedAlternativeStores(androidConfig.getArraySafe("supportedAlternativeStores"))
|
|
99
126
|
.prod(configJson.getBool("isProd") ?: true)
|
|
100
127
|
|
|
128
|
+
if (androidConfig.has("malwareConfig")) {
|
|
129
|
+
val malwareConfig = androidConfig.getJSONObject("malwareConfig")
|
|
130
|
+
talsecBuilder.whitelistedInstallationSources(malwareConfig.getArraySafe("whitelistedInstallationSources"))
|
|
131
|
+
talsecBuilder.blacklistedHashes(malwareConfig.getArraySafe("blacklistedHashes"))
|
|
132
|
+
talsecBuilder.blacklistedPackageNames(malwareConfig.getArraySafe("blacklistedPackageNames"))
|
|
133
|
+
talsecBuilder.suspiciousPermissions(malwareConfig.getNestedArraySafe("suspiciousPermissions"))
|
|
134
|
+
}
|
|
101
135
|
return talsecBuilder.build()
|
|
102
136
|
}
|
|
103
137
|
|
|
@@ -106,5 +140,7 @@ class FreeraspPlugin : Plugin() {
|
|
|
106
140
|
.toString() // name of the channel over which threat callbacks are sent
|
|
107
141
|
private val THREAT_CHANNEL_KEY = (10000..999999999).random()
|
|
108
142
|
.toString() // key of the argument map under which threats are expected
|
|
143
|
+
val MALWARE_CHANNEL_KEY = (10000..999999999).random()
|
|
144
|
+
.toString() // key of the argument map under which malware data is expected
|
|
109
145
|
}
|
|
110
146
|
}
|
|
@@ -23,6 +23,8 @@ internal sealed class Threat(val value: Int) {
|
|
|
23
23
|
object ObfuscationIssues : Threat((10000..999999999).random())
|
|
24
24
|
object SystemVPN : Threat((10000..999999999).random())
|
|
25
25
|
object DevMode : Threat((10000..999999999).random())
|
|
26
|
+
object Malware : Threat((10000..999999999).random())
|
|
27
|
+
object ADBEnabled : Threat((10000..999999999).random())
|
|
26
28
|
|
|
27
29
|
companion object {
|
|
28
30
|
internal fun getThreatValues(): JSONArray {
|
|
@@ -40,7 +42,9 @@ internal sealed class Threat(val value: Int) {
|
|
|
40
42
|
UnofficialStore.value,
|
|
41
43
|
Overlay.value,
|
|
42
44
|
ObfuscationIssues.value,
|
|
43
|
-
DevMode.value
|
|
45
|
+
DevMode.value,
|
|
46
|
+
Malware.value,
|
|
47
|
+
ADBEnabled.value
|
|
44
48
|
))
|
|
45
49
|
)
|
|
46
50
|
}
|
|
@@ -38,7 +38,9 @@ internal class TalsecThreatHandler(private val instance: FreeraspPlugin) :
|
|
|
38
38
|
instance.notifyListeners(Threat.ObfuscationIssues)
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
override fun onMalwareDetected(
|
|
41
|
+
override fun onMalwareDetected(suspiciousAppInfos: MutableList<SuspiciousAppInfo>?) {
|
|
42
|
+
instance.notifyMalware(suspiciousAppInfos ?: mutableListOf())
|
|
43
|
+
}
|
|
42
44
|
|
|
43
45
|
override fun onUnlockedDeviceDetected() {
|
|
44
46
|
instance.notifyListeners(Threat.Passcode)
|
|
@@ -52,6 +54,10 @@ internal class TalsecThreatHandler(private val instance: FreeraspPlugin) :
|
|
|
52
54
|
instance.notifyListeners(Threat.DevMode)
|
|
53
55
|
}
|
|
54
56
|
|
|
57
|
+
override fun onADBEnabledDetected() {
|
|
58
|
+
instance.notifyListeners(Threat.ADBEnabled)
|
|
59
|
+
}
|
|
60
|
+
|
|
55
61
|
override fun onSystemVPNDetected() {
|
|
56
62
|
instance.notifyListeners(Threat.SystemVPN)
|
|
57
63
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
package com.aheaditec.freerasp.models
|
|
2
|
+
|
|
3
|
+
import kotlinx.serialization.Serializable
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Simplified, serializable wrapper for Talsec's SuspiciousAppInfo
|
|
8
|
+
*/
|
|
9
|
+
@Serializable
|
|
10
|
+
data class CapSuspiciousAppInfo(
|
|
11
|
+
val packageInfo: CapPackageInfo,
|
|
12
|
+
val reason: String,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Simplified, serializable wrapper for Android's PackageInfo
|
|
17
|
+
*/
|
|
18
|
+
@Serializable
|
|
19
|
+
data class CapPackageInfo(
|
|
20
|
+
val packageName: String,
|
|
21
|
+
val appName: String?,
|
|
22
|
+
val version: String?,
|
|
23
|
+
val appIcon: String?,
|
|
24
|
+
val installerStore: String?
|
|
25
|
+
)
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
package com.aheaditec.freerasp.utils
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.content.pm.PackageInfo
|
|
5
|
+
import android.util.Base64
|
|
6
|
+
import android.util.Log
|
|
7
|
+
import com.aheaditec.freerasp.models.CapPackageInfo
|
|
8
|
+
import com.aheaditec.freerasp.models.CapSuspiciousAppInfo
|
|
9
|
+
import com.aheaditec.talsec_security.security.api.SuspiciousAppInfo
|
|
10
|
+
import com.getcapacitor.JSArray
|
|
11
|
+
import kotlinx.serialization.encodeToString
|
|
12
|
+
import kotlinx.serialization.json.Json
|
|
13
|
+
import org.json.JSONArray
|
|
14
|
+
import org.json.JSONException
|
|
15
|
+
import org.json.JSONObject
|
|
16
|
+
|
|
17
|
+
private inline fun <reified T> JSONArray.toPrimitiveArray(): Array<T> {
|
|
18
|
+
val output = mutableListOf<T>()
|
|
19
|
+
|
|
20
|
+
for (i in 0 until this.length()) {
|
|
21
|
+
val element: T = when (T::class) {
|
|
22
|
+
String::class -> this.getString(i) as T
|
|
23
|
+
Int::class -> this.getInt(i) as T
|
|
24
|
+
Double::class -> this.getDouble(i) as T
|
|
25
|
+
Long::class -> this.getLong(i) as T
|
|
26
|
+
Boolean::class -> this.getBoolean(i) as T
|
|
27
|
+
else -> throw JSONException("Cannot parse JSON array - unsupported type")
|
|
28
|
+
}
|
|
29
|
+
output.add(element)
|
|
30
|
+
}
|
|
31
|
+
return output.toTypedArray()
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
internal fun JSONObject.getArraySafe(key: String): Array<String> {
|
|
35
|
+
if (this.has(key)) {
|
|
36
|
+
val inputArray = this.getJSONArray(key)
|
|
37
|
+
return inputArray.toPrimitiveArray()
|
|
38
|
+
}
|
|
39
|
+
return arrayOf()
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
internal fun JSONObject.getNestedArraySafe(key: String): Array<Array<String>> {
|
|
43
|
+
val outArray = mutableListOf<Array<String>>()
|
|
44
|
+
if (this.has(key)) {
|
|
45
|
+
val inputArray = this.getJSONArray(key)
|
|
46
|
+
for (i in 0 until inputArray.length()) {
|
|
47
|
+
outArray.add(inputArray.getJSONArray(i).toPrimitiveArray())
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return outArray.toTypedArray()
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Converts the Talsec's SuspiciousAppInfo to Capacitor equivalent
|
|
55
|
+
*/
|
|
56
|
+
internal fun SuspiciousAppInfo.toCapSuspiciousAppInfo(context: Context): CapSuspiciousAppInfo {
|
|
57
|
+
return CapSuspiciousAppInfo(
|
|
58
|
+
packageInfo = this.packageInfo.toCapPackageInfo(context),
|
|
59
|
+
reason = this.reason,
|
|
60
|
+
)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Converts the Android's PackageInfo to Capacitor equivalent
|
|
65
|
+
*/
|
|
66
|
+
internal fun PackageInfo.toCapPackageInfo(context: Context): CapPackageInfo {
|
|
67
|
+
return CapPackageInfo(
|
|
68
|
+
packageName = this.packageName,
|
|
69
|
+
appName = Utils.getAppName(context, this.applicationInfo),
|
|
70
|
+
version = this.versionName,
|
|
71
|
+
appIcon = Utils.getAppIconAsBase64String(context, this.packageName),
|
|
72
|
+
installerStore = Utils.getInstallationSource(context, this.packageName)
|
|
73
|
+
)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Convert the Talsec's SuspiciousAppInfo to base64-encoded JSArray,
|
|
78
|
+
* which can be then sent to Capacitor
|
|
79
|
+
*/
|
|
80
|
+
internal fun MutableList<SuspiciousAppInfo>.toEncodedJSArray(context: Context): JSArray {
|
|
81
|
+
val output = JSArray()
|
|
82
|
+
this.forEach { suspiciousAppInfo ->
|
|
83
|
+
val capSuspiciousAppInfo = suspiciousAppInfo.toCapSuspiciousAppInfo(context)
|
|
84
|
+
try {
|
|
85
|
+
val encodedAppInfo =
|
|
86
|
+
Base64.encodeToString(
|
|
87
|
+
Json.encodeToString(capSuspiciousAppInfo).toByteArray(),
|
|
88
|
+
Base64.DEFAULT
|
|
89
|
+
)
|
|
90
|
+
output.put(encodedAppInfo)
|
|
91
|
+
} catch (e: Exception) {
|
|
92
|
+
Log.e("Talsec", "Could not serialize suspicious app data: ${e.message}")
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return output
|
|
96
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
package com.aheaditec.freerasp.utils
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.content.pm.ApplicationInfo
|
|
5
|
+
import android.graphics.Bitmap
|
|
6
|
+
import android.graphics.Canvas
|
|
7
|
+
import android.graphics.drawable.BitmapDrawable
|
|
8
|
+
import android.os.Build
|
|
9
|
+
import android.util.Base64
|
|
10
|
+
import android.util.Log
|
|
11
|
+
import java.io.ByteArrayOutputStream
|
|
12
|
+
|
|
13
|
+
internal object Utils {
|
|
14
|
+
|
|
15
|
+
private fun compressBitmap(bitmap: Bitmap): String {
|
|
16
|
+
val byteArrayOutputStream = ByteArrayOutputStream()
|
|
17
|
+
bitmap.compress(Bitmap.CompressFormat.PNG, 10, byteArrayOutputStream)
|
|
18
|
+
val byteArray = byteArrayOutputStream.toByteArray()
|
|
19
|
+
return Base64.encodeToString(byteArray, Base64.NO_WRAP)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Retrieves human-readable application name
|
|
24
|
+
*/
|
|
25
|
+
internal fun getAppName(context: Context, applicationInfo: ApplicationInfo?): String? {
|
|
26
|
+
return applicationInfo?.let { context.packageManager.getApplicationLabel(it) as String }
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Retrieves app icon for the given package name as Drawable, transforms it to Bitmap,
|
|
31
|
+
* compresses to PNG and finally encodes the data to Base64
|
|
32
|
+
* @param context Capacitor context
|
|
33
|
+
* @param packageName package name for which icon should be retrieved
|
|
34
|
+
* @return Base-64 encoded string
|
|
35
|
+
*/
|
|
36
|
+
internal fun getAppIconAsBase64String(context: Context, packageName: String): String? {
|
|
37
|
+
try {
|
|
38
|
+
val drawable = context.packageManager.getApplicationIcon(packageName)
|
|
39
|
+
|
|
40
|
+
if (drawable is BitmapDrawable && drawable.bitmap != null) {
|
|
41
|
+
return compressBitmap(drawable.bitmap)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (drawable.intrinsicWidth > 0 && drawable.intrinsicHeight > 0) {
|
|
45
|
+
val bitmap = Bitmap.createBitmap(
|
|
46
|
+
drawable.intrinsicWidth,
|
|
47
|
+
drawable.intrinsicHeight,
|
|
48
|
+
Bitmap.Config.ARGB_8888
|
|
49
|
+
)
|
|
50
|
+
val canvas = Canvas(bitmap)
|
|
51
|
+
drawable.setBounds(0, 0, canvas.width, canvas.height)
|
|
52
|
+
drawable.draw(canvas)
|
|
53
|
+
return compressBitmap(bitmap)
|
|
54
|
+
}
|
|
55
|
+
return null
|
|
56
|
+
} catch (e: Exception) {
|
|
57
|
+
Log.e("Talsec", "Could not retrieve app icon for ${packageName}: ${e.message}")
|
|
58
|
+
return null
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Retrieves installation source for the given package name
|
|
64
|
+
* @param context Capacitor context
|
|
65
|
+
* @param packageName package name for which installation source should be retrieved
|
|
66
|
+
* @return Installation source package name
|
|
67
|
+
*/
|
|
68
|
+
@Suppress("DEPRECATION")
|
|
69
|
+
internal fun getInstallationSource(context: Context, packageName: String): String? {
|
|
70
|
+
return try {
|
|
71
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
|
72
|
+
context.packageManager.getInstallSourceInfo(packageName).installingPackageName
|
|
73
|
+
} else {
|
|
74
|
+
context.packageManager.getInstallerPackageName(packageName)
|
|
75
|
+
}
|
|
76
|
+
} catch (e: Exception) {
|
|
77
|
+
Log.e("Talsec", "Could not retrieve app installation source for ${packageName}: ${e.message}")
|
|
78
|
+
null
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -10,25 +10,48 @@ export interface FreeraspPlugin {
|
|
|
10
10
|
ids: number[];
|
|
11
11
|
}>;
|
|
12
12
|
getThreatChannelData(): Promise<{
|
|
13
|
-
ids: [string, string];
|
|
13
|
+
ids: [string, string, string];
|
|
14
|
+
}>;
|
|
15
|
+
addToWhitelist(options: {
|
|
16
|
+
packageName: string;
|
|
17
|
+
}): Promise<{
|
|
18
|
+
result: boolean;
|
|
14
19
|
}>;
|
|
15
20
|
}
|
|
16
|
-
export type FreeraspConfig = {
|
|
21
|
+
export declare type FreeraspConfig = {
|
|
17
22
|
androidConfig?: AndroidConfig;
|
|
18
23
|
iosConfig?: IOSConfig;
|
|
19
24
|
watcherMail: string;
|
|
20
25
|
isProd?: boolean;
|
|
21
26
|
};
|
|
22
|
-
export type AndroidConfig = {
|
|
27
|
+
export declare type AndroidConfig = {
|
|
23
28
|
packageName: string;
|
|
24
29
|
certificateHashes: string[];
|
|
25
30
|
supportedAlternativeStores?: string[];
|
|
31
|
+
malwareConfig?: MalwareConfig;
|
|
26
32
|
};
|
|
27
|
-
export type IOSConfig = {
|
|
33
|
+
export declare type IOSConfig = {
|
|
28
34
|
appBundleId: string;
|
|
29
35
|
appTeamId: string;
|
|
30
36
|
};
|
|
31
|
-
export type
|
|
37
|
+
export declare type MalwareConfig = {
|
|
38
|
+
blacklistedHashes?: string[];
|
|
39
|
+
blacklistedPackageNames?: string[];
|
|
40
|
+
suspiciousPermissions?: string[][];
|
|
41
|
+
whitelistedInstallationSources?: string[];
|
|
42
|
+
};
|
|
43
|
+
export declare type SuspiciousAppInfo = {
|
|
44
|
+
packageInfo: PackageInfo;
|
|
45
|
+
reason: string;
|
|
46
|
+
};
|
|
47
|
+
export declare type PackageInfo = {
|
|
48
|
+
packageName: string;
|
|
49
|
+
appName?: string;
|
|
50
|
+
version?: string;
|
|
51
|
+
appIcon?: string;
|
|
52
|
+
installerStore?: string;
|
|
53
|
+
};
|
|
54
|
+
export declare type NativeEventEmitterActions = {
|
|
32
55
|
privilegedAccess?: () => any;
|
|
33
56
|
debug?: () => any;
|
|
34
57
|
simulator?: () => any;
|
|
@@ -42,6 +65,8 @@ export type NativeEventEmitterActions = {
|
|
|
42
65
|
obfuscationIssues?: () => any;
|
|
43
66
|
devMode?: () => any;
|
|
44
67
|
systemVPN?: () => any;
|
|
68
|
+
malware?: (suspiciousApps: SuspiciousAppInfo[]) => any;
|
|
69
|
+
adbEnabled?: () => any;
|
|
45
70
|
};
|
|
46
71
|
export declare class Threat {
|
|
47
72
|
value: number;
|
|
@@ -59,6 +84,8 @@ export declare class Threat {
|
|
|
59
84
|
static Overlay: Threat;
|
|
60
85
|
static ObfuscationIssues: Threat;
|
|
61
86
|
static DevMode: Threat;
|
|
87
|
+
static Malware: Threat;
|
|
88
|
+
static ADBEnabled: Threat;
|
|
62
89
|
constructor(value: number);
|
|
63
90
|
static getValues(): Threat[];
|
|
64
91
|
}
|
package/dist/esm/definitions.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Capacitor } from
|
|
1
|
+
import { Capacitor } from '@capacitor/core';
|
|
2
2
|
export class Threat {
|
|
3
3
|
constructor(value) {
|
|
4
4
|
this.value = value;
|
|
@@ -19,6 +19,8 @@ export class Threat {
|
|
|
19
19
|
this.Overlay,
|
|
20
20
|
this.ObfuscationIssues,
|
|
21
21
|
this.DevMode,
|
|
22
|
+
this.Malware,
|
|
23
|
+
this.ADBEnabled,
|
|
22
24
|
]
|
|
23
25
|
: [
|
|
24
26
|
this.AppIntegrity,
|
|
@@ -49,4 +51,6 @@ Threat.UnofficialStore = new Threat(0);
|
|
|
49
51
|
Threat.Overlay = new Threat(0);
|
|
50
52
|
Threat.ObfuscationIssues = new Threat(0);
|
|
51
53
|
Threat.DevMode = new Threat(0);
|
|
54
|
+
Threat.Malware = new Threat(0);
|
|
55
|
+
Threat.ADBEnabled = new Threat(0);
|
|
52
56
|
//# sourceMappingURL=definitions.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAwE5C,MAAM,OAAO,MAAM;IAoBjB,YAAY,KAAa;QACvB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAED,MAAM,CAAC,SAAS;QACd,OAAO,SAAS,CAAC,WAAW,EAAE,KAAK,SAAS;YAC1C,CAAC,CAAC;gBACE,IAAI,CAAC,YAAY;gBACjB,IAAI,CAAC,gBAAgB;gBACrB,IAAI,CAAC,KAAK;gBACV,IAAI,CAAC,KAAK;gBACV,IAAI,CAAC,QAAQ;gBACb,IAAI,CAAC,SAAS;gBACd,IAAI,CAAC,0BAA0B;gBAC/B,IAAI,CAAC,SAAS;gBACd,IAAI,CAAC,aAAa;gBAClB,IAAI,CAAC,eAAe;gBACpB,IAAI,CAAC,OAAO;gBACZ,IAAI,CAAC,iBAAiB;gBACtB,IAAI,CAAC,OAAO;gBACZ,IAAI,CAAC,OAAO;gBACZ,IAAI,CAAC,UAAU;aAChB;YACH,CAAC,CAAC;gBACE,IAAI,CAAC,YAAY;gBACjB,IAAI,CAAC,gBAAgB;gBACrB,IAAI,CAAC,KAAK;gBACV,IAAI,CAAC,KAAK;gBACV,IAAI,CAAC,QAAQ;gBACb,IAAI,CAAC,SAAS;gBACd,IAAI,CAAC,0BAA0B;gBAC/B,IAAI,CAAC,SAAS;gBACd,IAAI,CAAC,aAAa;gBAClB,IAAI,CAAC,QAAQ;gBACb,IAAI,CAAC,eAAe;aACrB,CAAC;IACR,CAAC;;AArDM,mBAAY,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;AAC7B,uBAAgB,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;AACjC,YAAK,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;AACtB,YAAK,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;AACtB,eAAQ,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;AACzB,gBAAS,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;AAC1B,iCAA0B,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;AAC3C,gBAAS,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;AAC1B,oBAAa,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;AAC9B,eAAQ,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;AACzB,sBAAe,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;AAChC,cAAO,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;AACxB,wBAAiB,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;AAClC,cAAO,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;AACxB,cAAO,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;AACxB,iBAAU,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC","sourcesContent":["import { Capacitor } from '@capacitor/core';\n\nexport interface FreeraspPlugin {\n addListener(listener: string, callback: (event: any) => void): any;\n talsecStart(options: {\n config: FreeraspConfig;\n }): Promise<{ started: boolean }>;\n onInvalidCallback(): void;\n getThreatIdentifiers(): Promise<{ ids: number[] }>;\n getThreatChannelData(): Promise<{ ids: [string, string, string] }>;\n addToWhitelist(options: {\n packageName: string;\n }): Promise<{ result: boolean }>;\n}\n\nexport type FreeraspConfig = {\n androidConfig?: AndroidConfig;\n iosConfig?: IOSConfig;\n watcherMail: string;\n isProd?: boolean;\n};\n\nexport type AndroidConfig = {\n packageName: string;\n certificateHashes: string[];\n supportedAlternativeStores?: string[];\n malwareConfig?: MalwareConfig;\n};\n\nexport type IOSConfig = {\n appBundleId: string;\n appTeamId: string;\n};\n\nexport type MalwareConfig = {\n blacklistedHashes?: string[];\n blacklistedPackageNames?: string[];\n suspiciousPermissions?: string[][];\n whitelistedInstallationSources?: string[];\n};\n\nexport type SuspiciousAppInfo = {\n packageInfo: PackageInfo;\n reason: string;\n};\n\nexport type PackageInfo = {\n packageName: string;\n appName?: string;\n version?: string;\n appIcon?: string;\n installerStore?: string;\n};\n\nexport type NativeEventEmitterActions = {\n privilegedAccess?: () => any;\n debug?: () => any;\n simulator?: () => any;\n appIntegrity?: () => any;\n unofficialStore?: () => any;\n hooks?: () => any;\n deviceBinding?: () => any;\n deviceID?: () => any;\n passcode?: () => any;\n secureHardwareNotAvailable?: () => any;\n obfuscationIssues?: () => any;\n devMode?: () => any;\n systemVPN?: () => any;\n malware?: (suspiciousApps: SuspiciousAppInfo[]) => any;\n adbEnabled?: () => any;\n};\n\nexport class Threat {\n value: number;\n\n static AppIntegrity = new Threat(0);\n static PrivilegedAccess = new Threat(0);\n static Debug = new Threat(0);\n static Hooks = new Threat(0);\n static Passcode = new Threat(0);\n static Simulator = new Threat(0);\n static SecureHardwareNotAvailable = new Threat(0);\n static SystemVPN = new Threat(0);\n static DeviceBinding = new Threat(0);\n static DeviceID = new Threat(0);\n static UnofficialStore = new Threat(0);\n static Overlay = new Threat(0);\n static ObfuscationIssues = new Threat(0);\n static DevMode = new Threat(0);\n static Malware = new Threat(0);\n static ADBEnabled = new Threat(0);\n\n constructor(value: number) {\n this.value = value;\n }\n\n static getValues(): Threat[] {\n return Capacitor.getPlatform() === 'android'\n ? [\n this.AppIntegrity,\n this.PrivilegedAccess,\n this.Debug,\n this.Hooks,\n this.Passcode,\n this.Simulator,\n this.SecureHardwareNotAvailable,\n this.SystemVPN,\n this.DeviceBinding,\n this.UnofficialStore,\n this.Overlay,\n this.ObfuscationIssues,\n this.DevMode,\n this.Malware,\n this.ADBEnabled,\n ]\n : [\n this.AppIntegrity,\n this.PrivilegedAccess,\n this.Debug,\n this.Hooks,\n this.Passcode,\n this.Simulator,\n this.SecureHardwareNotAvailable,\n this.SystemVPN,\n this.DeviceBinding,\n this.DeviceID,\n this.UnofficialStore,\n ];\n }\n}\n"]}
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { FreeraspPlugin, FreeraspConfig, NativeEventEmitterActions } from './definitions';
|
|
2
2
|
declare const Freerasp: FreeraspPlugin;
|
|
3
|
-
declare const setThreatListeners: <T extends NativeEventEmitterActions>(callbacks: T & Record<Exclude<keyof T,
|
|
3
|
+
declare const setThreatListeners: <T extends NativeEventEmitterActions>(callbacks: T & Record<Exclude<keyof T, "privilegedAccess" | "debug" | "simulator" | "appIntegrity" | "unofficialStore" | "hooks" | "deviceBinding" | "deviceID" | "passcode" | "secureHardwareNotAvailable" | "obfuscationIssues" | "devMode" | "systemVPN" | "malware" | "adbEnabled">, []>) => Promise<void>;
|
|
4
4
|
declare const removeThreatListeners: () => void;
|
|
5
|
-
declare const startFreeRASP: <T extends NativeEventEmitterActions>(config: FreeraspConfig, reactions: T & Record<Exclude<keyof T,
|
|
5
|
+
declare const startFreeRASP: <T extends NativeEventEmitterActions>(config: FreeraspConfig, reactions: T & Record<Exclude<keyof T, "privilegedAccess" | "debug" | "simulator" | "appIntegrity" | "unofficialStore" | "hooks" | "deviceBinding" | "deviceID" | "passcode" | "secureHardwareNotAvailable" | "obfuscationIssues" | "devMode" | "systemVPN" | "malware" | "adbEnabled">, []>) => Promise<boolean>;
|
|
6
|
+
declare const addToWhitelist: (packageName: string) => Promise<boolean>;
|
|
6
7
|
export * from './definitions';
|
|
7
|
-
export { Freerasp, startFreeRASP, setThreatListeners, removeThreatListeners };
|
|
8
|
+
export { Freerasp, startFreeRASP, setThreatListeners, removeThreatListeners, addToWhitelist, };
|