Skip to content

Commit 040ce1c

Browse files
committed
feat(example): add malware demo
1 parent ef8a899 commit 040ce1c

File tree

8 files changed

+353
-4
lines changed

8 files changed

+353
-4
lines changed

example/assets/arrow-down.png

440 Bytes
Loading

example/assets/arrow-up.png

427 Bytes
Loading

example/src/App.tsx

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,45 @@
11
import * as React from 'react';
22

33
import { Platform } from 'react-native';
4-
import { useFreeRasp } from 'freerasp-react-native';
4+
import {
5+
addToWhitelist,
6+
useFreeRasp,
7+
type SuspiciousAppInfo,
8+
} from 'freerasp-react-native';
59
import { DemoApp } from './DemoApp';
610
import { commonChecks, iosChecks, androidChecks } from './checks';
11+
import { useEffect } from 'react';
712

813
const App = () => {
914
const [appChecks, setAppChecks] = React.useState([
1015
...commonChecks,
1116
...(Platform.OS === 'ios' ? iosChecks : androidChecks),
1217
]);
18+
const [suspiciousApps, setSuspiciousApps] = React.useState<
19+
SuspiciousAppInfo[]
20+
>([]);
21+
22+
useEffect(() => {
23+
(async () => {
24+
Platform.OS === 'android' && (await addItemsToMalwareWhitelist());
25+
})();
26+
}, []);
1327

1428
const config = {
1529
androidConfig: {
1630
packageName: 'com.freeraspreactnativeexample',
1731
certificateHashes: ['AKoRuyLMM91E7lX/Zqp3u4jMmd0A7hH/Iqozu0TMVd0='],
1832
// supportedAlternativeStores: ['storeOne', 'storeTwo'],
33+
malware: {
34+
blocklistedHashes: ['FgvSehLMM91E7lX/Zqp3u4jMmd0A7hH/Iqozu0TMVd0u'],
35+
blocklistedPackageNames: ['com.wultra.app.screenlogger'],
36+
blocklistedPermissions: [
37+
['android.permission.BLUETOOTH', 'android.permission.INTERNET'],
38+
['android.permission.INTERNET'],
39+
['android.permission.BATTERY_STATS'],
40+
],
41+
whitelistedInstallationSources: ['com.apkpure.aegon'],
42+
},
1943
},
2044
iosConfig: {
2145
appBundleId: 'com.freeraspreactnativeexample',
@@ -144,11 +168,37 @@ const App = () => {
144168
)
145169
);
146170
},
171+
// Android only
172+
malware: (detectedApps: SuspiciousAppInfo[]) => {
173+
setSuspiciousApps(detectedApps);
174+
setAppChecks((currentState) =>
175+
currentState.map((threat) =>
176+
threat.name === 'Malware' ? { ...threat, status: 'nok' } : threat
177+
)
178+
);
179+
},
180+
};
181+
182+
const addItemsToMalwareWhitelist = async () => {
183+
const appsToWhitelist = [
184+
'com.talsecreactnativesecuritypluginexample',
185+
'com.example.myApp',
186+
];
187+
appsToWhitelist.forEach(async (app) => {
188+
try {
189+
const whitelistResponse = await addToWhitelist(app);
190+
console.info(
191+
`Malware Whitelist response for ${app}: ${whitelistResponse}`
192+
);
193+
} catch (error: any) {
194+
console.info('Error while adding app to malware whitelist: ', error);
195+
}
196+
});
147197
};
148198

149199
useFreeRasp(config, actions);
150200

151-
return <DemoApp checks={appChecks} />;
201+
return <DemoApp checks={appChecks} suspiciousApps={suspiciousApps} />;
152202
};
153203

154204
export default App;

example/src/DemoApp.tsx

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,16 @@ import CloseCircle from '../assets/close-circle-outline.png';
66
import TalsecLogo from '../assets/talsec-logo.png';
77
import { Image } from 'react-native';
88
import { Colors } from './styles';
9+
import { MalwareModal } from './MalwareModal';
10+
import type { SuspiciousAppInfo } from 'freerasp-react-native';
911

10-
export const DemoApp = (props: any) => {
12+
export const DemoApp: React.FC<{
13+
checks: {
14+
name: string;
15+
status: string;
16+
}[];
17+
suspiciousApps: SuspiciousAppInfo[];
18+
}> = ({ checks, suspiciousApps }) => {
1119
return (
1220
<>
1321
<Flex
@@ -30,7 +38,7 @@ export const DemoApp = (props: any) => {
3038
>
3139
freeRASP checks:
3240
</Text>
33-
{props.checks.map((check: any, idx: number) => (
41+
{checks.map((check: any, idx: number) => (
3442
<Box
3543
key={idx}
3644
style={{
@@ -60,6 +68,12 @@ export const DemoApp = (props: any) => {
6068
>
6169
{check.name}
6270
</Text>
71+
{check.name === 'Malware' && (
72+
<MalwareModal
73+
isDisabled={check.status === 'ok'}
74+
suspiciousApps={suspiciousApps}
75+
/>
76+
)}
6377
{check.status === 'ok' ? (
6478
<Image
6579
source={CheckmarkCircle}

example/src/MalwareItem.tsx

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
import { Button, HStack } from '@react-native-material/core';
2+
import { addToWhitelist, type SuspiciousAppInfo } from 'freerasp-react-native';
3+
import ArrowUp from '../assets/arrow-up.png';
4+
import ArrowDown from '../assets/arrow-down.png';
5+
import React from 'react';
6+
import { useState } from 'react';
7+
import { TouchableOpacity, View, Text, Image, StyleSheet } from 'react-native';
8+
import { Colors } from './styles';
9+
10+
export const MalwareItem: React.FC<{ app: SuspiciousAppInfo }> = ({ app }) => {
11+
const [expanded, setExpanded] = useState(false);
12+
13+
const appUninstall = async () => {
14+
alert('Implement yourself!');
15+
};
16+
17+
const whitelistApp = async (packageName: string) => {
18+
try {
19+
const whitelistResponse = await addToWhitelist(packageName);
20+
console.info(
21+
`Malware Whitelist response for ${app}: ${whitelistResponse}`
22+
);
23+
alert('Restart app for whitelist to take effect');
24+
} catch (error: any) {
25+
console.info('Error while adding app to malware whitelist: ', error);
26+
}
27+
};
28+
29+
return (
30+
<View style={styles.item}>
31+
<TouchableOpacity onPress={() => setExpanded(!expanded)}>
32+
<HStack>
33+
<Image
34+
style={styles.iconSmall}
35+
source={{
36+
uri: `data:image/png;base64,${app.packageInfo.appIcon}`,
37+
}}
38+
/>
39+
<View style={styles.textView}>
40+
<Text numberOfLines={1} style={styles.titleText}>
41+
{app.packageInfo.appName}
42+
</Text>
43+
</View>
44+
45+
<View style={styles.buttonView}>
46+
<Image
47+
source={expanded ? ArrowUp : ArrowDown}
48+
style={{
49+
tintColor: Colors.grey,
50+
width: 30,
51+
height: 30,
52+
}}
53+
/>
54+
</View>
55+
</HStack>
56+
</TouchableOpacity>
57+
{expanded && (
58+
<>
59+
<View style={styles.spacer} />
60+
<Text style={styles.listItemTitle}>Package name:</Text>
61+
<Text style={styles.listItem}>{app.packageInfo.packageName}</Text>
62+
<Text style={styles.listItemTitle}>App name:</Text>
63+
<Text style={styles.listItem}>
64+
{app.packageInfo.appName ?? 'Not specified'}
65+
</Text>
66+
<Text style={styles.listItemTitle}>App version:</Text>
67+
<Text style={styles.listItem}>
68+
{app.packageInfo.version ?? 'Not specified'}
69+
</Text>
70+
<Text style={styles.listItemTitle}>App Icon:</Text>
71+
{app.packageInfo.appIcon ? (
72+
<Image
73+
style={styles.icon}
74+
source={{
75+
uri: `data:image/png;base64,${app.packageInfo.appIcon}`,
76+
}}
77+
/>
78+
) : (
79+
<Text style={styles.listItem}>Not specified</Text>
80+
)}
81+
<Text style={styles.listItemTitle}>Installer store:</Text>
82+
<Text style={styles.listItem}>
83+
{app.packageInfo.installerStore ?? 'Not specified'}
84+
</Text>
85+
<Text style={styles.listItemTitle}>Detection reason:</Text>
86+
<Text style={styles.listItem}>{app.reason}</Text>
87+
<HStack style={styles.buttonGroup}>
88+
<Button
89+
title={'Add to whitelist'}
90+
onPress={() => whitelistApp(app.packageInfo.packageName)}
91+
></Button>
92+
<Button title={'Uninstall'} onPress={appUninstall}></Button>
93+
</HStack>
94+
</>
95+
)}
96+
</View>
97+
);
98+
};
99+
100+
const styles = StyleSheet.create({
101+
button: {
102+
borderRadius: 20,
103+
paddingHorizontal: 30,
104+
paddingVertical: 10,
105+
marginTop: 15,
106+
elevation: 2,
107+
},
108+
buttonOpen: {
109+
backgroundColor: '#F194FF',
110+
},
111+
buttonClose: {
112+
backgroundColor: '#2196F3',
113+
},
114+
item: {
115+
backgroundColor: '#d4e4ff',
116+
borderRadius: 20,
117+
padding: 20,
118+
marginVertical: 8,
119+
},
120+
listItemTitle: {
121+
fontSize: 20,
122+
fontWeight: 'bold',
123+
},
124+
listItem: {
125+
fontSize: 16,
126+
paddingBottom: 5,
127+
},
128+
titleText: {
129+
fontSize: 20,
130+
},
131+
icon: {
132+
marginTop: 5,
133+
marginBottom: 5,
134+
width: 50,
135+
height: 50,
136+
},
137+
iconSmall: {
138+
width: 40,
139+
height: 40,
140+
},
141+
textView: {
142+
justifyContent: 'center',
143+
flex: 1,
144+
marginLeft: 20,
145+
marginRight: 30,
146+
},
147+
buttonView: {
148+
justifyContent: 'center',
149+
},
150+
spacer: {
151+
height: 15,
152+
},
153+
buttonGroup: {
154+
marginTop: 10,
155+
justifyContent: 'space-between',
156+
},
157+
});

0 commit comments

Comments
 (0)