Detect if an iOS app is running on Jailbroken Device in Swift (iOS) programmatically

Sachin Sabat
3 min readAug 1, 2020

Detect Jailbreak device in iOS/ Swift | Avoid Attackers to intrude in your application by all means possible in a single page| Supported to Swift (world first Protocol Oriented Language 🤘)

There are many ways to bypass the JailBreak implementation namely Liberty- Lite, A- Bypass, KernByPass (kernel level root change using MTerminal) from the Cydia Directory

But, we will detect it by all means possible and successfully pass our security check list for our application.

Github Link:- https://github.com/SachinSabat/CheckJailBreakDevice

Why JailBreak a device?

— Attackers JailBreak a device to get unrestricted access (root privileges)of the application, making it accessible to source code, and crucial files of the application. All the application downloaded from the app store is downloaded in /var/mobile/Applications/directory.

So in JailBreak Device there is always a Cydia app Installed.

Identify a JailBreak device in swift 5.0?

  1. We will check if we can open Cydia App:-
func isCydiaAppInstalled() -> Bool {return UIApplication.shared.canOpenURL(URL(string: "cydia://")!)}

Add this in your plist file-

<key>LSApplicationQueriesSchemes</key><array><string>cydia</string></array>

Call this function from didFinishLaunchingWithOptions and applicationDidBecomeActive, This works 90% for every application which detects Cydia app in rooted device, If in case the root directory is being changed then we can go by 2nd option for JailBreak detection.

2. Detecting File from the System:-

Many files are created when we JailBreak a device. Detecting it in the file system method will let one know if the device is JailBroken or not. I have list down important files to check in the file system.

/private/var/lib/apt 
/Applications/Cydia.app
/Applications/RockApp.app
/Applications/Icy.app
/Applications/WinterBoard.app
/Applications/SBSetttings.app
/Applications/blackra1n.app
/Applications/IntelliScreen.app
/Applications/Snoop-itConfig.app
/bin/sh
/usr/libexec/sftp-server
/usr/libexec/ssh-keysign /Library/MobileSubstrate/MobileSubstrate.dylib
/bin/bash
/usr/sbin/sshd
/etc/apt /System/Library/LaunchDaemons/com.saurik.Cydia.Startup.plist /System/Library/LaunchDaemons/com.ikey.bbot.plist /Library/MobileSubstrate/DynamicLibraries/LiveClock.plist /Library/MobileSubstrate/DynamicLibraries/Veency.plist

Create a function that checks all those files in the root directory. Like shown below;

func isJailBrokenFilesPresentInTheDirectory() -> Bool {let fm = FileManager.defaultif(fm.fileExists(atPath: "/private/var/lib/apt")) || (fm.fileExists(atPath: "/Applications/Cydia.app")){// This Device is jailbrokenreturn true} else {// Continue the device is not jailbrokenreturn false}}

Other method is to try to write into system files.

3. Writing into System Files:-

All application are being given the root privilege and can modify the files outside the sandbox. If the app can write to files outside its sandbox then the app is being run on a JailBreak device.

static func canEditSandboxFilesForJailBreakDetecttion() -> Bool {let jailBreakTestText = "Test for JailBreak"do {try jailBreakTestText.write(toFile:"/private/jailBreakTestText.txt", atomically:true, encoding:String.Encoding.utf8)return true} catch {return false}}

GitHub Link:- https://github.com/SachinSabat/CheckJailBreakDevice

4. Calling System API functions:-

In a sandbox environment which has root privilege does not allow call to system API. We can make a call to those system API and recognise if we are running our app in JailBroken device.

  • Fork() API call -
let pid = fork()if(!pid){return true}else if(pid >= 0){return false}
  • System() API call -
let system= system()if(system == 1){return true}else if(system == 0){return false}

This both fucntion call will make our job done to check for JailBreak device. Calling _dyld_image_name function takes a lot of time to execute and give us the result, which won’t be suitable in a application to call and execute for JailBreak detection.

In all above, function calls do check for if(TARGET_IPHONE_SIMULATOR) || arch(i386) || arch(x86_64) and return false accordingly. All three are checks to identify if the app is being run on simulator.

Call the JailBreak function from didFinishLaunchingWithOptions and applicationDidBecomeActive. Also, we can call from the viewDidLoad() function of important ViewController page.

Exit the application if found on JailBroken device by two ways:-

// Exit the app (Recommended first option)UIControl().sendAction(#selector(URLSessionTask.suspend), to: UIApplication.shared, for: nil)---------------------- OR ------------------------exit(-1)

--

--