WEBVTT

1
00:00:00.600 --> 00:00:06.050
Welcome. This tutorial covers how the library detects a jailbroken iPhone.

2
00:00:06.500 --> 00:00:13.400
We will walk through four jailbreak signals, and then look honestly at what modern rootless jailbreaks do to them.

3
00:00:13.850 --> 00:00:19.450
By the end you will know what each check inspects, why it matters, and how it gets evaded.

4
00:00:21.067 --> 00:00:29.092
A jailbreak removes Apple's app sandbox. Any process can then read another app's data, including its keychain items.

5
00:00:29.542 --> 00:00:35.692
It also switches off code-signing enforcement, so an attacker can patch your binary while it runs.

6
00:00:36.142 --> 00:00:42.992
And it lets reverse engineers decrypt an App Store binary, re-sign it, and redistribute a cracked copy.

7
00:00:43.442 --> 00:00:50.417
That is why the first question for a high-value flow is: is the operating system boundary still intact?

8
00:00:52.033 --> 00:01:02.058
The first check is jailbreak_files. It probes a fixed list of about fifty paths that jailbreaks, package managers, and tweak loaders leave behind.

9
00:01:02.508 --> 00:01:09.958
Each path is tested twice: once with the Foundation file manager, and once with the raw access system call.

10
00:01:10.408 --> 00:01:17.433
Two lookups matter, because some jailbreaks hide paths from the high-level API but not from the syscall.

11
00:01:17.883 --> 00:01:22.033
Any hit emits a strong signal in the jailbreak category.

12
00:01:23.667 --> 00:01:34.542
The second signal is jailbreak_url_schemes. Package managers and jailbreak utilities register custom URL schemes so tweaks can deep link into them.

13
00:01:34.992 --> 00:01:44.242
The check asks the system, through canOpenURL, whether anything handles cydia, sileo, zebra, filza, undecimus, or activator.

14
00:01:44.692 --> 00:01:50.667
A yes means a jailbreak app is installed, even if its files sit at unusual paths.

15
00:01:51.117 --> 00:02:03.017
Apple only lets an app query schemes it declares in LSApplicationQueriesSchemes, so an undeclared scheme is invisible. The Expo plugin adds the declarations for you.

16
00:02:04.633 --> 00:02:13.833
The symlinks check looks at system directories that are plain directories on a stock device, like Applications, usr include, and usr share.

17
00:02:14.283 --> 00:02:21.308
Legacy jailbreaks remount the small system partition, move big directories to var, and symlink them back.

18
00:02:21.758 --> 00:02:29.308
The check asks for each directory's symbolic link destination. If one exists, the structure has been altered.

19
00:02:29.758 --> 00:02:34.933
That fingerprint survives even after the obvious jailbreak apps are removed.

20
00:02:36.533 --> 00:02:45.233
Writable system tries something a stock iPhone never allows: creating a file outside the app container, under/private.

21
00:02:45.683 --> 00:02:51.883
It opens a random path with fopen, writes a single byte, closes it, and deletes it again.

22
00:02:52.333 --> 00:02:58.533
If that works, the sandbox is gone. That is the defining capability a jailbreak grants.

23
00:02:58.983 --> 00:03:07.033
Newer iOS versions seal the system volume, so even many jailbreaks cannot make it writable, and this check can miss them.

24
00:03:08.633 --> 00:03:21.933
Now the honest part. Modern rootless jailbreaks such as Dopamine relocate everything under var jb. The path list includes it, but the legacy paths are gone, and hiding tweaks can mask the rest.

25
00:03:22.383 --> 00:03:29.808
Symlinks never fire on rootless jailbreaks, because they stop repartitioning and symlinking system folders.

26
00:03:30.258 --> 00:03:36.208
The writable system check misses them too, since the sealed system volume stays read-only.

27
00:03:36.658 --> 00:03:41.533
And the URL scheme probe only sees schemes the app declared in advance.

28
00:03:43.133 --> 00:03:47.808
The native module runs every check and returns a list of signals.

29
00:03:48.258 --> 00:03:52.908
Signals you chose to ignore move aside and never affect the result.

30
00:03:53.358 --> 00:04:00.083
Any remaining signal in a compromising category, jailbreak included, makes the status compromised.

31
00:04:00.533 --> 00:04:08.283
If a run is incomplete the status is unknown, and unknown must never be treated as clean. Only clean is safe.

32
00:04:09.900 --> 00:04:17.350
Let us recap. One: a jailbreak removes the sandbox and code signing, which is why detection matters.

33
00:04:17.800 --> 00:04:24.575
Two: four independent probes look at files, URL schemes, symlinks, and writable system paths.

34
00:04:25.025 --> 00:04:29.250
Three: rootless jailbreaks and hiding tweaks evade several of them.

35
00:04:29.700 --> 00:04:36.150
Four: treat only a clean status as safe, and pair it with Apple App Attest for high-value flows.

36
00:04:37.767 --> 00:04:44.842
Thanks for watching. The checks live in DIIntegrityChecks.m, and the full reference is in the README.

37
00:04:45.292 --> 00:04:48.642
Next, watch the Android root detection video.
