yo-yo-yo-jbo/maps_side_chan
GitHub: yo-yo-yo-jbo/maps_side_chan
Stars: 2 | Forks: 0
# Side-channel attack in Apple Maps
As I mentioned in one of my previous blogposts, [TCC](https://github.com/yo-yo-yo-jbo/macos_tcc/) is a mechanism on macOS and iOS that enforces that private user data stays private.
It's the source of both annoying popups and enhanced security, and it's persistent -- once a user has made a choice whether to let a certain App access a certain type of private data (called "TCC service" in Apple terminology) - the choice persists.
The security boundary as defined by Apple is clear - an App should not gain access to a TCC service (e.g. camera, location, microphone, a user's Downloads folder) unless a user approves it knowingly (usually via the annoying popups I mentioned earlier).
One of the earliest types of TCC data protections is access to Apple's location services; it has a very interesting history (you can see that architecturally since its data is saved in `/var/db/locationd/clients.plist` instead of the usual `TCC.db` file).
In this blogpost, we're going to see a silly example of a **side-channel attack** and how one can bypass those constraints for location information.
I've disclosed that issue to Apple back in 2025, and it was tracked as `OE1101126364412`. After more than a year, Apple did not consider this to be an applicable security vulnerability (and I kind of agree on this one).
Thus, I feel comfortable sharing this blogpost more like a concept than an actual vulnerability blogpost.
## Background on side-channel attacks
Side-channel attacks utilize the idea that side-effects of operations leak data about the internals of the operation itself. Here are a few examples:
1. Checking for password correctness with [memcmp](https://man7.org/linux/man-pages/man3/memcmp.3.html): at every system that checks for passwords there should be a check that compares a desired secret and a secret provided by a user. Since `memcmp` and `strcmp` compare chunk-by-chunk and finish as soon as there's a mismatch - shorted check times means that fewer characters were correct. I've presented such an example [in the past](https://www.microsoft.com/en-us/security/blog/2021/06/30/microsoft-finds-new-netgear-firmware-vulnerabilities-that-could-lead-to-identity-theft-and-full-system-compromise/) if you're interested.
2. The infamous [Pentagon Pizza Index](https://www.pizzint.watch): this is a semi-serious index that shows a correlation between the US government "high-alert" state and the number of pizza orders around the Pentagon - for example, the Pizza index was very high around the [US strikes in Venezuela](https://en.wikipedia.org/wiki/2026_United_States_strikes_in_Venezuela).
3. [Padding Oracle Attacks](https://en.wikipedia.org/wiki/Padding_oracle_attack): very similar to example #1, but the method of leaking data is by checking whether a [block cipher](https://en.wikipedia.org/wiki/Block_cipher) padding is valid or not; the check could be direct (e.g. getting a unique error message) or indirect (e.g. via timing).
4. My very own LLM side-channel attack ("[WhisperLeak](https://www.microsoft.com/en-us/security/blog/2025/11/07/whisper-leak-a-novel-side-channel-cyberattack-on-remote-language-models/)") - which correlates between LLM conversation topics and packet sizes and timings.
5. [Spectre](https://en.wikipedia.org/wiki/Spectre_(security_vulnerability)) and [Meltdown](https://en.wikipedia.org/wiki/Meltdown_(security_vulnerability)), the notorious speculative execution CPU vulnerabilities, are timing side-channel attacks that allow one to read memory that normally one would not have access to.
Note that these are just a bunch of examples that use data sizes or time to gain data, but there are more examples that use [power analysis](https://arxiv.org/abs/1801.00932), for instance, to gain insights of private data.
## Apple Maps
One day, I was conducting my own research regarding macOS schema registrations (e.g. like "mailto://" or "http://").
You can view those using the `lsregister` tool:
1. It's documented [here](https://developer.apple.com/library/archive/featuredarticles/iPhoneURLScheme_Reference/MapLinks/MapLinks.html)!
2. It can get source and destination addresses (with the `saddr` and `daddr` parameters).
3. You can supply a "here" parameter to source or destination addresses.
4. You can supply a method of transport in the `dirflg` parameter - `w` for walking, `d` for driving or `r` for public transportation.
5. Most importantly - when you supply a navigation query, it opens Maps and calculates the navigation **without any user interaction**.
So, that got me thinking that I should start looking at it from a side-channel attack idea, since shorter paths are easier to calculate and present.
This, in turn, could get me access to my location.
Initially, I was thinking to abuse timing or network RX stats, but then I understood something simpler - drawing the path between two dots takes more graphics to do, and that might mean more [Mach messages](https://github.com/yo-yo-yo-jbo/macos_mach_ports/) to the Window Server!

## Exploitation
Exploitation is simple - even though you cannot get a Task Port to Maps, you can use the `libproc!proc_pidinfo` to get data about a process (that's how tools like [htop](https://htop.dev) work on macOS). While `proc_pidinfo` is not officially documented, it's used in many open-source tools and use can conclude a lot about it from Apple's [libproc.h header file](https://github.com/Apple-FOSS-Mirror/Libc/blob/master/darwin/libproc.h).
A call to `proc_pidinfo` provides a lot of information about the PID, as can be seen [here](https://github.com/apple/darwin-xnu/blob/main/bsd/sys/proc_info.h):
struct proc_taskinfo {
uint64_t pti_virtual_size; /* virtual memory size (bytes) */
uint64_t pti_resident_size; /* resident memory size (bytes) */
uint64_t pti_total_user; /* total time */
uint64_t pti_total_system;
uint64_t pti_threads_user; /* existing threads only */
uint64_t pti_threads_system;
int32_t pti_policy; /* default policy for new threads */
int32_t pti_faults; /* number of page faults */
int32_t pti_pageins; /* number of actual pageins */
int32_t pti_cow_faults; /* number of copy-on-write faults */
int32_t pti_messages_sent; /* number of messages sent */
int32_t pti_messages_received; /* number of messages received */
int32_t pti_syscalls_mach; /* number of mach system calls */
int32_t pti_syscalls_unix; /* number of unix system calls */
int32_t pti_csw; /* number of context switches */
int32_t pti_threadnum; /* number of threads in the task */
int32_t pti_numrunning; /* number of running threads */
int32_t pti_priority; /* task priority*/
};
To prove my point, I wrote a small Python script that calls `proc_pidinfo` (I showed how to call C functions from Python [in a previous blogpost](https://github.com/yo-yo-yo-jbo/python_for_researchers/)) after trying different locations, and simply chooses the one with the smallest amount of Mach calls. Of course, this is a toy-example, and one could do a better job with giving more precise locations over a larger dataset:

You can also attempt to abuse CPU usage, memory consumption and pagein statistics, but I found the number of Mach calls to be quite consistent.
In any case, I've uploaded my PoC as [sidechan.py](sidechan.py) for your leisure.
## Summary
Interestingly, this approach works for avenues outside of Apple Maps - for instance, websites that already have access to location (such as the ones described [here](https://www.microsoft.com/en-us/security/blog/2024/10/17/new-macos-vulnerability-hm-surf-could-lead-to-unauthorized-data-access/)) actually affect memory usage of browser processes in a way that might let one deterine location information from them.
I reported the idea to Apple without testing it in early 2025, they asked for a PoC which I was too busy to implement, but I'm quite happy to have provided that to them in January 2026.
In any case, I hope you enjoyed this short blogpost, with the hope it might inspire you to look for new side-channel ideas.
Stay tuned!
Jonathan Bar Or