Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,4 +168,8 @@ checkDeviceSecurity();

or please see **example-app** for a complete example.

## Security limitations

Root and jailbreak detection is a best-effort risk signal. The iOS implementation combines file and directory checks, sandbox escape checks, process environment checks, known local Frida endpoint checks, and loaded Mach-O image inspection. Runtime instrumentation can still modify an application's code or its returned values, so no client-side plugin can guarantee detection against an attacker who fully controls the process. Use the result as one layer of a broader security strategy and enforce sensitive decisions on a trusted backend.

Use this plugin to enhance your application's security and respond appropriately to potential risks.
8 changes: 4 additions & 4 deletions example-app/ios/App/App.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
Expand Down Expand Up @@ -334,7 +334,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
Expand All @@ -352,7 +352,7 @@
DEVELOPMENT_TEAM = 9XFYDGX5DN;
INFOPLIST_FILE = App/Info.plist;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.developer-tools";
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MARKETING_VERSION = 7.0.0;
OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\"";
Expand All @@ -374,7 +374,7 @@
DEVELOPMENT_TEAM = 9XFYDGX5DN;
INFOPLIST_FILE = App/Info.plist;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.developer-tools";
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MARKETING_VERSION = 7.0.0;
PRODUCT_BUNDLE_IDENTIFIER = ryltsov.alex.device.security.detect.demo;
Expand Down
14 changes: 7 additions & 7 deletions example-app/ios/App/App/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
<string>example-app</string>
<string>example-app</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
Expand All @@ -22,12 +22,12 @@
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSCameraUsageDescription</key>
<string>This app requires camera access to support taking photos.</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>This app requires photo library access to support accessing photos.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>This app requires photo library access to support accessing photos.</string>
<key>NSCameraUsageDescription</key>
<string>This app requires camera access to support taking photos.</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>This app requires photo library access to support accessing photos.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>This app requires photo library access to support accessing photos.</string>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
Expand Down
2 changes: 1 addition & 1 deletion example-app/ios/App/Podfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
require_relative '../../node_modules/@capacitor/ios/scripts/pods_helpers'

platform :ios, '14.0'
platform :ios, '15.0'
use_frameworks!

# workaround to avoid Xcode caching of Pods that requires
Expand Down
73 changes: 4 additions & 69 deletions ios/Sources/DeviceSecurityDetectPlugin/DeviceSecurityDetect.swift
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import Foundation
import UIKit
import LocalAuthentication

@objc public class DeviceSecurityDetect: NSObject {
private let jailbreakDetector = JailbreakDetector(environment: LiveJailbreakDetectionEnvironment())

@objc public func isJailBreak() -> Bool {
log("Checking if device is jailbroken")
#if targetEnvironment(simulator)
log("Skipping jailbreak checks on simulator")
return false
#else
return jailbreakDetector.isJailbroken()
#endif
return hasCydiaInstalled() || isContainsSuspiciousApps() || isSuspiciousSystemPathsExists() || canEditSystemFiles()
}

@objc public func pinCheck() -> Bool {
Expand All @@ -24,71 +26,4 @@ import LocalAuthentication
return false
}
}

func hasCydiaInstalled() -> Bool {
return UIApplication.shared.canOpenURL(URL(string: "cydia://")!)
}

func isContainsSuspiciousApps() -> Bool {
for path in suspiciousAppsPathToCheck {
if FileManager.default.fileExists(atPath: path) {
return true
}
}
return false
}

func isSuspiciousSystemPathsExists() -> Bool {
for path in suspiciousSystemPathsToCheck {
if FileManager.default.fileExists(atPath: path) {
return true
}
}
return false
}

func canEditSystemFiles() -> Bool {
let jailBreakText = "Developer Insider"
do {
try jailBreakText.write(toFile: jailBreakText, atomically: true, encoding: .utf8)
return true
} catch {
return false
}
}

var suspiciousAppsPathToCheck: [String] {
return [
"/Applications/Cydia.app",
"/Applications/blackra1n.app",
"/Applications/FakeCarrier.app",
"/Applications/Icy.app",
"/Applications/IntelliScreen.app",
"/Applications/MxTube.app",
"/Applications/RockApp.app",
"/Applications/SBSettings.app",
"/Applications/WinterBoard.app"
]
}

var suspiciousSystemPathsToCheck: [String] {
return [
"/Library/MobileSubstrate/DynamicLibraries/LiveClock.plist",
"/Library/MobileSubstrate/DynamicLibraries/Veency.plist",
"/private/var/lib/apt",
"/private/var/lib/apt/",
"/private/var/lib/cydia",
"/private/var/mobile/Library/SBSettings/Themes",
"/private/var/stash",
"/private/var/tmp/cydia.log",
"/System/Library/LaunchDaemons/com.ikey.bbot.plist",
"/System/Library/LaunchDaemons/com.saurik.Cydia.Startup.plist",
"/usr/bin/sshd",
"/usr/libexec/sftp-server",
"/usr/sbin/sshd",
"/etc/apt",
"/bin/bash",
"/Library/MobileSubstrate/MobileSubstrate.dylib"
]
}
}
Loading
Loading