How To Detect Jailbroken iOS Device?

How To Detect Jailbroken iOS Device?

How To Detect Jailbroken iOS Device?

hanks to the mobile era we have mobile apps for everything these days. Every business from a barbers shop to huge retailers has apps so that they can be closer to their customers. On one hand, we really leverage this convenience but on the other hand, there are risks of exposing a lot of confidential information while using these apps. And it becomes very vital when dealing with payments and other sensitive information. As a developer of these apps, it is our responsibility to put checks to make sure privacy and security are not compromised. Here is a comprehensive list of security best practices. But this article focuses on detecting if an iOS device is jailbroken.

JailBroken detections techniques basically fall under these categories

1. File Extension Checks

If a device is jailbroken, there are some files that exist in the system. One common file is Cydia. Let take a look at the code below how we would check for the existence of these files

func isDeviceJailBroken() ->Bool {
    if access("/Applications/Cydia.app", F_OK) != -1 || access("/Applications/blackra1n.app", F_OK) != -1 || access("/Applications/FakeCarrier.app", F_OK) != -1 || access("/Applications/Icy.app", F_OK) != -1 || access("/Applications/IntelliScreen.app", F_OK) != -1 || access("/Applications/MxTube.app", F_OK) != -1 || access("/Applications/RockApp.app", F_OK) != -1 || access("/Applications/SBSettings.app", F_OK) != -1 || access("/Applications/WinterBoard.app", F_OK) != -1 || access("/Library/MobileSubstrate/MobileSubstrate.dylib", F_OK) != -1 || access("/Library/MobileSubstrate/DynamicLibraries/LiveClock.plist", F_OK) != -1 || access("/Library/MobileSubstrate/DynamicLibraries/Veency.plist", F_OK) != -1 || access("/private/var/lib/apt", F_OK) != -1 || access("/private/var/lib/cydia", F_OK) != -1 || access("/private/var/mobile/Library/SBSettings/Themes", F_OK) != -1 || access("/private/var/stash", F_OK) != -1 || access("/private/var/tmp/cydia.log", F_OK) != -1 || access("/System/Library/LaunchDaemons/com.ikey.bbot.plist", F_OK) != -1 || access("/System/Library/LaunchDaemons/com.saurik.Cydia.Startup.plist", F_OK) != -1 || access("/usr/bin/sshd", F_OK) != -1 || access("/usr/libexec/sftp-server", F_OK) != -1 || access("/usr/sbin/sshd", F_OK) != -1 || access("/bin/bash", F_OK) != -1 || access("/etc/apt", F_OK) != -1 {
        return true
    }
    return false
}

2. URI Schemes

iOS App allows registering for different schemes that allow opening our app directly from a weblink. If a device is jailbroken we can check for the existence of cydia:// scheme. Below is code that checks for the existence for the URI scheme

func isDeviceJailBroken() -> Bool {
    if let url = URL(string: "cydia://package/com.example.package") {
        if UIApplication.shared.canOpenURL(url) {
            return true
        }
        return false
    }
}

3. Sandbox Check

JailBroken device alters the sandbox behavior of the app. Basically, the app can access or affect things outside of its sandbox. So we check by writing a file outside our sandbox and if we succeed then the device is jailbroken. This is how it will look in code.

func isDeviceJailBroken() -> Bool {
    let error: Error? = nil
    let stringToBeWritten = "This is a JB test."
    do {
        try stringToBeWritten.write(toFile: "/private/jailbreak.txt", atomically: true, encoding: .utf8)
    } catch {
    }
    if error == nil {
        return true
    } else {
        let fileManager = FileManager.default
        do {
            try fileManager.removeItem(atPath: "/private/jailbreak.txt")
        } catch {
        }
    }
    return false
}

4. Dynamic Linker Check

Dynamic Linking provides a way for executables to take advantage of code provided by other libraries without compiling and be able to ship that code in the executable file. This greatly helps executables to reuse code without including a copy of these different libraries. On the other hand, static linking will include all code the executable needs are shipped with it.

Usually Anti jailbroken detection tools are loaded as dynamic libraries. iOS dynamic linker dyld loads all the dynamic libraries. So we can check the presence of anti-jailbreak-detection tools by looking at the names and numbers of libraries loaded into the current process. If an anti-jailbreak-detection tool is running, we know the device is jailbroken.

Conclusion

All the methods mentioned above helps us to detect jailbroken devices. We can decide to take whatever action we want once we detect that. JailBroken device detection definitely adds a layer of security to your app. But by no way or means, the list above is enough to do that. End of the day, as a good developer we need to practice all the good security practices to secure our iOS app .

Originally published at shashankthakur.dev.