React-Native: Jailbreak and Root detection

    Hi guys, i never talk about mobile app security, it's help your app to be more safe but too bore in another way, right? just sometimes we needed it on the app production but not while development. Security is not easy for beginner but imagine that you've twin app on other web portal than AppStore or PlayStore but you didn't do that. Someone clone your app, reverse engineering and running on simulator or unidentified device, it's not a good sign for your business.

    At least you should avoid a kind of person who try to hack your app in simple way, let's get start.
You have to create a new project or based on current your project structure.

    I’ve used RN 0.61.5 for this but don’t use lower than RN 0.60.0 and I’ve mainly used npm than yarn, who using yarn please adapt to your command. I’ve created a new project with a command line from Terminal like below.

npx react-native init HelloWorld --version 0.61.5

After that locate into the HelloWorld folder and use the below command line.

npm install jail-monkey@2.2.0 --save

Waiting till an end of new command prompt again liked below image.

*For iOS you need to use pod install, if you've not familiar with CocoaPods, please check this out.

From terminal at root project type: cd ios && pod install && cd .. then hit Enter and wait until your pod install completed similar below image.


My project structure look like below.

HelloWorld

|--- __tests__ |--- android

|--- ios

|--- node_modules

|--- src | |--- components

| | |--- AppRestrict.js // <-- we need to create this new file.

| |--- images

    | |        |--- banned.png // <-- create your own image file or copy from my blog. | |--- main | |--- App.js // <-- leave this file as root top-level but modified a bit of code.

| |--- MainApplication.js // <-- create this file as Main for App.js.

|--- index.js // <-- update import path to App.js under main folder.

App.js
    Open ‘HelloWorld/src/main/App.js’ with TextEditor and then place this code and save. Below code we use MainApplication as Main view then leave as root App container.


import React, { Component } from "react";
import MainApplication from "./MainApplication";

class App extends Component {
render() {
return (
<MainApplication />
);
}
}

export default App;


AppRestrict.js
    Open ‘HelloWorld/src/components/AppRestrict.js’ with TextEditor and then place this code and save. Below code we create AppRestrict screen as component display when founded any Jailbreak and Root detection, don't forget to attached image under src/images folder.

banned.png


import React, { PureComponent } from 'react';
import {StyleSheet, View, Modal, Image, SafeAreaView, Text} from 'react-native';

class AppRestrict extends PureComponent {
constructor(props) {
super(props);
this.image = require("../images/banned.png");
}

render() {
const {show} = this.props;
if (show) {
return (
<SafeAreaView style={styles.container}>
<Modal
animationType="slide"
visible={true}
style={styles.modal}>
<View style={styles.container}>
<View style={styles.alertContainer}>
<View style={styles.alertBody}>
<View style={styles.logoContainer}>
<Image style={styles.logo} source={this.image} />
<Text style={styles.newsTitle}>
Error
</Text>
<Text style={styles.title}>
Your device is jailbroken.{"\n"}
                        This app does not support jailbroken devices.
</Text>
</View>

</View>
</View>
</View>
</Modal>
</SafeAreaView>
);
} else {
return null;
}
}
}

const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center'
},
alertContainer: {
flex: 1,
alignItems: 'center'
},
alertBody: {
margin: 0,
},
logoContainer: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
logo: {
width: 150,
height: 150,
},
modal: {
backgroundColor: 'white',
},
newsTitle: {
textAlign: 'center',
marginVertical: 8,
fontWeight: 'bold'
},
title: {
textAlign: 'center',
marginVertical: 8,
},

});

export default AppRestrict;


MainApplication.js
    Open ‘HelloWorld/src/main/MainApplication.js’ with TextEditor and then place this code and save. Below code we create MainApplication component as main screen, then we need to import AppRestrict from previous step and JailMonkey also. I've use state isRestrict for update when found at least one thing occur then update and show AppRestrict screen.

import React, { Component } from 'react';
import { View, StatusBar, Text, StyleSheet, Platform } from 'react-native';
import JailMonkey from 'jail-monkey'
import AppRestrict from "../components/AppRestrict";

class MainApplication extends Component {
constructor(props) {
super(props);
this.state = {
isRestrict: false
};
this.appRestriction();
}

appRestriction = async () => {
try {
if (Platform.OS === "android") {
// (ANDROID ONLY) Check if application is running on external storage
let isOnExternalStorage = await JailMonkey.isOnExternalStorage();
if (__DEV__) console.log('isOnExternalStorage: ', isOnExternalStorage);
this.rejectRoot(isOnExternalStorage);
// (ANDROID ONLY) Check if the phone has some malicious apps installed
let isDebugged = await JailMonkey.isDebugged();
if (__DEV__) console.log('isDebugged: ', isDebugged);
this.rejectRoot(isDebugged);
let hookDetected = await JailMonkey.hookDetected();
if (__DEV__) console.log('hookDetected: ', hookDetected);
this.rejectRoot(hookDetected);
}

// is this device JailBroken on iOS/Android?
let isJailBroken = await JailMonkey.isJailBroken();
if (__DEV__) console.log('isJailBroken: ', isJailBroken);
this.rejectRoot(isJailBroken);
// Can this device mock location - no need to root!
let canMockLocation = await JailMonkey.canMockLocation();
if (__DEV__) console.log('canMockLocation: ', canMockLocation);
this.rejectRoot(canMockLocation);
// Check if device violates any of the above
let trustFall = await JailMonkey.trustFall();
if (__DEV__) console.log('trustFall: ', trustFall);
this.rejectRoot(trustFall);

} catch (error) {
// Error retrieving data
if (__DEV__) console.log('error occurs: ', error);
}
};

rejectRoot(founded) {
if (founded) {
this.setState({ isRestrict: true });
}
}

render() {
return (
<View style={styles.container}>
<StatusBar barStyle="default" />
<View style={styles.textContainer}>
<Text style={styles.statusText}>Hello World</Text>
</View>
<AppRestrict show={this.state.isRestrict} />
</View>
);
}
}

const styles = StyleSheet.create({
container: {
backgroundColor: '#ABEBC6',
flexDirection: 'row',
justifyContent: 'space-around',
alignItems: 'center',
width: '100%',
flex: 1,
},
textContainer: {
borderColor: '#229954',
borderTopWidth: 1,
borderBottomWidth: 1,
backgroundColor: '#fff',
flexDirection: 'column',
justifyContent: 'space-between',
alignItems: 'center',
height: 28,
flex: 1,
},
statusText: {
color: '#229954',
height: 80,
fontWeight: '700',
fontSize: 18,
},
});

export default MainApplication;

index.js
    One last thing. Find HelloWorld/index.js open with the Text editor looking at line import App from './App'; and change it to import App from './src/main/App'; then save file. Try to run on simulator both iOS and Android.



    For example: running test with iOS and Android simulator then above screen should be appear and blocking any user to interact your main content as protected level as you've decided any case from Jailbreak and Root detection. From this point you can use this screen as result for other reason for allow or not allow user in some cases of unusual purpose.

Thank you so much for visit this blog. See U next thread. :)

No Like, No Thumbs Up, No Bell, Please support me by click ads, thank you...

No comments:

Post a Comment