Skip to content

Commit

Permalink
feat: [#172429524] Show modal if rooted / jailbroken (#1961)
Browse files Browse the repository at this point in the history
* [#173510346] add jailmonkey lib

* [#173510346] remove Android rooted check

* [#173510346] add actions and logics

* [#173510346] update comment

* [#173510346] add jail-monkey exception

* Merge branch 'master' of github.com:pagopa/io-app into 172429524-show-modal-if-rooted-jailbroken

# Conflicts:
#	ts/screens/authentication/LandingScreen.tsx

* [#172429524] fix

* [#172429524] add comments

* [#172429524] fix comment
  • Loading branch information
Undermaken authored Jun 26, 2020
1 parent 27c004f commit fa235ab
Show file tree
Hide file tree
Showing 15 changed files with 162 additions and 150 deletions.
1 change: 1 addition & 0 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ def jscFlavor = 'org.webkit:android-jsc:+'
def enableHermes = project.ext.react.get("enableHermes", false)

dependencies {
implementation project(':jail-monkey')
implementation project(':react-native-linear-gradient')
implementation project(':react-native-share')
implementation fileTree(dir: "libs", include: ["*.jar"])
Expand Down
86 changes: 8 additions & 78 deletions android/app/src/main/java/it/pagopa/io/app/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,8 @@ protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
showAlertDialog(getString(R.string.dialog_attention), getString(R.string.tablet_not_supported));
} else {
if (!isEmulator() && isDeviceRooted()) {
super.onCreate(savedInstanceState);
// on rooted device show message ant stop app
showAlertDialog(getString(R.string.alert_device_rooted_title),
getString(R.string.alert_device_rooted_desc));
} else {
SplashScreen.show(this, R.style.SplashScreenTheme);
super.onCreate(savedInstanceState);
}
SplashScreen.show(this, R.style.SplashScreenTheme);
super.onCreate(savedInstanceState);
}
// Fix the problem described here:
// https://stackoverflow.com/questions/48072438/java-lang-illegalstateexception-only-fullscreen-opaque-activities-can-request-o
Expand All @@ -61,17 +54,12 @@ protected void onCreate(Bundle savedInstanceState) {

@Override
protected ReactActivityDelegate createReactActivityDelegate() {
if (!isEmulator() && isDeviceRooted()) {
// on rooted device not attach main component
return new ReactActivityDelegate(this, null);
} else {
return new ReactActivityDelegate(this, getMainComponentName()) {
@Override
protected ReactRootView createRootView() {
return new RNGestureHandlerEnabledRootView(MainActivity.this);
}
};
}
return new ReactActivityDelegate(this, getMainComponentName()) {
@Override
protected ReactRootView createRootView() {
return new RNGestureHandlerEnabledRootView(MainActivity.this);
}
};
}

@Override
Expand All @@ -80,64 +68,6 @@ public void onRequestPermissionsResult(int requestCode, String[] permissions, in
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}

/**
* Check rooted device https://stackoverflow.com/a/8097801/2470948
*/
private boolean isDeviceRooted() {
// check only once
if (isRootedDeviceFlag == null) {
isRootedDeviceFlag = (checkRootMethod1() || checkRootMethod2() || checkRootMethod3());
}
return isRootedDeviceFlag;
}

private boolean checkRootMethod1() {
// check 1: get from build info, test-keys means it was signed with a custom key
// generated by a third-party developer
String buildTags = android.os.Build.TAGS;
return buildTags != null && buildTags.contains("test-keys");
}

private boolean checkRootMethod2() {
// check 2: if /system/app/Superuser.apk or its directories are present
String[] paths = { "/system/app/Superuser.apk", "/sbin/su", "/system/bin/su", "/system/xbin/su",
"/data/local/xbin/su", "/data/local/bin/su", "/system/sd/xbin/su", "/system/bin/failsafe/su",
"/data/local/su", "/su/bin/su" };
for (String path : paths) {
if (new File(path).exists())
return true;
}
return false;
}

private boolean checkRootMethod3() {
Process process = null;
try {
// check 3: try executing a command, this operation requires root privileges
process = Runtime.getRuntime().exec(new String[] { "/system/xbin/which", "su" });
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
if (in.readLine() != null)
return true;
return false;
} catch (Throwable t) {
return false;
} finally {
if (process != null)
process.destroy();
}
}

/**
* Detect when running on the emulator
* https://stackoverflow.com/a/21505193/2470948
*/
private boolean isEmulator() {
return Build.FINGERPRINT.startsWith("generic") || Build.FINGERPRINT.startsWith("unknown")
|| Build.MODEL.contains("google_sdk") || Build.MODEL.contains("Emulator")
|| Build.MODEL.contains("Android SDK built for x86") || Build.MANUFACTURER.contains("Genymotion")
|| (Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic"))
|| "google_sdk".equals(Build.PRODUCT);
}

private void showAlertDialog(String title, String message) {
new AlertDialog.Builder(MainActivity.this).setTitle(title).setMessage(message)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.learnium.RNDeviceInfo.RNDeviceInfo;
import com.lugg.ReactNativeConfig.ReactNativeConfigPackage;
import com.facebook.react.ReactApplication;
import com.gantix.JailMonkey.JailMonkeyPackage;
import com.BV.LinearGradient.LinearGradientPackage;
import cl.json.RNSharePackage;
import com.reactnativecommunity.asyncstorage.AsyncStoragePackage;
Expand Down Expand Up @@ -60,6 +61,7 @@ protected String getJSMainModuleName() {
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(new MainReactPackage(),
new JailMonkeyPackage(),
new LinearGradientPackage(),
new RNSharePackage(), new ScreenBrightnessPackage(), new AsyncStoragePackage(), new QRScanReaderPackage(),
new ImagePickerPackage(), new FlagSecurePackage(), new RNFSPackage(), new AndroidOpenSettingsPackage(),
Expand Down
2 changes: 2 additions & 0 deletions android/settings.gradle
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
rootProject.name = 'ItaliaApp'
include ':jail-monkey'
project(':jail-monkey').projectDir = new File(rootProject.projectDir, '../node_modules/jail-monkey/android')
include ':react-native-linear-gradient'
project(':react-native-linear-gradient').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-linear-gradient/android')
include ':react-native-share'
Expand Down
59 changes: 1 addition & 58 deletions ios/ItaliaApp/AppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,6 @@ - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if ([self isDeviceJailBroken]) {
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view.backgroundColor = UIColor.whiteColor;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
//show popup
UIAlertController * alert= [UIAlertController
alertControllerWithTitle:NSLocalizedString(@"ALERT_DEVICE_ROOTED_TITLE", @"")
message:NSLocalizedString(@"ALERT_DEVICE_ROOTED_DESC", @"")
preferredStyle:UIAlertControllerStyleAlert];

UIViewController *vc = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
[vc presentViewController:alert animated:YES completion:nil];
} else {
//continue
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
moduleName:@"ItaliaApp"
Expand All @@ -57,7 +41,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(

// see https://github.com/crazycodeboy/react-native-splash-screen#third-stepplugin-configuration
[RNSplashScreen show];
}


return YES;
}
Expand Down Expand Up @@ -99,47 +83,6 @@ - (void)application:(UIApplication *)application didReceiveLocalNotification:(UI
[RCTPushNotificationManager didReceiveLocalNotification:notification];
}

// Check if the device is jailbroken
-(BOOL)isDeviceJailBroken
{
#if !(TARGET_IPHONE_SIMULATOR)
// Check 1 : existence of files that are common for jailbroken devices
if ([[NSFileManager defaultManager] fileExistsAtPath:@"/Applications/Cydia.app"] ||
[[NSFileManager defaultManager] fileExistsAtPath:@"/Library/MobileSubstrate/MobileSubstrate.dylib"] ||
[[NSFileManager defaultManager] fileExistsAtPath:@"/bin/bash"] ||
[[NSFileManager defaultManager] fileExistsAtPath:@"/usr/sbin/sshd"] ||
[[NSFileManager defaultManager] fileExistsAtPath:@"/etc/apt"] ||
[[NSFileManager defaultManager] fileExistsAtPath:@"/private/var/lib/apt/"] ||
[[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"cydia://package/com.example.package"]]) {
return YES;
}
FILE *f = NULL ;
if ((f = fopen("/bin/bash", "r")) ||
(f = fopen("/Applications/Cydia.app", "r")) ||
(f = fopen("/Library/MobileSubstrate/MobileSubstrate.dylib", "r")) ||
(f = fopen("/usr/sbin/sshd", "r")) ||
(f = fopen("/usr/bin/ssh", "r")) ||
(f = fopen("/etc/apt", "r"))) {
fclose(f);
return YES;
}
fclose(f);
// Check 2 : Reading and writing in system directories (sandbox violation)
NSError *error;
NSString *stringToBeWritten = @"Jailbreak Test.";
[stringToBeWritten writeToFile:@"/private/jailbreak.txt" atomically:YES
encoding:NSUTF8StringEncoding error:&error];
if(error==nil){
//Device is jailbroken
return YES;
} else {
[[NSFileManager defaultManager] removeItemAtPath:@"/private/jailbreak.txt" error:nil];
}
#endif
return NO;

}


// Code used to replace the main view with a blank one when application is in background.
// Taken from @https://pinkstone.co.uk/how-to-control-the-preview-screenshot-in-the-ios-multitasking-switcher/
Expand Down
6 changes: 6 additions & 0 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ PODS:
- glog (0.3.5)
- instabug-reactnative (8.7.0):
- React
- jail-monkey (2.3.2):
- React
- Mixpanel (3.6.0)
- QrCode (1.0.2):
- React
Expand Down Expand Up @@ -147,6 +149,7 @@ DEPENDENCIES:
- Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`)
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
- instabug-reactnative (from `../node_modules/instabug-reactnative`)
- jail-monkey (from `../node_modules/jail-monkey`)
- QrCode (from `../node_modules/react-native-lewin-qrcode/ios`)
- React (from `../node_modules/react-native/`)
- React-Core (from `../node_modules/react-native/React`)
Expand Down Expand Up @@ -206,6 +209,8 @@ EXTERNAL SOURCES:
:podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec"
instabug-reactnative:
:path: "../node_modules/instabug-reactnative"
jail-monkey:
:path: "../node_modules/jail-monkey"
QrCode:
:path: "../node_modules/react-native-lewin-qrcode/ios"
React:
Expand Down Expand Up @@ -298,6 +303,7 @@ SPEC CHECKSUMS:
Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51
glog: 1f3da668190260b06b429bb211bfbee5cd790c28
instabug-reactnative: 6a4b20152fee125f9b884371ef10ccbf721dff1e
jail-monkey: d7c5048b2336f22ee9c9e0efa145f1f917338ea9
Mixpanel: 446b6e7713aa34a9a3516ff7648d56551384fc94
QrCode: d288f3c041248649031e1d7ef6b14319242cf76a
React: 53c53c4d99097af47cf60594b8706b4e3321e722
Expand Down
2 changes: 1 addition & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ module.exports = {
//'\\.js$': 'ts-jest',
},
transformIgnorePatterns: [
"node_modules/(?!(jest-)?react-native|react-navigation|@react-navigation|react-navigation-redux-helpers|react-native-device-info|native-base|native-base-shoutem-theme|@shoutem/animation|@shoutem/ui|rn-placeholder|jsbarcode|@pagopa/react-native-cie|react-native-share)"
"node_modules/(?!(jest-)?react-native|react-navigation|@react-navigation|react-navigation-redux-helpers|react-native-device-info|native-base|native-base-shoutem-theme|@shoutem/animation|@shoutem/ui|rn-placeholder|jsbarcode|@pagopa/react-native-cie|react-native-share|jail-monkey)"
],
globals: {
"ts-jest": {
Expand Down
9 changes: 9 additions & 0 deletions locales/en/index.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,15 @@ rooted:
title: Looks like the security of your device has been compromised!
bodyiOS: !include jailbroken_body.md
bodyAndroid: !include rooted_body.md
continueAlert:
title: Continue
body: Are you sure you understand the risks and want to continue?
confirmText: Yes
cancelText: Cancel
cancelAlert:
title: Exit
body: You can close the app
confirmText: Exit
locales:
it: Italian
en: English
Expand Down
9 changes: 9 additions & 0 deletions locales/it/index.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,15 @@ rooted:
title: Sembra che la sicurezza del tuo dispositivo sia compromessa!
bodyiOS: !include jailbroken_body.md
bodyAndroid: !include rooted_body.md
continueAlert:
title: Continua
body: Sei sicuro di aver compreso i rischi e voler continuare?
confirmText: Si
cancelText: Annulla
cancelAlert:
title: Esci
body: Puoi chiudere l'app
confirmText: Esci
locales:
it: Italiano
en: Inglese
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"io-ts": "1.8.5",
"italia-pagopa-commons": "^1.2.0",
"italia-ts-commons": "5.1.11",
"jail-monkey": "^2.3.2",
"lodash": "^4.17.15",
"native-base": "2.13.8",
"native-base-shoutem-theme": "0.3.1",
Expand Down
Loading

0 comments on commit fa235ab

Please sign in to comment.